Fuzzing SQLite With AFL

Top-level Files of tip
Login

Top-level Files of tip

Files in the top-level directory from the latest check-in


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