0% found this document useful (0 votes)
71 views113 pages

BruCON DDIF Day1 21 April

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
71 views113 pages

BruCON DDIF Day1 21 April

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 113

Deep Dive Into Fuzzing

BruCON 2022
Day 1
Who are we?

Dhiraj Mishra - www.inputzero.io Zubin Devnani - www.devtty0.io


- RandomDhiraj - p1ngfl0yd

Senior Security Consultant Senior Security Consultant


Open-source contributor OSCP|E|WP
AFL, AFL++, Metasploit Metasploit contributor

[email protected] [email protected]
A moment please

Fuzzing = Patience
- Success mantra
Agenda (Day 1) – A very high level overview

AFL utilities, 1
Introduction and Mutating inputs 3
need to fuzzing Prerequisite and
and coverage
installation
guided fuzzing

Smart fuzzing
and 2 Domain specific
Instrumenting fuzzing,
Types of fuzzing , AFL its principal and strategy.

binaries understanding

Effective way of crash analysis, ASAN and LLVM


trace bitmap
L
t AF

No some pro tip, resolving common dependencies.


n
re 4
iffe e
Fuzzing STDIO/IN – Finding targets and fuzzing d u
ubuntu packages. rin
g
h niq
p a rk ec
o m wo
e vet
C m sla
fra n d
Input mutation, testcase minimization ra
a ste
M

Utilizing

symbolizer.
Grammar for
fuzzing

Exercise for day


#1
How this will help you?

Security
Developer Pentester Researcher

Discovering bugs for Finding 0days on widely used softwares


inhouse projects
Provided VM’s

Username: fuzzing
Password: fuzzing! For Linux (Ubuntu 20 LTS) Local OVA file

Username: Fuzzing
Password: ????
Why Fuzzing?
==20297==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x629000009748 at pc 0x0000004e58b9 bp 0x7ffca5141520 sp 0x7ffca5140cd0
READ of size 17771 at 0x629000009748 thread T0
#0 0x4e58b8 in __asan_memcpy /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:23:3
#1 0x5224a8 in tls1_process_heartbeat /home/input0/heartbleed/BUILD/ssl/t1_lib.c:2586:3
#2 0x58e51d in ssl3_read_bytes /home/input0/heartbleed/BUILD/ssl/s3_pkt.c:1092:4
#3 0x592c5a in ssl3_get_message /home/input0/heartbleed/BUILD/ssl/s3_both.c:457:7 Remember Heartbleed?
CVE-2014-0160
#4 0x55e847 in ssl3_get_client_hello /home/input0/heartbleed/BUILD/ssl/s3_srvr.c:941:4
#5 0x55a8a9 in ssl3_accept /home/input0/heartbleed/BUILD/ssl/s3_srvr.c:357:9
#6 0x51653d in LLVMFuzzerTestOneInput /home/input0/Downloads/fuzzer-test-suite-master/openssl-1.0.1f/target.cc:34:3
#7 0x42dd1c in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:515:13
#8 0x42d57b in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:440:3
#9 0x42efad in fuzzer::Fuzzer::MutateAndTestOne() /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:648:19
#10 0x42f865 in fuzzer::Fuzzer::Loop(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, fuzzer::fuzzer_allocator<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > > > const&) /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:775:5
#11 0x424570 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:754:6
#12 0x446172 in main /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#13 0x7f9e23b21b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#14 0x41d609 in _start (/home/input0/heartbleed/openssl-1.0.1f-fsanitize_fuzzer+0x41d609)

0x629000009748 is located 0 bytes to the right of 17736-byte region [0x629000005200,0x629000009748)


allocated by thread T0 here:
#0 0x4e67d3 in __interceptor_malloc /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88:3
#1 0x5c1dbb in CRYPTO_malloc /home/input0/heartbleed/BUILD/crypto/mem.c:308:8
#2 0x594199 in freelist_extract /home/input0/heartbleed/BUILD/ssl/s3_both.c:708:12
#3 0x594199 in ssl3_setup_read_buffer /home/input0/heartbleed/BUILD/ssl/s3_both.c:770
#4 0x59477c in ssl3_setup_buffers /home/input0/heartbleed/BUILD/ssl/s3_both.c:827:7
#5 0x55b474 in ssl3_accept /home/input0/heartbleed/BUILD/ssl/s3_srvr.c:292:9
#6 0x51653d in LLVMFuzzerTestOneInput /home/input0/Downloads/fuzzer-test-suite-master/openssl-1.0.1f/target.cc:34:3
#7 0x42dd1c in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:515:13
#8 0x42f3ad in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >,
fuzzer::fuzzer_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:701:3
#9 0x42f6e5 in fuzzer::Fuzzer::Loop(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, fuzzer::fuzzer_allocator<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > > > const&) /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:739:3
#10 0x424570 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:754:6
#11 0x446172 in main /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#12 0x7f9e23b21b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:23:3 in __asan_memcpy


Shadow bytes around the buggy address:
0x0c527fff9290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c527fff92a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c527fff92b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c527fff92c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c527fff92d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c527fff92e0: 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa fa
0x0c527fff92f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c527fff9300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c527fff9310: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c527fff9320: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c527fff9330: 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
==20297==ABORTING
Types of fuzzing?

./{Bin__AFL__ary} AAAAAA..

./{Binary} AAAAAA..
./{BAiAn_A_AFL__aAry} AAAAAA..

Black box, White box, Grey box.

Black box: No source code


White box: Open source
Grey box: Mutation based
Coverage Guided Fuzzing

Initial
Seeds
Inputs
Coverage Guided Fuzzing

Captures
Initial
Seeds
Inputs Input
Coverage Guided Fuzzing

Captures Random
Initial
Seeds
Inputs Input Mutation Input
Coverage Guided Fuzzing

Captures Random Executes


Initial
Seeds
Inputs Input Mutation Input Mutated Program
Input
Coverage Guided Fuzzing

Captures Random Executes


Initial
Seeds
Inputs Input Mutation Input Mutated Program
Input

0000000000602088 b __afl_area_ptr
0000000000400b9e t __afl_die
0000000000602098 b __afl_fork_pid
0000000000400ab9 t __afl_fork_resume
0000000000400a21 t __afl_fork_wait_loop
00000000004009fb t __afl_forkserver
00000000006020a8 B
__afl_global_area_ptr
0000000000400890 t __afl_maybe_log
0000000000602090 b __afl_prev_loc
00000000004008b8 t __afl_return
00000000004008c0 t __afl_setup
0000000000400ba6 t __afl_setup_abort
00000000006020a0 b __afl_setup_failure
00000000004008e1 t __afl_setup_first
00000000004008a0 t __afl_store
000000000060209c b __afl_temp
Coverage Guided Fuzzing

Instrumented program

Captures Random Executes


Initial
Seeds
Inputs Input Mutation Input Mutated Program
Input

0000000000602088 b __afl_area_ptr
0000000000400b9e t __afl_die
0000000000602098 b __afl_fork_pid
0000000000400ab9 t __afl_fork_resume
0000000000400a21 t __afl_fork_wait_loop
00000000004009fb t __afl_forkserver
00000000006020a8 B
__afl_global_area_ptr
0000000000400890 t __afl_maybe_log
0000000000602090 b __afl_prev_loc
00000000004008b8 t __afl_return
00000000004008c0 t __afl_setup
0000000000400ba6 t __afl_setup_abort
00000000006020a0 b __afl_setup_failure
00000000004008e1 t __afl_setup_first
00000000004008a0 t __afl_store
000000000060209c b __afl_temp
Coverage Guided Fuzzing

Instrumented program

Captures Random Executes


Initial
Seeds
Inputs Input Mutation Input Mutated Program
Input

0000000000602088 b __afl_area_ptr
0000000000400b9e t __afl_die
0000000000602098 b __afl_fork_pid
0000000000400ab9 t __afl_fork_resume
0000000000400a21 t __afl_fork_wait_loop
00000000004009fb t __afl_forkserver
00000000006020a8 B
__afl_global_area_ptr
0000000000400890 t __afl_maybe_log
0000000000602090 b __afl_prev_loc
00000000004008b8 t __afl_return
00000000004008c0 t __afl_setup
0000000000400ba6 t __afl_setup_abort
00000000006020a0 b __afl_setup_failure
00000000004008e1 t __afl_setup_first
00000000004008a0 t __afl_store
000000000060209c b __afl_temp

Save OR Not
Coverage Guided Fuzzing

Instrumented program

Captures Random Executes


Initial
Seeds
Inputs Input Mutation Input Mutated Program
Input

0000000000602088 b __afl_area_ptr
0000000000400b9e t __afl_die
0000000000602098 b __afl_fork_pid
0000000000400ab9 t __afl_fork_resume
0000000000400a21 t __afl_fork_wait_loop
00000000004009fb t __afl_forkserver
00000000006020a8 B
__afl_global_area_ptr
0000000000400890 t __afl_maybe_log
0000000000602090 b __afl_prev_loc
00000000004008b8 t __afl_return
00000000004008c0 t __afl_setup
0000000000400ba6 t __afl_setup_abort
00000000006020a0 b __afl_setup_failure
00000000004008e1 t __afl_setup_first
00000000004008a0 t __afl_store
000000000060209c b __afl_temp

Save OR Not
Coverage
Coverage Guided Fuzzing

Instrumented program

Captures Random Executes


Initial
Seeds
Inputs Input Mutation Input Mutated Program
Input

0000000000602088 b __afl_area_ptr
0000000000400b9e t __afl_die
0000000000602098 b __afl_fork_pid
0000000000400ab9 t __afl_fork_resume
0000000000400a21 t __afl_fork_wait_loop
00000000004009fb t __afl_forkserver
00000000006020a8 B
__afl_global_area_ptr
0000000000400890 t __afl_maybe_log
0000000000602090 b __afl_prev_loc
00000000004008b8 t __afl_return
00000000004008c0 t __afl_setup
0000000000400ba6 t __afl_setup_abort
00000000006020a0 b __afl_setup_failure
00000000004008e1 t __afl_setup_first
00000000004008a0 t __afl_store
000000000060209c b __afl_temp

Save OR Not
Coverage
Coverage Guided Fuzzing

Instrumented program

Captures Random Executes


Initial
Seeds
Inputs Input Mutation Input Mutated Program
Input

0000000000602088 b __afl_area_ptr
0000000000400b9e t __afl_die
0000000000602098 b __afl_fork_pid
0000000000400ab9 t __afl_fork_resume
0000000000400a21 t __afl_fork_wait_loop
00000000004009fb t __afl_forkserver
00000000006020a8 B
__afl_global_area_ptr
0000000000400890 t __afl_maybe_log
0000000000602090 b __afl_prev_loc
00000000004008b8 t __afl_return
00000000004008c0 t __afl_setup
0000000000400ba6 t __afl_setup_abort
00000000006020a0 b __afl_setup_failure
00000000004008e1 t __afl_setup_first
00000000004008a0 t __afl_store
000000000060209c b __afl_temp

New Branch Coverage


Save OR Not
Coverage
Class of vulnerablities

Buffer Overflow

Buffer [6 Bytes]

[1] [2] [3] [4] [5] [6]


Class of vulnerablities

Buffer Overflow

Buffer [6 Bytes] Overflow

[1] [2] [3] [4] [5] [6] [A] [A]


Class of vulnerablities

use-after-free – Initializing the free memory

Other Objects

Initialized buffer
313

Allocated buffer
Class of vulnerablities

use-after-free – Initializing the free memory

Other Objects

Initialized buffer
313

void *memset(void *s, int c, size_d 13);

Allocated buffer
13

Pointer to a Value to be Number for


memory stored char to be
block stored
Class of vulnerablities

use-after-free – Initializing the free memory

Other Objects

Initialized buffer
313

Freed memory

Allocated buffer
13
0000000000400c77 t .AFL_SHM_ENV
White box fuzzing 0000000000400c77
0000000000601e10
t
d
.AFL_VARS
_DYNAMIC
0000000000602000 d _GLOBAL_OFFSET_TABLE_
0000000000400d10 R _IO_stdin_used
0000000000400e6c r __FRAME_END__
0000000000400d38 r __GNU_EH_FRAME_HDR
0000000000200db8 d _DYNAMIC 0000000000602080 D __TMC_END__
0000000000200fa8 d _GLOBAL_OFFSET_TABLE_ 0000000000602088 b __afl_area_ptr
0000000000000820 R _IO_stdin_used 0000000000400b9e t __afl_die
w _ITM_deregisterTMCloneTable 0000000000602098 b __afl_fork_pid
w _ITM_registerTMCloneTable 0000000000400ab9 t __afl_fork_resume
000000000000098c r __FRAME_END__ 0000000000400a21 t __afl_fork_wait_loop
0000000000000848 r __GNU_EH_FRAME_HDR 00000000004009fb t __afl_forkserver
0000000000201010 D __TMC_END__ 00000000006020a8 B __afl_global_area_ptr
0000000000201010 B __bss_start 0000000000400890 t __afl_maybe_log
w __cxa_finalize@@GLIBC_2.2.5 0000000000602090 b __afl_prev_loc
0000000000201000 D __data_start 00000000004008b8 t __afl_return
00000000000006d0 t __do_global_dtors_aux 00000000004008c0 t __afl_setup
0000000000200db0 t __do_global_dtors_aux_fini_array_entry 0000000000400ba6 t __afl_setup_abort
0000000000201008 D __dso_handle 00000000006020a0 b __afl_setup_failure
0000000000200da8 t __frame_dummy_init_array_entry 00000000004008e1 t __afl_setup_first
w __gmon_start__ 00000000004008a0 t __afl_store
0000000000200db0 t __init_array_end 000000000060209c b __afl_temp
0000000000200da8 t __init_array_start 0000000000602080 B __bss_start
U __isoc99_scanf@@GLIBC_2.7 0000000000602070 D __data_start
0000000000000810 T __libc_csu_fini 00000000004007e0 t __do_global_dtors_aux
00000000000007a0 T __libc_csu_init 0000000000601e08 t __do_global_dtors_aux_fini_array_entry
U __libc_start_main@@GLIBC_2.2.5 0000000000602078 D __dso_handle
U __stack_chk_fail@@GLIBC_2.4 0000000000601e00 t __frame_dummy_init_array_entry
0000000000201010 D _edata w __gmon_start__
0000000000201018 B _end 0000000000601e08 t __init_array_end
0000000000000814 T _fini 0000000000601e00 t __init_array_start
00000000000005a8 T _init U __isoc99_scanf@@GLIBC_2.7
0000000000000610 T _start 0000000000400d00 T __libc_csu_fini
0000000000201010 b completed.7698 0000000000400c90 T __libc_csu_init
0000000000201000 W data_start U __libc_start_main@@GLIBC_2.2.5
0000000000000640 t deregister_tm_clones 0000000000400760 T _dl_relocate_static_pie
0000000000000710 t frame_dummy 0000000000602080 D _edata
000000000000071a T main 00000000006020b0 B _end
U printf@@GLIBC_2.2.5 U _exit@@GLIBC_2.2.5
0000000000000680 t register_tm_clones 0000000000400d04 T _fini
0000000000400650 T _init
gcc program.c
0000000000400730 T _start
U atoi@@GLIBC_2.2.5
U close@@GLIBC_2.2.5
0000000000602080 b completed.7698
afl-clang program.c
White box fuzzing

$ cat program.c

#include<stdio.h>
int main() {
int a, b, sum;
printf("\nEnter two number: ");
scanf("%d %d", &a, &b);
sum = a + b;
printf("Sum : %d", sum);
return(0);
}

Enter two number: 2 2


Sum: 4
White box fuzzing

$ cat program.c

#include<stdio.h>
int main() {
int a, b, sum;
printf("\nEnter two number: ");
scanf("%d %d", &a, &b);
sum = a + b;
121 123 124 125 224 443
printf("Sum : %d", sum);
return(0); Constraints from point A to B

Enter two number: 2 2


Sum: 4
AFL – American Fuzzing Lop

Bunny the fuzzer - Michał Zalewski

Input based fuzzer


How AFL Works

Instruments 1
Compile your 3
your target AFL mangles
binary with
AFL testcase

Provide an 2 Executes
input compiled binary
(File) using mutated
Instrumentation ejected in binary is to capture

testcase

G1 4
EF F G
branch, edges, coverage point.

Instruments your binary by replacing the CC with D A


BC BE

Input can be anything, .xml .png .wav .txt etc.

Mutates the testcases (Input files)


afl-gcc or afl-clang A
: 1 C
Provide input file to the targeted OG : A
cur_location = <COMPILE_TIME_RANDOM>;
M T
shared_mem[cur_location ^ prev_location]++; instrumented binary (.txt, .xml,
prev_location = cur_location >> 1; .pcap, .wav etc)

Depending on your binary


Analyze and
stores findings in
output directory
Process Timing

Process timing:
This gives an idea about time elapsed in
fuzzing, run time, and last unique crash
and hang.
Overall Results

Overall results:
This gives information about cycles done,
total path covered so far, and count of
unique hangs and crash.
Cycle Progress

Cycle progress:
ID of current testcase.
Map Coverage

Map coverage:
The section provides some trivia about
the coverage observed by the
instrumentation embedded in the target
binary.
Stage Process

Stage progress:
The section gives an in-depth idea at
what the fuzzer is doing right now. It has
nine core methods which is elaborated
further.
Findings in Depth

Findings in depth:
Favored paths – select paths on priority
ones.
New edges – path results in better edge
coverage.
Total crashes and timeouts.
Fuzzing Yields

Fuzzing yields:
This is elaborated further in AFL fuzzing
strategy
Path Geometry

Path geometry:
Levels – Level of initial testcase.
Pending – New testcase which are yet to
use in fuzzing.
Pend fav – Pending testcases
Own find – New paths found by fuzzing
instance.
Imported – Any paths imported from
other fuzzer.
Stability – How stable the fuzzer is while
fuzzing the targeted binary.
CPU Utlization

The term is pretty much self-explanatory,


this shows the CPU utilization while
fuzzing.
(afl-gotcpu)
AFL Strategy

Calibration - pre-fuzzing stage where the


execution path is examined.
Trim - another pre-fuzzing stage where the
test case is trimmed to the shortest.
Bitflip - There are number of bits toggled at
any given time in input file.
Arith - The fuzzer tries to subtract or add small
integers.
Interest - The fuzzer has a list of known
interesting bits and values to try.
Extras – User or auto dictionary.
Havoc – Various stack-based operations.
Splice - It is equivalent to 'havoc', except
that it first splices together two random inputs
from the queue.
Sync – Master and slave (Parallel fuzzing).
Flips, Tweaks, Splice - Repeat

Entry point #1

Point #2 static int afl_splice(mutate_info_t * info, mutate_buffer_t * buf)


Flips {
if (info->stage_cur > MAX(HAVOC_MIN, SPLICE_HAVOC * (info->perf_score / info-
Point #3 >havoc_div) / 100))
Tweaks
return MUTATOR_DONE;

Point #4 return splice_buffers(info, buf);

Splice }

….

Yeil Point 12,13,14,15


ds
Basic AFL Utils

Name Description

afl-gcc Replacement for gcc, used to recompile binary.

afl-clang Replacement for clang, used to recompile binary.

afl-fuzz This program takes a binary and attempts a variety of fuzzing strategies.

afl-cmin If a large corpus of data is available for screening, afl-cmin can be used
to reject redundant files.
afl-gotcpu Shows CPU utilization.

afl-showmap It runs the targeted binary and displays the contents of the trace bitmap in
a human-readable form.
afl-plot It generates gnuplot images from output data.

afl-tmin Test case minimizer

afl-whatsup It checks if the fuzzer is alive.

afl-analyze The tool takes an input file, sequentially flips bytes in this data stream.

Not an exhaustive list…


Basic AFL Utils

Name Description

CC & CXX You will need to override the CC or CXX environment variable before
triggering the configure script.
./configure This script is responsible for getting ready to build the binary and check
required dependencies.
--disable-shared Don’t build shared libraries

Makefile ./configure script produces a customized Makefile specific according to


your system, Makefile runs a series of task defined in it.
CMakeList.txt The file CMakeList.txt is the input to the CMake build system for building
software packages.
@@ For programs that take input from a file, use '@@' to mark the location in the
target.
echo core > It instructs the system to save coredumps as a file instead sending them to
/proc/sys/kernel/core_pattern system-based crash handler app.
General Idea – Configure and Make

./configure --flags Makefile à make –j4


Number of threads
Creates Makefile OR
make -j $(nproc)

Program.c Program.c

./configure script produces a customized Makefile specific according to your system and then Makefile runs a series of task
defined in it.
Prerequisities & Installation

#! /bin/bash

$ sudo apt-get update $ cd qemu_mode


Installing QEMU

$ sudo apt-get install build-essential $ ./build_qemu_support.sh

$ sudo apt-get install clang # Allows non-instrumented binaries to be run under afl-fuzz.

$ sudo apt-get install gcc

$ sudo apt-get install gdb

$ git clone https://github.com/google/AFL.git $ git clone https://github.com/AFLplusplus/AFLplusplus.git


Installing
$ cd AFL ; make clean all from source $ cd AFLplusplus ; make source-only

$ sudo make install $ sudo make install

OR
$ sudo apt-get install afl
Prerequisities & Installation - Docker
#
# This Dockerfile for AFLplusplus uses Ubuntu 20.04 focal and
# installs LLVM 11 from llvm.org for afl-clang-lto support :-)
# It also installs gcc/g++ 10 from the Ubuntu development platform
# has focal has gcc-10 but not g++-10 ...
#

FROM ubuntu:20.04
MAINTAINER afl++ team <[email protected]>
LABEL "about"="AFLplusplus docker image"

ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get upgrade -y && \


apt-get -y install --no-install-suggests --no-install-recommends \
automake \
bison flex \
build-essential \
git \
python3 python3-dev python3-setuptools python-is-python3 \
libtool libtool-bin \
libglib2.0-dev \
wget vim jupp nano \
apt-utils apt-transport-https ca-certificates gnupg dialog \
libpixman-1-dev

RUN echo deb http://apt.llvm.org/focal/ llvm-toolchain-focal main >> /etc/apt/sources.list && \


wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -

RUN echo deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu focal main >> /etc/apt/sources.list && \


$ docker pull aflplusplus/aflplusplus
apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 1E9377A2BA9EF27F

RUN apt-get update && apt-get upgrade -y

RUN apt-get install -y gcc-10 g++-10 gcc-10-plugin-dev gcc-10-multilib \


$ docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus
libc++-10-dev gdb lcov

RUN apt-get install -y clang-11 clang-tools-11 libc++1-11 libc++-11-dev \


libc++abi1-11 libc++abi-11-dev libclang1-11 libclang-11-dev \
libclang-common-11-dev libclang-cpp11 libclang-cpp11-dev liblld-11 \
liblld-11-dev liblldb-11 liblldb-11-dev libllvm11 libomp-11-dev \
libomp5-11 lld-11 lldb-11 llvm-11 llvm-11-dev llvm-11-runtime llvm-11-tools

RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 0


RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 0

RUN rm -rf /var/cache/apt/archives/*

ARG CC=gcc-10
ARG CXX=g++-10
ARG LLVM_CONFIG=llvm-config-11

RUN git clone https://github.com/AFLplusplus/AFLplusplus


RUN cd AFLplusplus && export REAL_CXX=g++-10 && make distrib && \
make install && make clean

RUN git clone https://github.com/vanhauser-thc/afl-cov afl-cov


RUN cd afl-cov && make install

RUN echo 'alias joe="jupp --wordwrap"' >> ~/.bashrc

ENV AFL_SKIP_CPUFREQ=1

Source: https://github.com/AFLplusplus/AFLplusplus/blob/stable/Dockerfile
Prerequisities & Installation – AFL Utils

Utilities for automated crash sample processing/analysis, easy afl-fuzz job management and corpus
optimization

Prerequisites:
$ git clone https://gitlab.com/rc0r/afl-utils
$ sudo apt-get install python3-pip
$ sudo pip3 install setuptools

Setup:
$ cd afl-utils
$ python3 setup.py install
$ echo "source /usr/lib/python3.6/site-packages/exploitable-1.32_rcor-
py3.6.egg/exploitable/exploitable.py" >> ~/.gdbinit

Verify:
$ afl-collect –-help
AFL v/s AFL++

Source: https://github.com/AFLplusplus/AFLplusplus/
Coffee – Break
STDIO/IN

$ cat buffer.c 0000000000200db0 d _DYNAMIC


0000000000200fa0 d _GLOBAL_OFFSET_TABLE_
0000000000000890 R _IO_stdin_used
#include <stdio.h> w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
void input() 0000000000000a5c r __FRAME_END__
00000000000008c8 r __GNU_EH_FRAME_HDR
0000000000201010 D __TMC_END__
{ 0000000000201010 B __bss_start
printf(”pwnFunction\n"); w __cxa_finalize@@GLIBC_2.2.5
0000000000201000 D __data_start
} 0000000000000720 t __do_global_dtors_aux
0000000000200da8 t __do_global_dtors_aux_fini_array_entry
void zero() 0000000000201008 D __dso_handle
0000000000200da0 t __frame_dummy_init_array_entry
w __gmon_start__
{ 0000000000200da8 t __init_array_end
char buffer[313]; 0000000000200da0 t __init_array_start
printf("Enter your text:"); U __isoc99_scanf@@GLIBC_2.7
0000000000000880 T __libc_csu_fini
scanf("%s", buffer); 0000000000000810 T __libc_csu_init
printf("You entered: %s", buffer); U __libc_start_main@@GLIBC_2.2.5
U __stack_chk_fail@@GLIBC_2.4
} 0000000000201010 D _edata
0000000000201018 B _end
int main() 0000000000000884 T _fini
00000000000005e0 T _init
0000000000000660 T _start
{ 0000000000201010 b completed.7698
zero(); 0000000000201000 W data_start
0000000000000690 t deregister_tm_clones
return 0; 000000000000077d T echo
} 0000000000000760 t frame_dummy
000000000000076a T input
00000000000007f5 T main
$ gcc buffer.c U printf@@GLIBC_2.2.5
U puts@@GLIBC_2.2.5
$ ./a.out
00000000000006d0 t register_tm_clones
Enter some text:AAAAAAAAAAA
You entered: AAAAAAAAAAA
STDIO/IN

$ cat buffer.c 0000000000400d8f t .AFL_SHM_ENV


0000000000400d8f t .AFL_VARS
0000000000601e10 d _DYNAMIC
#include <stdio.h> Import Header 0000000000602000 d _GLOBAL_OFFSET_TABLE_
STDIO 0000000000400e20 R _IO_stdin_used
void input() 0000000000400fd4 r __FRAME_END__
0000000000400e58 r __GNU_EH_FRAME_HDR
0000000000602088 D __TMC_END__
{ 0000000000602090 b __afl_area_ptr
printf(”pwnFunction\n"); 0000000000400cb6 t __afl_die
00000000006020a0 b __afl_fork_pid
} 0000000000400bd1 t __afl_fork_resume
Catch the secret ()
0000000000400b39 t __afl_fork_wait_loop
void zero() 0000000000400b13 t __afl_forkserver
00000000006020b0 B __afl_global_area_ptr
00000000004009a8 t __afl_maybe_log
{ Simple overflow here. 0000000000602098 b __afl_prev_loc
char buffer[313]; 00000000004009d0 t __afl_return
printf("Enter your text:"); 00000000004009d8 t __afl_setup
0000000000400cbe t __afl_setup_abort
scanf("%s", buffer); 00000000006020a8 b __afl_setup_failure
printf("You entered: %s", buffer); 00000000004009f9 t __afl_setup_first
00000000004009b8 t __afl_store
} 00000000006020a4 b __afl_temp
0000000000602088 B __bss_start
int main() 0000000000602078 D __data_start
0000000000400820 t __do_global_dtors_aux
0000000000601e08 t __do_global_dtors_aux_fini_array_entry
{ 0000000000602080 D __dso_handle
zero(); 0000000000601e00 t __frame_dummy_init_array_entry
…..
return 0; U getenv@@GLIBC_2.2.5
} 0000000000400860 T input
0000000000400930 T main_2.2.5

$ afl-gcc buffer.c
$ ./a.out
Enter some text:AAAAAAAAAAA
You entered: AAAAAAAAAAA
Difference in CC
0000000000400d8f t .AFL_SHM_ENV 0000000000400d8f t .AFL_SHM_ENV 000000000063c810 D _ZN11__sanitizer14IOCTL_TIOCMSETE
0000000000400d8f t .AFL_VARS 0000000000400d8f t .AFL_VARS 000000000063c808 D _ZN11__sanitizer14IOCTL_TIOCNXCLE
0000000000601e10 d _DYNAMIC 0000000000601e10 d _DYNAMIC 000000000063c804 D _ZN11__sanitizer14IOCTL_TIOCOUTQE
0000000000602000 d _GLOBAL_OFFSET_TABLE_ 0000000000602000 d _GLOBAL_OFFSET_TABLE_ 000000000063c7f8 D _ZN11__sanitizer14IOCTL_TIOCSETDE
0000000000400e20 R _IO_stdin_used 0000000000400e20 R _IO_stdin_used 0000000000408410 T
0000000000400fd4 r __FRAME_END__ 0000000000400fd4 r __FRAME_END__ _ZN11__sanitizer14InternalCallocEmmPNS_28SizeClassAllocatorLocalC
0000000000400e58 r __GNU_EH_FRAME_HDR 0000000000400e58 r __GNU_EH_FRAME_HDR acheINS_20SizeClassAllocator32INS_4AP32EEEEE
0000000000602088 D __TMC_END__ 0000000000602088 D __TMC_END__ 0000000000414610 T _ZN11__sanitizer14IsAbsolutePathEPKc
0000000000602090 b __afl_area_ptr 0000000000602090 b __afl_area_ptr 0000000000420e90 T
0000000000400cb6 t __afl_die 0000000000400cb6 t __afl_die _ZN11__sanitizer14LLVMSymbolizer11SymbolizePCEmPNS_15SymbolizedSt
00000000006020a0 b __afl_fork_pid 00000000006020a0 b __afl_fork_pid ackE
0000000000400bd1 t __afl_fork_resume 0000000000400bd1 t __afl_fork_resume 0000000000421040 T
0000000000400b39 t __afl_fork_wait_loop 0000000000400b39 t __afl_fork_wait_loop _ZN11__sanitizer14LLVMSymbolizer13SymbolizeDataEmPNS_8DataInfoE
0000000000400b13 t __afl_forkserver 0000000000400b13 t __afl_forkserver 00000000004206e0 T
00000000006020b0 B __afl_global_area_ptr 00000000006020b0 B __afl_global_area_ptr _ZN11__sanitizer14LLVMSymbolizer20FormatAndSendCommandEbPKcmNS_10
00000000004009a8 t __afl_maybe_log 00000000004009a8 t __afl_maybe_log ModuleArchE
0000000000602098 b __afl_prev_loc 0000000000602098 b __afl_prev_loc 0000000000420030 T
00000000004009d0 t __afl_return 00000000004009d0 t __afl_return _ZN11__sanitizer14LLVMSymbolizerC1EPKcPNS_17LowLevelAllocatorE
00000000004009d8 t __afl_setup 00000000004009d8 t __afl_setup 0000000000420030 T
0000000000400cbe t __afl_setup_abort 0000000000400cbe t __afl_setup_abort _ZN11__sanitizer14LLVMSymbolizerC2EPKcPNS_17LowLevelAllocatorE
00000000006020a8 b __afl_setup_failure 00000000006020a8 b __afl_setup_failure 0000000000413dc0 T _ZN11__sanitizer14MmapFixedOrDieEmm
00000000004009f9 t __afl_setup_first 00000000004009f9 t __afl_setup_first 000000000088d548 B _ZN11__sanitizer14PageSizeCachedE
00000000004009b8 t __afl_store 00000000004009b8 t __afl_store 000000000041d690 T _ZN11__sanitizer14SleepForMillisEi
00000000006020a4 b __afl_temp 00000000006020a4 b __afl_temp 0000000000418f30 W _ZN11__sanitizer14SymbolizerTool5FlushEv
0000000000602088 B __bss_start 0000000000602088 B __bss_start 000000000041f790 W
0000000000602078 D __data_start 0000000000602078 D __data_start _ZN11__sanitizer14SymbolizerTool8DemangleEPKc
0000000000400820 t __do_global_dtors_aux 0000000000400820 t __do_global_dtors_aux 0000000000419d90 T
0000000000601e08 t __do_global_dtors_aux_fini_array_entry 0000000000601e08 t __do_global_dtors_aux_fini_array_entry _ZN11__sanitizer14ThreadRegistry10FindThreadEPFbPNS_17ThreadConte
0000000000602080 D __dso_handle 0000000000602080 D __dso_handle xtBaseEPvES3_
0000000000601e00 t __frame_dummy_init_array_entry 0000000000601e00 t __frame_dummy_init_array_entry 000000000041a1a0 T
….. w __gmon_start__ _ZN11__sanitizer14ThreadRegistry10JoinThreadEjPv
U getenv@@GLIBC_2.2.5 0000000000601e08 t __init_array_end 000000000041a550 T
0000000000400860 T input 0000000000601e00 t __init_array_start _ZN11__sanitizer14ThreadRegistry11StartThreadEjmbPv
0000000000400930 T main_2.2.5 U __isoc99_scanf@@GLIBC_2.7 000000000042e72c _ZN11__sanitizer14ThreadRegistry11kUnknownTidE
0000000000400e10 T __libc_csu_fini
0000000000400da0 T __libc_csu_init $ afl-clang-fast
$ afl-gcc U __libc_start_main@@GLIBC_2.2.5
00000000004007a0 T _dl_relocate_static_pie
0000000000602088 D _edata
00000000006020b8 B _end
U _exit@@GLIBC_2.2.5
0000000000400e14 T _fini

$ afl-clang

Instrumentation Coverage
__afl_maybe_log()

Small C program
__afl_maybe_log()

Strings from binutils


__afl_maybe_log()

Strings from binutils


Variable Declarations

__afl_maybe_log()

__afl_setup()

__afl_setup_first()

__afl_store()

__afl_forkserver()

__afl_fork_wait_loop()

__afl_fork_resume()

__afl_setup_abort()

__afl_return()

__afl_global_area_ptr

__afl_area_ptr

__afl_fork_pid

__afl_prev_loc

__afl_setup_failure

__afl_temp
Exercise
Fuzzing STDIN/IO
App Directory

~/home/fuzzing/
|_AFLplusplus <---- Installation directory of AFL
|_Targets <---- Targets to fuzz
|_corpus <---- Relevant seeds for targets
|_output <---- Output generated by AFL while fuzzing
App Directory

~/home/fuzzing/
|_AFLplusplus <---- Installation directory of AFL
|_Targets <---- Targets to fuzz
|_corpus <---- Relevant seeds for targets
|_output <---- Output generated by AFL while fuzzing
|_default <---- Default path
|_queue <---- Queue Seeds for new execution path
|_crashes <---- Seeds that caused program a crash
|_hangs <---- Seeds that caused program timeout

Although not necessary AFL_HANG_TMOUT to set timeout


Understanding Output

id:000004,sig:11,src:000000,op:havoc,rep:8

Seed ID ID of the testcase Havoc, 8 rounds


use as input of random tweaks
Understanding Output

id:000004,sig:11,src:000000,op:havoc,rep:8 +cov

Seed ID ID of the testcase Havoc, 8 rounds Improved coverage


use as input of random tweaks
Simple Crash Triage

for crash in $DIR/crashes/id:*; do


id=`basename -- "$crash" | cut -d, -f1 | cut -d: -f2`
sig=`basename -- "$crash" | cut -d, -f2 | cut -d: -f2`
# Grab the args, converting @@ to $crash
use_args=""
use_stdio=1
for a in $@; do
Assumes targeted application reads from stdin. if [ "$a" = "@@" ] ; then
args="$use_args $crash"
unset use_stdio
else
args="$use_args $a"
fi
done
Sample Makefile

# Sample Makefile
all: #Target name
afl-clang-fast buffer.c -o buffer

# Sample Makefile with variables $ make

CC=afl-clang-fast #Compiler afl-clang-fast buffer.c -o buffer


Declared
TARGET=buffer #Filename afl-clang-fast++2.66c by <[email protected]> in CLASSIC mode
afl-llvm-pass++2.66c by <[email protected]> and
all: <[email protected]>
Called
$(CC) buffer.c -o $(TARGET) [+] Instrumented 3 locations (non-hardened mode, ratio 100%).
clean: $ make clean
make clean
rm $(TARGET) rm buffer
$
Targets

Selecting Targets and Fuzzing Targets

Source: https://lcamtuf.coredump.cx/afl/
Targets we are fuzzing

Sr .No Tragets Software maintainer


1 GNU Binutils GNU
2 LibWav Marc Volker
3 Tcpdump The Tcpdump Group
4 Xpdf Derek Noonburg
5 Hermes Facebook
6 VIM VIM (Brammool)
/home/fuzzing/examples/
Exercise
Fuzzing Targets under /home/fuzzing/examples/
Targets – Ubuntu Packages

apt search package_name

apt show package_name

apt install package_name


Not a pro tip #1

#!/usr/bin/env bash apt-cache search package_name


base_dir=$pwd
apt-search file file_name

echo "[+] Installing common libraries for enhanced fuzzing support"

sudo apt-get update && sudo apt-get -y upgrade

sudo apt-get install -y build-essential nmap build-essential llvm libcairo2-dev \

libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev nmap afl-clang git curl wireshark clang gdb bison \

libbison-dev zita-rev1 python-parsley btyacc bnfc racc libreadline-dev libssl-dev libpq5 libpq-dev \

libreadline5 libsqlite3-dev libpcap-dev autoconf postgresql pgadmin3 curl zlib1g-dev libxml2-dev libxslt1-dev \

libyaml-dev curl zlib1g-dev gawk bison libffi-dev libgdbm-dev libncurses5-dev libtool sqlite3 libgmp-dev \

gnupg2 dirmngr screen re2c pkg-config lib32asan2 valgrind qt4-qmake libqt4-dev tcpdump cmake python3 flex \

make openssl libgbm1 gdbserver net-tools fontconfig libpango1.0-dev libxft2 libxft-dev libcups2-dev libcork-dev \

libqt5core5a libqtcore4 libqt5gui5 libqt5network5 libqt4-network libreadline-dev libconfig-dev libssl-dev \

lua5.2 liblua5.2-dev libevent-dev libjansson-dev libpython-dev fossil libavis-dev harvid libavahi-glib-dev \

libswscale-dev liba52-0.7.4-dev libxcb-xkb-dev libxcb-composite0-dev libdssialsacompat-dev alsa-utils \

libao-dev apt-file python-pip dput librivet-dev libcue-dev libbellesip-dev libbctoolbox-dev libantlr3c-dev \

nvptx-tools texi2html libgnutls-dane0 gnuastro auctex a2ps ; sudo apt-get install -y --reinstall texinfo ; sudo apt-get install -y libgd-dev \

libsynctex-dev unrar php7.1 postgresql-client-10 libqt4-sql-psql pspg libsipwitch-dev sipwitch p7zip-full zlib1g libzzip-dev \

libsdl2-dev openssh-server libelf-dev zstd libboost-all-dev g++ automake autoconf autoconf-archive libtool liblz4-dev liblzma-dev \

zlib1g-dev make libjsoncpp-dev libiberty-dev qemu-kvm qemu virt-manager libavcodec-dev libavutil-dev virt-viewer libvirt-bin \

libdlna-dev winff mencoder libdlna-dev libchromaprint-dev libchromaprint-tools libchromaprint1 libsoxr-dev libcap-dev libsoxr0 checkinstall \

Source: https://raw.githubusercontent.com/RootUp/PersonalStuff/master/pack.sh
Lunch - Break
Smart Fuzzing
Input Generation – Phase 1

Small seeds are always better

Seed inputs must cover different branches

Remove duplicate seeds covering the same branches


Input Generation - Ni
void mutate_area(const char *data, size_t end) {
static char buff[BUFSIZE];
A tiny input generation library written in C. retry:
switch(random() % 35) {
• https://gitlab.com/akihe/ni case 0: { /* insert a random byte */
size_t pos = (end ? random() % end : 0);
write_all(data, pos);
LOGM("ins");
buff[0] = random() & 255;
write_all(buff, 1);
write_all(data + pos, end - pos);
break; }
case 1: { /* drop a byte */
size_t pos = (end ? random() % end : 0);
if (pos+1 >= end)
goto retry;
LOGM("drop");
write_all(data, pos);
write_all(data+pos+1, end-(pos+1));
break; }
case 2:
….
Input Generation – Radamsa

A general-purpose fuzzer, more powerful than Ni.

• https://gitlab.com/akihe/radamsa

$ sudo apt-get install gcc make git wget


Installation
$ git clone https://gitlab.com/akihe/radamsa.git && cd radamsa && make && sudo make install

$ echo "aaa" | radamsa


Simple testcase
aaaa
Input Generation – Radamsa

Making corpus for AFL via Radamsa $ echo 1337 | ./radamsa


-132?5
$ echo 1337 | ./radamsa
1
$ echo 1337 | ./radamsa
--1
$ echo 1337 | ./radamsa
6261708
$ echo 1337 | ./radamsa
?????$ echo 1337 | ./radamsa
1337
$ echo 1337 | ./radamsa
37
$ echo 1337 | ./radamsa
--157
$ echo 1337 | ./radamsa
1336
…..
Input Generation – Radamsa

Making corpus for AFL via Radamsa $ echo 1337 | ./radamsa


-132?5

$ radamsa –o outdir/output_corpus%n.ext –n 50 –r input/sample_corpus.ext –m ft=3 $ echo 1337 | ./radamsa


1
$ echo 1337 | ./radamsa
%n = corpus number Megabytes output per second.
--1
$ echo 1337 | ./radamsa
6261708
$ echo 1337 | ./radamsa
?????$ echo 1337 | ./radamsa
1337
$ echo 1337 | ./radamsa
37
$ echo 1337 | ./radamsa
--157
$ echo 1337 | ./radamsa
1336
…..
laf-intel instrumentation – More Code coverage - Phase 2

skip trivial switch..


Entry point #1 LLVM Passes switch: 2 cases 8 bit
skip trivial switch..
switch: 3 cases 8 bit
skip trivial switch..
switch: 2 cases 32 bit
switch: 2 cases 32 bit
Point #2 switch: 2 cases 31 bit
switch: 2 cases 32 bit
Split-switches-pass
....

p switch: 2 cases 32 bit


em
cm Point #3 switch: 2 cases 32 bit
m
mp, switch: 3 cases 32 bit
rc Split-compare-pass
st
or
m Running compare-transform-pass by [email protected], extended by [email protected]
sf Replacing 80 calls to strcmp/memcmp/strncmp/strcasecmp/strncasecmp
ran
T
strcmp: unroll len 3: ex
Point #4 strcmp: unroll len 7: normal
strcmp: unroll len 7: redraw
Compare transform pass strcmp: unroll len 5: expr
…. New code coverage
strcmp: unroll len 5: call
strcmp: unroll len 5: mode
strcmp: unroll len 8: in_mode
strcmp: unroll len 6: in_io
strcmp: unroll len 7: out_io
strcmp: unroll len 7: err_io

Point 12,13,14,15

To enable the passes you must set environment variables before you compile the target project.
Environment Variables

What are env variables, how we use it?

$ export LD_PRELOAD=

$ export AFL_EXIT_WHEN_DONE=

$ export AFL_INST_RATIO=

$ export AFL_HARDEN=

$ export AFL_LLVM_LAF_SPLIT_SWITCHES=

$ export AFL_LLVM_LAF_SPLIT_COMPARES=

$ export AFL_LLVM_LAF_SPLIT_FLOATS=
….

Useful for sometimes of custom fuzzing setups.


Test Case Minimization

function getopt(argc, argv, options, thisopt, i)


{
if (length(options) == 0) # no options given
return -1
if (argv[Optind] == "--") { # all done
Optind++
_opti = 0
return -1
} else if (argv[Optind] !~ /^-[^:\t ]/) {
_opti = 0
return -1
Minimize a test corpus of input files, can also be used post }
fuzzing. if (_opti == 0)
_opti = 2
thisopt = substr(argv[Optind], _opti, 1)
Optopt = thisopt
i = index(options, thisopt)
if (i == 0) {
if (Opterr)
printf("%c -- invalid option\n", thisopt) >
"/dev/stderr”
if (_opti >= length(argv[Optind])) {
Optind++
_opti = 0
} else
_opti++
return "?"
Exercise
Fuzzing Targets under /home/fuzzing/examples/ + Radamsa + LAF + Test case minimization
Custom Mutators

Shared object file can always be imported under LD_PRELOAD= radamsa-mutator.so

Example: $ CFLAGS="-fPIC" make lib/libradamsa.so


grammar_mutator honggfuzz libfuzzer radamsa symcc
Case Study - Samsung MMS Exploit

What are env variables, how we use it?

$ export AFL_PRELOAD=

Source: https://github.com/googleprojectzero/SkCodecFuzzer
Exercise
Fuzzing Targets under /home/fuzzing/examples/ + Custom Mutator + LAF + Test case minimization + AFL Plot
Effective Triage Analysis

Not all crashes are exploitable, how do verify this?

try:
We can verify this via certain GDB plugins.
disas = gdb.execute("disas $pc", False, True).splitlines()

1. Attach the binary in GDB except RuntimeError as e:


2. Pass malformed input generated by AFL warnings.warn(str(e))
3. Import GDB addon
return
4. Check exploitable or not
pos = 0
for line in disas:
if self._re_gdb_pc.match(line):
You would find this under, /home/fuzzing/exploitable
break
pos += 1
print("\n".join(disas[max(pos-5, 0):pos+5]))
Effective Triage Analysis

Getting crash summary with unique EIP’s

---CRASH SUMMARY---
Filename: in/test.bit
SHA1: c7a2bbb62ac19b8cf0fb6e805652b7194dd0c86a
Classification: UNKNOWN
Hash: 4047a4349a30f16d63eb90faaf9a7b7d.c0034fe36fde214ae3d25dfc815ec415
Command: ./Thordec in/test.bit out.yuv
Faulting Frame:
read_block @ 0x000000000040cdac: in /home/dhiraj/thor/build/Thordec
Disassembly:
0x000000000040cd92: lea rax,[r12+rax*4+0x218]
0x000000000040cd9a: add DWORD PTR [rax+r13*4+0x80],ecx
0x000000000040cda2: bsr edx,r11d
0x000000000040cda6: xor edx,0xffffffe0
0x000000000040cda9: add edx,0x1d
=> 0x000000000040cdac: add DWORD PTR [rax+rdx*4+0xbc],ecx
0x000000000040cdb3: imul rax,r15,0x64
0x000000000040cdb7: lea rax,[r12+rax*1+0x218]
0x000000000040cdbf: lea rdx,[rdx+rdx*4]
0x000000000040cdc3: lea rax,[rax+rdx*4]
Stack Head (6 entries):
read_block @ 0x000000000040cdac: in /home/dhiraj/thor/build/Thordec
decode_block @ 0x000000000040edea: in /home/dhiraj/thor/build/Thordec
process_block_dec_hbd @ 0x000000000040e46b: in /home/dhiraj/thor/build/Thordec
process_block_dec_hbd @ 0x000000000040e3ba: in /home/dhiraj/thor/build/Thordec
decode_frame @ 0x000000000040d5ea: in /home/dhiraj/thor/build/Thordec
main @ 0x000000000040676b: in /home/dhiraj/thor/build/Thordec
Registers:
rax=0x00007fffffff65dc rbx=0x00007fffffffd670 rcx=0x0000000000000000 rdx=0x00000000ffffffff
rsi=0x0000000000000000 rdi=0x00007fffffffd670 rbp=0x00007ffffffecc90 rsp=0x00007ffffffdcaf0
r8=0x0000000000000004 r9=0x0000000000000008 r10=0xffffffffffffffd0 r11=0x0000000000000004
r12=0x00007fffffff63b0 r13=0x0000000000000000 r14=0x0000000000000000 r15=0x0000000000000001
rip=0x000000000040cdac efl=0x0000000000010286 cs=0x0000000000000033 ss=0x000000000000002b
ds=0x0000000000000000 es=0x0000000000000000 fs=0x0000000000000000 gs=0x0000000000000000
Extra Data:
Description: Access violation
Short description: AccessViolation (21/22)
Explanation: The target crashed due to an access violation but there is not enough
additional information available to determine
exploitability.
---END SUMMARY---
Exercise
Perform triage anylasis
llvm-symbolizer

Converts address into source code lines/locations

Source: https://llvm.org/docs/CommandGuide/llvm-symbolizer.html
Sanitizer’s – Find bugs during runtime
==20297==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x629000009748 at pc 0x0000004e58b9 bp 0x7ffca5141520 sp 0x7ffca5140cd0
READ of size 17771 at 0x629000009748 thread T0
#0 0x4e58b8 in __asan_memcpy /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:23:3
#1 0x5224a8 in tls1_process_heartbeat /home/input0/heartbleed/BUILD/ssl/t1_lib.c:2586:3
#2 0x58e51d in ssl3_read_bytes /home/input0/heartbleed/BUILD/ssl/s3_pkt.c:1092:4
#3 0x592c5a in ssl3_get_message /home/input0/heartbleed/BUILD/ssl/s3_both.c:457:7
#4 0x55e847 in ssl3_get_client_hello /home/input0/heartbleed/BUILD/ssl/s3_srvr.c:941:4
#5 0x55a8a9 in ssl3_accept /home/input0/heartbleed/BUILD/ssl/s3_srvr.c:357:9
#6 0x51653d in LLVMFuzzerTestOneInput /home/input0/Downloads/fuzzer-test-suite-master/openssl-1.0.1f/target.cc:34:3
#7 0x42dd1c in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:515:13
#8 0x42d57b in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /tmp/final/llvm.src/projects/compiler-

Asan Tsan Msan UBSan


rt/lib/fuzzer/FuzzerLoop.cpp:440:3
#9 0x42efad in fuzzer::Fuzzer::MutateAndTestOne() /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:648:19
#10 0x42f865 in fuzzer::Fuzzer::Loop(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >,
fuzzer::fuzzer_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) /tmp/final/llvm.src/projects/compiler-
rt/lib/fuzzer/FuzzerLoop.cpp:775:5

ThreadSanittizer – Related to concurrency


#11 0x424570 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /tmp/final/llvm.src/projects/compiler-
rt/lib/fuzzer/FuzzerDriver.cpp:754:6
#12 0x446172 in main /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10

MemorySanitizer - Related to memory


#13 0x7f9e23b21b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#14 0x41d609 in _start (/home/input0/heartbleed/openssl-1.0.1f-fsanitize_fuzzer+0x41d609)

AddressSanitizer – Bugs related to


0x629000009748 is located 0 bytes to the right of 17736-byte region [0x629000005200,0x629000009748)

UndefinedBehaviorSanitizer -
allocated by thread T0 here:
#0 0x4e67d3 in __interceptor_malloc /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88:3
#1 0x5c1dbb in CRYPTO_malloc /home/input0/heartbleed/BUILD/crypto/mem.c:308:8
#2 0x594199 in freelist_extract /home/input0/heartbleed/BUILD/ssl/s3_both.c:708:12
#3 0x594199 in ssl3_setup_read_buffer /home/input0/heartbleed/BUILD/ssl/s3_both.c:770
#4 0x59477c in ssl3_setup_buffers /home/input0/heartbleed/BUILD/ssl/s3_both.c:827:7
#5 0x55b474 in ssl3_accept /home/input0/heartbleed/BUILD/ssl/s3_srvr.c:292:9

undefined behavior
#6 0x51653d in LLVMFuzzerTestOneInput /home/input0/Downloads/fuzzer-test-suite-master/openssl-1.0.1f/target.cc:34:3
#7 0x42dd1c in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:515:13
#8 0x42f3ad in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >,
fuzzer::fuzzer_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) /tmp/final/llvm.src/projects/compiler-
rt/lib/fuzzer/FuzzerLoop.cpp:701:3

addressing memory
#9 0x42f6e5 in fuzzer::Fuzzer::Loop(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >,
fuzzer::fuzzer_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) /tmp/final/llvm.src/projects/compiler-
rt/lib/fuzzer/FuzzerLoop.cpp:739:3
#10 0x424570 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /tmp/final/llvm.src/projects/compiler-
rt/lib/fuzzer/FuzzerDriver.cpp:754:6
#11 0x446172 in main /tmp/final/llvm.src/projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#12 0x7f9e23b21b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:23:3 in __asan_memcpy


Shadow bytes around the buggy address:
0x0c527fff9290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c527fff92a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c527fff92b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c527fff92c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c527fff92d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c527fff92e0: 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa fa
0x0c527fff92f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c527fff9300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c527fff9310: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c527fff9320: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c527fff9330: 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
==20297==ABORTING
Sanitizer’s

Buffer overflow

#include <stdio.h>
void secretFunction()
{
printf("pwnFunction!\n");
}
void echo()
Overflow here.
{
char buffer[313];
printf("Enter some text:\n");
scanf("%s", buffer);
printf("You entered: %s\n", buffer);
}
int main()
{
echo();
return 0;
}
Sanitizer’s

Use-after-free

int main(int argc, char** argv){


int* array = new int[100];
delete[] array;
return array[argc];
}
Not a pro tip #2

FYI – Microsoft integrated Address Sanitizer into Visual Studio 2019 version 16.1 Preview 3 and above.

Source: https://devblogs.microsoft.com/cppblog/addresssanitizer-asan-for-the-linux-workload-in-visual-studio-2019/
Exercise
Fuzzing Targets under /home/fuzzing/STDIO
AFL + ASAN

export AFL_USE_ASAN=1

afl-clang-fast -Wall -Wextra -O2 -o wav_info ../../libwav.c wav_info.c


afl-clang-fast++2.66d by <[email protected]> in CLASSIC mode
afl-llvm-pass++2.66d by <[email protected]> and <[email protected]>
[+] Instrumented 57 locations (non-hardened, ASAN mode, ratio 100%).
afl-llvm-pass++2.66d by <[email protected]> and <[email protected]>
[+] Instrumented 7 locations (non-hardened, ASAN mode, ratio 100%).
AFL + ASAN

FYI, AFL_HARDEN & AFL_USE_ASAN

afl-clang-fast -Wall -Wextra -O2 -o wav_info ../../libwav.c wav_info.c


afl-clang-fast++2.66d by <[email protected]> in CLASSIC mode

[-] PROGRAM ABORT : ASAN and AFL_HARDEN are mutually exclusive


Location : edit_params(), afl-clang-fast.c:421

Makefile:10: recipe for target 'wav_info' failed


make: *** [wav_info] Error 1

AFL_HARDEN automatically adds code hardening options which is helpful for catching non-crashing memory bugs.
AFL + ASAN

[-] Whoops, the target binary crashed suddenly, before receiving any input
from the fuzzer! Since it seems to be built with ASAN and you have a
restrictive memory limit configured; this is expected; please read
/usr/local/share/doc/afl/notes_for_asan.md for help.

ASAN on 64-bit systems consumes a lot of memory ; -m to the rescue


AFL + ASAN + LLVM Symbolizer

export ASAN_OPTIONS=symbolize=1

Converts address into source code lines/locations

Source: https://llvm.org/docs/CommandGuide/llvm-symbolizer.html
Not a pro tip #3

export ASAN_OPTIONS="coverage=1:coverage_direct=1"

Sanitizer’s Coverage
Not a pro tip #4

LC_ALL=C

Always check for your `locale` It forces binaries/applications to use the default language for the output.
Exercise
Fuzzing Targets under /home/fuzzing/ASAN/
Domain Specific Fuzzing

Mutated Seed

Initial Seed
Domain Specific Fuzzing

Mutated Seed

Initial Seed
Domain Specific Fuzzing

Reach 1 Reach 3 Reach 5

Mutated Seed

Initial Seed

Reach 2 Reach 4 Reach 6


Domain Specific Fuzzing

Achieving intermediate inputs from is_ms

Reach 1 Reach 3 Reach 5

Mutated Seed

Waypoints
Initial Seed

Reach 2 Reach 4 Reach 6


Domain Specific Fuzzing

Achieving coverage via Waypoints

$ git clone https://github.com/rohanpadhye/FuzzFactory.git

$ cd FuzzFactory ; make llvm-domains


Grammar

Extraction of tokens from corpus

By default, AFL will try to extract existing syntax tokens in the input corpus by watching the instrumentation very closely
during deterministic byte flips. This works for some types of parsers and grammars but isn't nearly as good as the -x
mode.
Grammar

Trim Seed Mutated Seed

Target Instrumented
Program Initial Seeds
Program

Executes in
Updates Queue Program
Grammar

Grammar

Trim Seed Mutated Seed

Target Instrumented
Program Initial Seeds
Program

Executes in
Updates Queue Program
Grammar
Grammar

Grabbing Keywords (Strings)

/home/fuzzing/grammar/strings.sh
Grammar

Capture token during runtime instrumentation of the target via libtokencap


Exercise
Making your own Grammar for Fuzzing
Symbolic Execution - SYMCC

SYMCC is an LLVM based C & C++ compiler that compiles symbolic execution right into the binary. This can be used by software
developers in replacement of clang or clang++

“Symbolic Execution are likely to have a smaller testcases more consistent set of synthetic inputs most of them would be a valid inputs.”

PS: SYMCC is faster than KLEE and QSYM


Day 1 – RECAP

What have we got so far?


Day 1 – Exercise

CVE-2019-20079 use-after-free in VIM


Thank you!
End of Day 1

You might also like