winafl

WINAFL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
afl-fuzz
afl-fuzz [afl options] -- [instrumentation options] -- target_cmd_line
其中[afl options]常用的参数包括(这些参数由afl-fuzz.exe处理):
-i    input directory with test cases
-o  output directory for fuzzer findings
-D  directory with DynamoRIO binaries (drrun, drconfig)
-t   timeout for each run
-f   location read by the fuzzed program (stdin)
-x   optional fuzzer dictionary (see README) 字典文件
[instrumentation options]常用的参数包括:
-coverage_module – fuzzing对象程序会调用到的模块,设置要记录的模块,支持多个模块的记录
-target_module – fuzzing对象模块,也就是-target_offset所在的模块
-target_offset – fuzzing的偏移地址,也就是会被instrumentation的偏移
-target_method       – 只有有符号表的情况下才能用的方法,根据符号名去设置偏移
-fuzz_iterations – 再fuzzing对象程序重新启动一次内运行目标函数的最大迭代数
-debug – debug模式
target_cmd_line参数就是你要fuzzing对象的启动程序。


Winafl是一个开源的优秀半自动化fuzz测试工具,相比较其他的公开fuzz测试工具还是有很大的优势的
daɪnəməʊ RIO
DynamoRIO应该算是winafl的核心部分,它主要实现的是指令动态插桩,其实就是之前我提到的指令扩展,对函数输入输出进行一定的检查。关于DynamoRIO的原理以及介绍在网上有很多描述,这里不做过多介绍了。
 
用DynamoRIO测试过程
这里我们要用到的是DynamoRIO的ddrun.exe工具,
afl-fuzz.exe通过-i参数指向的目录读取用户提供的测试文件,并通过各种变形存储到out/.cur_input文件,供被fuzzing的应用程序调用打开,查看afl_fuzz.c可以发现其对测试用例都做过哪些变形。

-i   测试用例存放目录, 测试样本的输入目录
-o  fuzzing过程和fuzz结果的输出目录
-D  DynamoRIO所处的目录
-t   每次的运行时间
-f   被fuzz的进程要读取的文件
-x  可选fuzzer目录

使用说明
首先找出要fuzz的函数基于模块的地址偏移
要保证程序可以正常的跑在DynamoRIO下面,可以通过WinAFL的独立调试模式来测试这一点。独立调试模式不会使用fuzz部分(使用-debug选项)
要想正常运行,必须要保证afl-fuzz.exe和winafl.dll在同一目录下
afl-fuzz [afl options] -- [instrumentation options] -- target_cmd_line

-D选项是必须启用的,用于指定DynamoRIO所处的目录
-t 选项也是必须启用的,由于不同的选项导致的执行效率不同。所以-t的时间应该灵活设置。
默认是支持多线程的程序记录的。如果是单线程程序可以使用-covtype edge选项
instrumentation options
-covtype                  设置记录方式,为多线程和单线程程序所使用。bb/edge
-coverage_module  设置要记录的模块,支持多个模块的记录
-target_module       fuzz目标函数所处的模块,必须要设置-target_method或-target_offset
-target_method       只有有符号表的情况下才能用的方法,根据符号名去搞
-target_offset          要fuzz函数的相对模块头的偏移
-fuzz_iterations       目标函数的最大迭代次数
-nargs                     被fuzz的函数有几个参数?
-debug                   不会连接fuzzer部分,只会输出一个日志文件。包含加载的模块、打开的文件和输出报告。
-logdir                     只在-debug下可用,输出的log文件的位置
coverage_module可以有多个,target_module只有一个

.\afl-fuzz.exe -i in -o out -t 200000000+ -D .\ -- -coverage_module gdiplus.dll -fuzz_iterations 5000 -target_module test_gdiplus.exe -target_method main -nargs 2 -- test_gdiplus.exe not_kitty.bmp @@
其中 “@@” 表示待 fuzzing 的测试用例文件在 in 目录下
drrun.exe -pidfile childpid_38a0fc9cc4272ad6.txt -no_follow_children -c winafl.dll -coverage_module gdiplus.dll -coverage_module WindowsCodecs.dll -fuzz_iterations 5000 -target_module test_gdiplus.exe -target_method main -nargs 2 -fuzzer_id 38a0fc9cc4272ad6 -- test_gdiplus.exe out\.cur_input