Fuzzing SQLite With AFL

Fuzzing SQLite Using AFL
Login

Fuzzing SQLite Using AFL

This repository contains seed files and instructions for fuzzing using the American Fuzzy Lop (AFL) fuzzer.

Prerequisites

  1. The SQLite source tree available from https://www.sqlite.org/src
  2. The latest version of AFL available from http://lcamtuf.coredump.cx/afl
  3. The content of this repository either as a tarball, or preferably as a Fossil clone.

How To Run The Fuzzer

  1. Untar the AFL download into a directory which we will here call ~/afl

  2. cd into ~/afl and type "make"

  3. Create a subdirectory ~/afl/sqlite

  4. cd into ~/afl/sqlite and open this repository: fossil open ~/repos/afl-sqlite.fossil

  5. Open the SQLite source repository in a directory which we will here call ~/sqlite.

  6. cd to ~/sqlite and build the amalgamation: ./configure; make sqlite3.c

  7. cd back to ~/afl/sqlite and copy source files into the ~/afl/sqlite directory: cp ~/sqlite/sqlite3.[ch] .; cp ~/sqlite/tool/fuzzershell.c .

  8. Build the instrumented fuzzershell: ../afl-gcc -O3 -o fuzzershell -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_LOAD_EXTENSION=0 -DSQLITE_NO_SYNC -DSQLITE_DEBUG -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE -DSQLITE_OMIT_RANDOMNESS -I. fuzzershell.c sqlite3.c -ldl

    • Easier alternative: sh get-files.sh; sh rebuild-main.sh
    • Set -DSQLITE_DEBUG to enable assert() statements.
    • Set -DSQLITE_OMIT_RANDOMNESS to cause SQLite's PRNG to be seeded the same way on every run, so that the AFL fuzzer does not see variance between runs using the same input.
    • The -DSQLITE_NO_SYNC is probably not needed since fuzzershell never writes to disk. But it does not hurt.
    • The -DSQLITE_THREADSAFE=0 and -DSQLITE_ENABLE_LOAD_EXTENSION=0 options preclude the need for linking with -ldl and -lpthreads
  9. Make an output directory: rm -rf out; mkdir out

  10. Disable the AFL warning about CPU frequency: export set AFL_SKIP_CPUFREQ=1

  11. Run the fuzzer: ../afl-fuzz -i cull2 -o out -T sql -x ../testcases/_extras/sql.dict -- ./fuzzershell

    • The original test vector set designed by Michal Zalewski is in the "minimized_culled" directory. This can be substituted in place of "cull2" if desired.
    • Used the "json-cases" directory instead of "cull2"/"minimized_culled" and omit the -x option if testing the json1.c extension
  12. If the fuzzer stops for any reason (for example to update "fuzzershell.c" to a new version) then it can be restated by changing the "-i cull2" argument to just "-i-". Example:

    • ../afl-fuzz -i- -o out -T sql -x ../testcases/_extras/sql.dict -- ./fuzzershell
    • Omit the -x option when testing json1.c
    • Easier alternative: sh rerun-sql.sh

Database File Fuzzing

The procedure above fuzzes SQL input. To fuzz the database file format, change steps (11) and (12) to be the following:

The seed database file in the dbfuzz directory are created using the db-fuzz-init.txt SQL script.

Other links

Acknowledgements