This is a custom version of afl-fuzz.
Now, only support x86_64.
- Comment method
The original fuzzer is only targeting javascript. So, we can extract keywords using comment.
For example, If we test this one,
function abc() { print(1); }
then, comment method will check exammples like this.
/**/f/*unction abc() { print(1); }*/
/**/fu/*nction abc() { print(1); }*/
/**/fun/*ction abc() { print(1); }*/
At this point, the program flow will be changed.
/**/function/* abc() { print(1); }*/
now, it saves 'function' as dictionary.
- Threshold model
If the program is using thread, then execution path will be changed.
So, we ignore small change in execution path which can be caused by thread.
But, disadvantage of this model is that we cannot detect real small flow changes.
We can only detect huge flow changes.
- Speed improvement using ptrace
The idea is come from Michal Zalewski's todo list.
If we can make fork server after skipping the initialization process, speed of fuzzer will be improved.
I tried this idea using ptrace.
First, find the first read or open point, which reads our input. After remembering the latest point before reading, restart application, and then make forkserver at the found point.
This method works pretty well in JavaScriptCore. Performance increases 2.5x
But in case of v8, it is not stable. I'm finding what the problem is.
It is almost same with original AFL.
Download afl-fuzz-js
$ git clone https://github.com/tunz/afl-fuzz-js.git
$ cd afl-fuzz-js
$ make
you can configure through the config.h file before compile the afl-fuzz-js.
Download Webkit
$ cd ~
$ svn checkout https://svn.webkit.org/repository/webkit/trunk webkit
$ cd webkit
Build with afl-fuzz-js
$ export AFL_HARDEN=1
$ export AFL_INST_RATIO=30
$ export CC=/path/to/afl-gcc
$ export CXX=/path/to/afl-g++
$ ./Toos/Scripts/build-jsc --gtk --makeargs="-j4"
You can remove gtk option, or change makeargs arguments. You can also compile with address santinizer. I think it would be very efficient, but I didn't tried yet. The value of AFL_HARDEN , AFL_INST_RATIO, CC, or CXX also can be changed by you. It depends on your choice and situation.
Fuzz with afl-fuzz-js
$ cd ~
$ mkdir fuzz
$ cd fuzz
$ cp ~/webkit/WebKitBuild/Release/bin/jsc ./jsc
$ /path/to/afl-fuzz -i [input directory] -o [output directory] -x [dictionary directory] -m 8G ./jsc @@
-m option also depends on your situation. You can parallelize it using -M and -S option. If you add more samples to input directory, it would be more efficient.
(If there is error that can't find start position, or there is crash)
Sometimes, there would be some problem (e.g. v8). Temporarily, use user defined start address.
Add
asm(".string \"[start]\"");
to what you want to start from. it specify the start position by user, not automatically.
Add -U option when you start afl-fuzz.
$ /path/to/afl-fuzz -i [input directory] -o [output directory] -x [dictionary directory] -m 8G -U ./jsc @@
Then, It will start from that line.