:title: Fuzzing with afl-fuzz
:author: Nils Moskopp
:css: index.css

afl-fuzz
========

- “smart” fuzzer
- coverage guided
- very low effort

----

fuzzing approaches
------------------

- blind fuzzing (loop)
- block coverage
- edge overage
- AFL model

----

AFL model (1)
-------------

- state exploration
- queue re-evaluation
- use coverage to cull

----

AFL model (2)
-------------

- trimming inputs → fast
- largely format-agnostic
- specialized dictionaries

----

AFL model (3)
-------------

- crash test deduplication
- address → is unreliable
- stack trace → inflation

----

AFL model (4)
-------------

- crash exploration!
- fork server (CoW)
- parallelization

----

AFL model (5)
-------------

- binary fuzz (qemu)
- cross-architecture
- file format analysis

----

pulling JPEGs out of thin air
-----------------------------

https://lcamtuf.blogspot.com/2014/11/pulling-jpegs-out-of-thin-air.html

----

a wild XML <!CDATA> appears!
----------------------------

https://lcamtuf.blogspot.com/2014/11/afl-fuzz-nobody-expects-cdata-sections.html

.. code::

   <a b="c">d</a>

.. code::

   <![<CDATA[C%Ada b="c":]]]>

----

risks of fuzzing
----------------

- CPU runs hot → throttling
- RAM and disk may fill up
- heavy I/O, i.e. SSD wear
- computer executes crap

----

prerequisites
-------------

1. a program that reads data
   eiter from stdin or file

2. the program must crash
   if important bugs occur

3. a small valid input file

----

quick start
-----------

compile with afc-gcc / afc-clang

.. code::

   afl-fuzz -i "${IDIR}" -o "${ODIR}" -- "${BIN}"

----

inputs
------

- gather valid inputs
- quantity > quality
- minimize corpus
- minimize files

----

TGA input (1)
-------------

- optional alpha channel
- bpp: 1, 8, 15, 16, 24, 32
- may be RLE-compressed
- may be color-mapped
- top-bottom / bottom-top

----

TGA input (2)
-------------

- 32bpp: B8G8R8A8
- 24bpp: B8G8R8
- 16bpp: A1R5G5B5
- 16bpp: K8A8
- 8bpp: K8

----

dictionaries
------------

→ just tokens, no grammar

.. code::

   tag_a="<a>"
   tag_abbr="<abbr>"
   tag_acronym="<acronym>"
   tag_address="<address>"

----

lots of CVEs
------------

https://github.com/mrash/afl-cve

(not updated since 2017)

----

programmming
------------

.. figure:: pics/cve-programming-language.jpeg

----

hands-on time
-------------

→ we start fuzzing now!

- scripts in folder
- ordered by numbers

----

interface
---------

- process timing
- overall results

----

interface: timing
-----------------

- should find paths in minutes!
- runtime: days, weeks, months?

----

interface: results
------------------

- cycles: count of queue passes
- color-coded (end: blue/green)
- paths: how much AFL knows yet
- AFL counts crashes & hangs ;)

----

interface: cycle progress
-------------------------

- how far along current pass is
- ID of test cases is important

----

interface: map coverage
-----------------------

- coverage (branch tuples)
- current input / corpus

----

interface: progress (1)
-----------------------

- calibration (briefly)
- trim testcases (length/step)
- bitflip (toggle/walk)
- arithmethics (add/sub ints)

----

interface: progress (2)
-----------------------

- interesting values (8 bit step)
- extras (dictionary injection)
- havoc (mutations + dictionary)
- splice (combines 2 queue items)
- sync (for parallel fuzzing)

----

interface: findings in depth
----------------------------

- nerd metrics

----

interface: strategy yields
--------------------------

- leaderboard ;)
- validate assumptions
- trim strategy (bytes/tries)

----

interface: path geometry (1)
----------------------------

- initial inputs: level 1
- derived inputs: level 2
- etc. pp.
- new paths found

----

interface: path geometry (2)
----------------------------

- stability: same execution?
- uninitialized memory used?
- leftover temporary files?
- sqlite “select random();”
- threads (harmless)

----

interface: CPU
--------------

- load is color-coded
- green: parallelize!
- red: no added fuzz!

----

status files
------------

- output directory
- fuzzer_stats file

----

sanitizers
----------

- ASAN
- MSAN
- UBSAN
- TSAN
- LSAN

----

sanitizers: ASAN (1)
--------------------------

*Address SANitizer*

- finds memory corruption:

  - buffer overflow
  - use after free
  - memory leaks

→ `-fsanitize=address`

----

sanitizers: ASAN (2)
--------------------------

- 32-bit: works ok
- 64-bit: memory hog

→ compile in 32 bit mode

- gcc compile option: -m32
- apt install gcc-multilib

----

sanitizers: MSAN
---------------------

*Memory SANitizer*

- finds uninitialized memory use

→ `-fsanitize=memory`

----

sanitizers: UBSAN
----------------------

*Undefined Behaviour SANitizer*

- finds undefined behavour

  - signed integer overflow
  - null pointer dereference
  - division by zero
  - etc. pp.

→ `-fsanitize=undefined`

----

sanitizers: TSAN
---------------------

*Thread SANitizer*

- finds race conditions

→ `-fsanitize=thread`

----

sanitizers: LSAN
---------------------

*Leak SANitizer*

- finds memory leaks
- little runtime overhead
- only triggers at the end

→ comes with address sanitizer

----

libfuzzer
---------

→ `-fsanitize=fuzzer`

https://www.moritz.systems/blog/an-introduction-to-llvm-libfuzzer/

https://google.github.io/clusterfuzz/setting-up-fuzzing/libfuzzer-and-afl/

----

sanitizers: common tips
-----------------------

- abort/trap on errors
- learn all the options
- use only one sanitizer
   - exception: libfuzzer

----

additional AFL
--------------

https://lcamtuf.coredump.cx/afl/

https://github.com/AFLplusplus/AFLplusplus

----

fun stuff
---------

more complex afl demo:
https://github.com/defuse/afl-demo

bug finding competition:
https://rode0day.mit.edu/