https://github.com/valldrac/granota
Alternative fuzzing engine for afl-fuzz binary instrumentation code.
https://github.com/valldrac/granota
afl fuzzer genetic-algorithm triage
Last synced: 3 months ago
JSON representation
Alternative fuzzing engine for afl-fuzz binary instrumentation code.
- Host: GitHub
- URL: https://github.com/valldrac/granota
- Owner: valldrac
- License: apache-2.0
- Created: 2016-03-21T05:04:39.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2016-03-21T08:54:01.000Z (about 9 years ago)
- Last Synced: 2025-01-21T00:19:48.298Z (5 months ago)
- Topics: afl, fuzzer, genetic-algorithm, triage
- Language: Shell
- Homepage:
- Size: 483 KB
- Stars: 2
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Granota
Alternative fuzzing engine for the [american-fuzzy-lop](http://lcamtuf.coredump.cx/afl/) (AFL) instrumentation system.
## Movitation
I started this project in 2013 to experiment some naive ideas in the early development days of the AFL fuzzer.
## Features
Remarkable features are:
* The fuzzing engine is based on genetic algorithms. The objective function depends on the coverage information provided by AFL`s instrumentation.
* Uses [crit-bit trees](http://cr.yp.to/critbit.html) to sort test cases. It allows different types of files to be fuzzed at once.
* Hooks I/O syscalls to fuzz daemons and standalone programs continuously without restarting them.
* Hooks memory comparison functions (e.g. strcmp) to potencially guest **magic headers** and defeact **checksums**.
* Week integration between the fuzzer and the fork server makes possible to target any child in the process tree.
* Child process forks late to bypass all the initialization overhead.
* Reads and writes fuzzed files direcly in shared memory (SHM) without touching the filesystem.
* Performs well even with large files (>100 KB).
* Generates unique crash logs based on the target's stack trace signature.
* Automatically classifies crash logs at runtime by severity using the [exploitable](https://github.com/jfoote/exploitable) library.
## Status
Some vulnerabilities were found in popular free software using this fuzzer. Bad news are that the genetic fuzzing engine offers limited coverage.
## Installation
Granota is built with autotools. Try typing:
```sh
./configure && make && sudo make install
```## Usage
Compile the target program with **granota-gcc** just as you would do with the original AFL.
Run granota binary. It requires a file to fuzz and the program's executable to test.
```
granota 0.27.afl built Mar 10 2016 20:28:12Usage: granota [OPTION]... EXE-PATH
Target Selection:
-f FILE path to target FILEDirectories:
-i DIR input DIR for test cases
-o DIR output DIR for test cases
-a DIR crash DIR for captured crashes
-e DIR temporary DIR (/dev/shm)Execution Control:
-t MSEC timeout for each input (1000 MSEC)
-m MB memory limit for children process (512 MB)
-q null-ify children's stdin, stdout, stderrFuzzing Options:
-l BYTES maximum size for each input file (1048576 BYTES)
-n FILES backlog of the input queue (4 FILES)
-s SECONDS stage duration (2 SECONDS)
```Finally launch the program's executable. Do not forget to inject the granota's helper library into the binary with **LD_PRELOAD**.
```sh
LD_PRELOAD=/usr/local/lib/libgranota.so /path/to/tested_binary ...
```The input directory with initial test cases is optional. If it not specified, the fuzzer starts with random inputs.
## Tutorial
The directory `tests/clamav` contains a framework to fuzz the [ClamAV](https://www.clamav.net) antivirus and the [zlib](http://www.zlib.net) and [bzip2](http://www.bzip.org) libraries. It illustates the use of the fuzzer on a relatively complex piece of software.
To run the test you will need an empty directory on your home directory called `$HOME/fuzz`. All files will be installed under that directory.
The build process is automated by the provided **Makefile**, so no further intervention should be necessary. Just go to the directory `tests/clamav` and run **make**.
The command line scanner `clamscan` is our target.
```sh
# Temporarily disable ASLR
sudo sysctl -w kernel.randomize_va_space=0# Allow ptrace processes
sudo sysctl -w kernel.yama.ptrace_scope=0# Disable piping core dumps
sudo sysctl -w kernel.core_pattern=core# Every 60 seconds clean up temporary files left by clamav (requires tmpwatch tool)
( while tmpwatch -cqa -X /tmp/foobar.exe 1m /tmp; do sleep 60; done ) &# Start the fuzzer
granota -i ~/fuzz/root/seeds -o ~/fuzz/root/testcases -a ~/fuzz/root/crashes -f ~/fuzz/root/foobar.exe ~/fuzz/root/bin/clamscan
```Switch to another terminal and run `clamscan`:
```
LD_PRELOAD=/usr/local/lib/libgranota.so \
~/fuzz/root/bin/clamscan --quiet -d ~/fuzz/root/test.ndb ~/fuzz/root/foobar.exe
```The fuzzing process will continue until you press Ctrl-C. There are three subdirectories created within the fuzz directory and updated in real time: seeds, testcases and crashes.
## Status Screen
```
_oo__ granota 0.27.afl up 0+08:34:18
_\- \__ Usage: 0m17.72s user, 0m28.43s sys, 990492 vctxsw
_\-)--)-,/_ Mem: 83864k used, 19309 pageftsSession: R (running), 106060 tpid, 36 evals/s
Crash: 0 exploitable, 0 probably, 1 probably-not
173 seen, 1 unknown, 0 error
Stage: # cycles evaluations nodes refines collns
=> 3 9063 748441 796 3888116 22306
2 1424 227602 365 323765 3081
1 0 0 0 0 0
0 1 52 32 7 0
Pivot: 254/1193 seq, 11 children, 0.0000465389 score (in 171.89 secs)
422 bytes, 1739/3376 critbit
0000: 504b 0304 1500 0200 0900 5914 fd38 fd3c PK........Y..8.<
0010: 07ef 1001 0000 2002 0000 0800 0000 636c ...... .......cl
0020: 616d 2e65 7865 bd51 314b 0331 187d 8987 am.exe.Q1K.1.}..
0030: 60ad 9a4d 7450 6f74 516b 7f80 7757 3399 `..MtPotQk..wW3.
```## Crashes
Hopefully after several minutes the fuzzer will find some crashes.
Here is an example of a crash log found in the current version of ClamAV (0.98.4) at the time of writing this.
**SourceAvNearNull.7zIn.c.1110.7e3eda3.1736ccb.log**
```
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
0x00007ffff4d10c39 in raise () from /usr/lib/libpthread.so.0Program received signal SIGSTOP, Stopped (signal).
0x00007ffff4d10c39 in raise () from /usr/lib/libpthread.so.0Program received signal SIGSEGV, Segmentation fault.
SzReadHeader2 (allocTemp=0x7ffff7bbfe30 , allocMain=0x7ffff7bbfe40 , lwtVector=0x7fffffff76e0, emptyFileVector=0x7fffffff76d8, emptyStreamVector=0x7fffffff76d0, digests=0x7fffffff76c8, digestsDefined=0x7fffffff76c0, unpackSizes=0x7fffffff76b8, sd=0x7fffffff7700, p=0x7fffffff7a80) at 7z/7zIn.c:1110
1110 file->Size = (*unpackSizes)[sizeIndex];
__main__:104: UserWarning: GDB v7.11 may not support required Python API
'exploitable' version 1.31 (granota)
Linux arch 4.4.1-2-ARCH #1 SMP PREEMPT Wed Feb 3 13:12:33 UTC 2016 x86_64
Signal si_signo: 11 Signal si_addr: 0x0
Nearby code:
Registers:
rax 0x0 0
rbx 0x7fffffff7a80 140737488321152
rcx 0x1 1
rdx 0x0 0
rsi 0x0 0
rdi 0x0 0
rbp 0x7ffff7bbfe30 0x7ffff7bbfe30
rsp 0x7fffffff7650 0x7fffffff7650
r8 0xffff7a7f 4294933119
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x7ffff7bbfe40 140737349680704
r13 0x7fffee3d8029 140737190395945
r14 0x1df631 1963569
r15 0x0 0
rip 0x7ffff532f727 0x7ffff532f727
eflags 0x10202 [ IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
Stack trace:
#0 SzReadHeader2 (allocTemp=0x7ffff7bbfe30 , allocMain=0x7ffff7bbfe40 , lwtVector=0x7fffffff76e0, emptyFileVector=0x7fffffff76d8, emptyStreamVector=0x7fffffff76d0, digests=0x7fffffff76c8, digestsDefined=0x7fffffff76c0, unpackSizes=0x7fffffff76b8, sd=0x7fffffff7700, p=0x7fffffff7a80) at 7z/7zIn.c:1110
#1 SzReadHeader (allocTemp=0x7ffff7bbfe30 , allocMain=0x7ffff7bbfe40 , sd=0x7fffffff7700, p=0x7fffffff7a80) at 7z/7zIn.c:1143
#2 SzArEx_Open2 (p=p@entry=0x7fffffff7a80, inStream=, allocMain=allocMain@entry=0x7ffff7bbfe40 , allocTemp=0x7ffff7bbfe30 ) at 7z/7zIn.c:1338
#3 0x00007ffff5332c19 in SzArEx_Open (p=0x7fffffff7a80, inStream=, allocMain=0x7ffff7bbfe40 , allocTemp=) at 7z/7zIn.c:1350
#4 0x00007ffff5321289 in cli_7unz (ctx=0x7fffffffc120, offset=) at 7z_iface.c:110
#5 0x00007ffff5073baa in magic_scandesc (ctx=ctx@entry=0x7fffffffc120, type=CL_TYPE_7Z, type@entry=CL_TYPE_ANY) at scanners.c:2725
#6 0x00007ffff506355b in cli_base_scandesc (type=CL_TYPE_ANY, ctx=0x7fffffffc120, desc=7) at scanners.c:3007
#7 cli_magic_scandesc (desc=desc@entry=7, ctx=ctx@entry=0x7fffffffc120) at scanners.c:3016
#8 0x00007ffff5079fdf in scan_common (context=, scanoptions=, engine=, scanned=, virname=0x7fffffffc418, map=0x0, desc=7) at scanners.c:3233
#9 cl_scandesc_callback (desc=7, virname=0x7fffffffc418, scanned=, engine=, scanoptions=, context=) at scanners.c:3252
#10 0x000000000041c1d4 in scanfile (filename=filename@entry=0x67ef40 "foobar.exe", engine=engine@entry=0x677d40, opts=opts@entry=0x673010, options=options@entry=4219447) at manager.c:303
#11 0x000000000042473d in scanmanager (opts=0x673010) at manager.c:1005
#12 0x0000000000402f72 in main (argc=, argv=0x7fffffffea38) at clamscan.c:164
#13 0x00007ffff497c610 in __libc_start_main () from /usr/lib/libc.so.6
#14 0x0000000000403c49 in _start ()
Title: SourceAvNearNull.7zIn.c.1110.7e3eda3.1736ccb
Description: Access violation near NULL on source operand
Short description: SourceAvNearNull (16/22)
Hash: 7e3eda35e167c5e06f14d897b82dc32f.1736ccb784c993920a7c90afbf417621
Exploitability Classification: PROBABLY_NOT_EXPLOITABLE
Explanation: The target crashed on an access violation at an address matching the source operand of the current instruction. This likely indicates a read access violation, which may mean the application crashed on a simple NULL dereference to data structure that has no immediate effect on control of the processor.
Other tags: AccessViolation (21/22)
```Please note that when you cannot reproduce a crash found by granota, the most likely cause is that you are not setting the same memory limit as used by the tool. Try:
```sh
LIMIT_MB=512
( ulimit -Sv $[LIMIT_MB << 10]; /path/to/tested_binary ... )
```## License
Licensed under the Apache License Version 2.0. See COPYING file.