title: | Fuzzing with afl-fuzz |
---|---|
Author: | Nils Moskopp |
css: | index.css |
- “smart” fuzzer
- coverage guided
- very low effort
- blind fuzzing (loop)
- block coverage
- edge overage
- AFL model
- state exploration
- queue re-evaluation
- use coverage to cull
- trimming inputs → fast
- largely format-agnostic
- specialized dictionaries
- crash test deduplication
- address → is unreliable
- stack trace → inflation
- crash exploration!
- fork server (CoW)
- parallelization
- binary fuzz (qemu)
- cross-architecture
- file format analysis
https://lcamtuf.blogspot.com/2014/11/pulling-jpegs-out-of-thin-air.html
https://lcamtuf.blogspot.com/2014/11/afl-fuzz-nobody-expects-cdata-sections.html
<a b="c">d</a>
<![<CDATA[C%Ada b="c":]]]>
- CPU runs hot → throttling
- RAM and disk may fill up
- heavy I/O, i.e. SSD wear
- computer executes crap
- a program that reads data eiter from stdin or file
- the program must crash if important bugs occur
- a small valid input file
compile with afc-gcc / afc-clang
afl-fuzz -i "${IDIR}" -o "${ODIR}" -- "${BIN}"
- gather valid inputs
- quantity > quality
- minimize corpus
- minimize files
- optional alpha channel
- bpp: 1, 8, 15, 16, 24, 32
- may be RLE-compressed
- may be color-mapped
- top-bottom / bottom-top
- 32bpp: B8G8R8A8
- 24bpp: B8G8R8
- 16bpp: A1R5G5B5
- 16bpp: K8A8
- 8bpp: K8
→ just tokens, no grammar
tag_a="<a>" tag_abbr="<abbr>" tag_acronym="<acronym>" tag_address="<address>"
https://github.com/mrash/afl-cve
(not updated since 2017)
→ we start fuzzing now!
- scripts in folder
- ordered by numbers
- process timing
- overall results
- should find paths in minutes!
- runtime: days, weeks, months?
- cycles: count of queue passes
- color-coded (end: blue/green)
- paths: how much AFL knows yet
- AFL counts crashes & hangs ;)
- how far along current pass is
- ID of test cases is important
- coverage (branch tuples)
- current input / corpus
- calibration (briefly)
- trim testcases (length/step)
- bitflip (toggle/walk)
- arithmethics (add/sub ints)
- interesting values (8 bit step)
- extras (dictionary injection)
- havoc (mutations + dictionary)
- splice (combines 2 queue items)
- sync (for parallel fuzzing)
- nerd metrics
- leaderboard ;)
- validate assumptions
- trim strategy (bytes/tries)
- initial inputs: level 1
- derived inputs: level 2
- etc. pp.
- new paths found
- stability: same execution?
- uninitialized memory used?
- leftover temporary files?
- sqlite “select random();”
- threads (harmless)
- load is color-coded
- green: parallelize!
- red: no added fuzz!
- output directory
- fuzzer_stats file
- ASAN
- MSAN
- UBSAN
- TSAN
- LSAN
Address SANitizer
- finds memory corruption:
- buffer overflow
- use after free
- memory leaks
→ -fsanitize=address
- 32-bit: works ok
- 64-bit: memory hog
→ compile in 32 bit mode
- gcc compile option: -m32
- apt install gcc-multilib
Memory SANitizer
- finds uninitialized memory use
→ -fsanitize=memory
Undefined Behaviour SANitizer
- finds undefined behavour
- signed integer overflow
- null pointer dereference
- division by zero
- etc. pp.
→ -fsanitize=undefined
Thread SANitizer
- finds race conditions
→ -fsanitize=thread
Leak SANitizer
- finds memory leaks
- little runtime overhead
- only triggers at the end
→ comes with address sanitizer
→ -fsanitize=fuzzer
https://www.moritz.systems/blog/an-introduction-to-llvm-libfuzzer/
https://google.github.io/clusterfuzz/setting-up-fuzzing/libfuzzer-and-afl/
- abort/trap on errors
- learn all the options
- use only one sanitizer
- exception: libfuzzer
https://lcamtuf.coredump.cx/afl/
https://github.com/AFLplusplus/AFLplusplus
more complex afl demo: https://github.com/defuse/afl-demo
bug finding competition: https://rode0day.mit.edu/