Skip to content

marcinguy/fuzzer

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
v6
 
 
 
 
v7
 
 
 
 

fuzzer

Purpose:

  • closed, proprietary binary and also open source binary, library fuzzing
  • speed

Code and approach is EXPERIMENTAL. YMMV

Ptrace fuzzer experiments based on https://h0mbre.github.io/Fuzzing-Like-A-Caveman-4/#

  • Modified it to snapshot also Heap (needed for a more real target than dummy one)
  • Modified it to snapshot and restore FP (Floating Point) registers along General Purpose registers
  • Fixed small bug with percentage showing of Coverage
  • debuged, debuged, debuged till it work with real target (Oniguruma library :))

TODO:

  • automatic snapshot collection from /proc/maps - DONE
  • shared memory for Corpus - DONE(50% speed increase on one core, multicore/distributed fuzzing)
  • Mutators - DONE
  • Your ideas?

Fuzzing at ca. 60k exec/s. I can imagine you can scale it even more with 25% drop per total cores. With 4 cores I achieved 60k exec/s (25% total drop, since 1 core was ca 20k). Below you can also see how I trigger Stack Protector with my crash. #fuzzing #speed Fuzzing older "Oniguruma" regular expression library

With shared memory corpus and increase of speed on one core to 50%, it could be even 90k exec per second (didn't try yet) on 4 cores.

Setup

Dont forget to:

sudo echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

Thats how proc maps looked on my system (see snapshot.c)

cat /proc/30918/maps | grep rw
0065f000-00664000 rw-p 0005f000 00:34 7868250                            /home/mk/fuzzer/v6
00664000-00685000 rw-p 00000000 00:00 0                                  [heap]
7ffff7dd1000-7ffff7dd3000 rw-p 001c4000 fd:01 13908802                   /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7dd3000-7ffff7dd7000 rw-p 00000000 00:00 0 
7ffff7fc5000-7ffff7fc8000 rw-p 00000000 00:00 0 
7ffff7ffd000-7ffff7ffe000 rw-p 00026000 fd:01 13908788                   /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]

Hopefully, rest you can figure out.

Fuzzer

Additional notes/hints on usage/Troubleshooting

Comment those lines out:

// dup both stdout and stderr and send them to /dev/null
       int fd = open("/dev/null", O_WRONLY);
       dup2(fd, 1);
       dup2(fd, 2);
       close(fd);

You will get the Test case buffer address on start, before hitting SPACE:

share memory attatched at 0x7ffff7ff7000 address
fuzz_location:0x7fffffffe2d0

dragonfly> debuggee pid: 12119
dragonfly> setting 'start/end' breakpoints:

   start-> 0x40185b
   end  -> 0x401863

Data ptr:0x7fffffffe2d0
read size: 0, max_size: 12

Adjust your

void* fuzz_location = (void*)0x7fffffffe2d0; 

The ADDRESS will be different when running in the SHELL and in DRAGONFLY. Use the second one!

Adjust start and end, disassembling the binary (sample ./v7)

   0x000000000040185b <+137>:	mov    rdi,rax
   0x000000000040185e <+140>:	call   0x4015c3 <LLVMFuzzerTestOneInput>
   0x0000000000401863 <+145>:	mov    edi,0x42817f

here:

long long unsigned start_addr = 0x40185b;       
long long unsigned end_addr = 0x401863;  

Breakpoints

Use Ghidra or nm to dump them:

nm -g -C ./v3 | grep " T " | cut -f 1 -d " " > listX.txt

Then generate using this Python Script:

import sys
f = open("listX.txt", "r")
i=0
for x in f:
  x = x[:-1]
  sys.stdout.write("vuln.bp_addresses["+str(i)+"]=0x"+x+";\n") 
  sys.stdout.flush()
  i=i+1

and put in fuzzer.c

Fuzz.

About

Ptrace fuzzer experiments

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages