Skip to content

Libfuzzer

libfuzzer

LLVM version of AFL

Example for Damn Vulnerable C Program

Compiling the Program:

>>> clang -fsanitize=fuzzer,address,undefined -g imgRead_libfuzzer.c -o imgRead_libfuzzer
imgRead_libfuzzer.c:86:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
}
^
1 warning generated.

Run the program:

>>> ./imgRead_libfuzzer
INFO: Seed: 2569578062
INFO: Loaded 1 modules   (86 inline 8-bit counters): 86 [0x56004f453148, 0x56004f45319e),
INFO: Loaded 1 PC tables (86 PCs): 86 [0x56004f4531a0,0x56004f453700),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2      INITED cov: 2 ft: 2 corp: 1/1b exec/s: 0 rss: 30Mb
=================================================================
==1805179==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000819e at pc 0x56004f3db28c bp 0x7ffd712987f0 sp 0x7ffd71297fa0
READ of size 10 at 0x60200000819e thread T0
    #0 0x56004f3db28b in __asan_memcpy (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x10f28b)
    #1 0x56004f4127a5 in LLVMFuzzerTestOneInput /tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer.c:35:3
    #2 0x56004f315f0f in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x49f0f)
    #3 0x56004f317ba0 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x4bba0)
    #4 0x56004f3184e9 in fuzzer::Fuzzer::MutateAndTestOne() (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x4c4e9)
    #5 0x56004f319e37 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x4de37)
    #6 0x56004f30182d in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x3582d)
    #7 0x56004f2f12f3 in main (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x252f3)
    #8 0x7facc26bf151 in __libc_start_main (/usr/lib/libc.so.6+0x28151)
    #9 0x56004f2f134d in _start (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x2534d)

0x60200000819e is located 0 bytes to the right of 14-byte region [0x602000008190,0x60200000819e)
allocated by thread T0 here:
    #0 0x56004f3dc349 in malloc (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x110349)
    #1 0x7facc2a98539 in operator new(unsigned long) /build/gcc/src/gcc/libstdc++-v3/libsupc++/new_op.cc:50:22
    #2 0x56004f317ba0 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x4bba0)
    #3 0x56004f3184e9 in fuzzer::Fuzzer::MutateAndTestOne() (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x4c4e9)
    #4 0x56004f319e37 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x4de37)
    #5 0x56004f30182d in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x3582d)
    #6 0x56004f2f12f3 in main (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x252f3)
    #7 0x7facc26bf151 in __libc_start_main (/usr/lib/libc.so.6+0x28151)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/tmp/Damn_Vulnerable_C_Program/imgRead_libfuzzer+0x10f28b) in __asan_memcpy
Shadow bytes around the buggy address:
  0x0c047fff8fe0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fd
  0x0c047fff8ff0: fa fa fd fd fa fa fd fd fa fa fd fa fa fa fd fa
  0x0c047fff9000: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c047fff9010: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c047fff9020: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
=>0x0c047fff9030: fa fa 00[06]fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==1805179==ABORTING
MS: 4 InsertByte-CopyPart-ChangeBit-CrossOver-; base unit: adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
0xa,0x58,0x83,0x0,0x0,0xa,0xa,0x0,0xa,0x0,0xa,0x0,0x0,0x0,
\x0aX\x83\x00\x00\x0a\x0a\x00\x0a\x00\x0a\x00\x00\x00
artifact_prefix='./'; Test unit written to ./crash-5b3e359967a560d8422b9557a5cbd4d6f2cdd3ff
Base64: CliDAAAKCgAKAAoAAAA=

Tutorial

Example Testfile:

#include <lib/parse_image.h>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size){
	free(ParseImage(data,size));
	return 0;
}

Example Compile:

#Add the AddressSanitizer, ThreadSanitizer, MemorySanitizer, and UndefinedBehaviourSanitizer
clang++ -std=c++11 -fsanitize=address,thread,memory,undefined,fuzzer fuzzer.cc library/*.cc
./fuzzer corpusdir