摘要:
afl-fuzz从2013年发布到现在,发现了很多真实的漏洞;在afl-fuzz的强劲优势效应下,2016年,windows下的afl-fuzz改版孕育而生——winafl。作为一个文件格式半自动漏洞挖掘工具,winafl可以帮助我们发现各种使用特定格式文件的应用软件漏洞,如文件编辑软件(doc、xls、pdf等)、图片查看软件(bmp、jpg、png等)、视频播放软件(avi、mp4、mpg等)。早期的winafl结合了DynamoRIO进行动态插桩,并实现了对windows下的闭源软件无情的fuzzing。后期很多人对winafl引入的DynamoRIO进行改良升级,或者直接替换插桩组件来达到最优的效果;也有的是对遗传算法的大改或直接替换,当然了这些都是后话。
当下我们的首要步骤是学会编译winafl并熟悉使用它,为后续的动态调试、分析、修改winafl做准备,当然不论是拿来做研究或挖洞,都是必须要会编译安装它的,所以我们编写了这篇文章。
我们将在文中为大家精要详解如何一步一步安装winafl;并对DynamoRIO编译和winafl编译进行步骤演示,分析常见错误示例并提出解决方法;以及测试编译是否能够正常运行。
全文内容包括:
1. 实验环境
2. git安装
3. cmake安装
4. DynamoRIO编译
- 编译DynamoRIO的x32版本
- 编译DynamoRIO的x64版本
5. winafl编译
- 编译winafl的x32版本
- 编译winafl的x64版本
6. 测试DynamoRIO和winafl
- DynamoRIO是否编译后可用
- winafl是否编译后可用
7. 总结
一、实验环境
工具 |
版本 |
链接 |
windows 7 pro |
en_windows_7_professional_with_sp1_x64_dvd_621750.iso |
|
Visual Studio |
VS2013_RTM_PRO_CHS.iso |
|
git |
Git-2.27.0-64-bit.exe |
https://gitscm.com/download/win |
cmake |
cmake-3.18.0-rc3-win32-x86.msi |
https://cmake.org/files/v3.18/ |
dynamorio |
dynamorio-release_7.1.0.zip (我们下载的是源码 Source code) |
https://github.com/DynamoRIO/dynamorio/releases/tag/release_7.1.0 |
winafl |
https://github.com/ivanfratric/winafl |
|
VMware |
VMware-workstation-full-15.1.0-13591040.exe |
|
ida |
IDA Pro 6.8 |
下文所有的操作都是在VMware里完成的,所以在 windows 7 pro中安装vs2013的步骤可以在网上查的到。
二、git安装
直接双击 Git-2.27.0-64-bit.exe 进行安装,然后一直next即可。
三、cmake安装
同样直接双击 cmake-3.18.0-rc3-win64-x64.msi 进行安装,然后一直next即可。
四、DynamoRIO编译
在 C:\ 盘下新建 my_winafl_fuzz 文件夹,并把下载好的DynamoRIO 源码(dynamorio-release_7.1.0.zip)解压并放入到my_winafl_fuzz目录下。
找到vcvarsall.bat ,并使用vcvarsall.bat来设置命令行的编译环境。下面是我的vcvarsall.bat所在目录。
vcvarsall.bat,用于生成命令行编译环境。 如果要在32位系统下生成32位代码,就执行vcvarsall x86 如果要在32位系统下生成64位代码,就执行vcvarsall x86_amd64 如果要在64位系统下生成32位代码,就执行vcvarsall x86 如果要在64位系统下生成64位代码,就执行vcvarsall amd64_x86 如果要在32位的arm平台的代码,就执行 vcvarsall x86_arm 如果要在64位的arm平台的代码,就执行 vcvarsall amd64_arm
1. 编译 DynamoRIO 的 x32 版本
在C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC目录下,右键cmd出来,然后执行下列命令。
Studio 12.0\VC>vcvarsall x86
Studio 12.0\VC>cd C:\my_winafl_fuzz\dynamorio-release_7.1.0
dynamorio-release_7.1.0>mkdir build32 && cd build32
dynamorio-release_7.1.0\build32>cmake -G"Visual Studio 12 2013" -A Win32 ..
*******************
cmake -G"Visual Studio 12 2013" -A Win32 .. //这里的两个.点表示上层目录
也可以用下列命令,这两条命令是等价的
cmake -G"Visual Studio 12 2013" .. // x32
如果要编译x64的话,就加
cmake -G"Visual Studio 12 2013 Win64" .. // x64
*******************
cmake --build . --config RelWithDebInfo //RelWithDebInfo 表示包含调试信息的release版本
解决 “Could NOT find Perl (missing: PERL_EXECUTABLE)” 的办法是,安装一个perl,并把perl的安装路径添加到PAHT环境变量里。由于我们安装了”Git-2.27.0-64-bit.exe”,而”C:\Program Files\Git\usr\bin”目录下刚好有perl.exe,以我们把 “C:\Program Files\Git\usr\bin” 添加到 PAHT环境变量即可。
然后重新启动cmd,重复上述命令即可:
经过上面的步骤,我们就完成了DynameRIO x32的编译,在build32\bin32目录下可以看到drrun.exe程序。
2. 编译DynamoRIO的x64版本
编译x64版本的步骤基本和上面一样。
Studio 12.0\VC>vcvarsall amd64_x86 // 切换64位编译环境
Studio 12.0\VC>cd C:\my_winafl_fuzz\dynamorio-release_7.1.0 // 进入dynamorio源码目录
dynamorio-release_7.1.0>mkdir build64 && cd build64 // 创建文件并进入
dynamorio-release_7.1.0\build32>cmake -G"Visual Studio 12 2013" -A x64 ..
#cmake -G"Visual Studio 12 2013 Win64" ..
dynamorio-release_7.1.0\build32>cmake --build . --config RelWithDebInfo
这里我通过另一种方式编译DynamoRIO — > 即:”Visual Studio命令提示工具”;该工具在【开始->所有程序->Visual Stdio 2013 -> Visual Studio Tools】目录下可以找到。
双击上面的”Visual Studio Tools”目录后,会看到下列内容:
这里对于新手来说,这里有个坑。但是我们先操作正确的步骤,然后演示遇到的坑。由于我们的系统是windos_x64的,所以必须选 “VS2013 x64 兼容工具命令提示”,双击”VS2013 x64 兼容工具命令提示”会弹出一个cmd。
经过上面步骤x64就编译完成了。可以看到”build64\bin64″目录下已经有了”drrun.exe”等文件。
通过上面步骤我们就完成了DynamoRIO的x32和x64的编译了。
现在我们来说说,新手可能会遇到的坑。我们先把”dynamorio-release_7.1.0″目录下的”build64″文件全部删除掉。双击”VS2013 x64 本机工具命令提示”,然后运行下面命令:
最后会报下列错误:
还有一种就是用最原始的来切换编译环境:
它也会出现下列错误:
为了避免这个错误,必须遵守”vcvarsall.bat” 用于生成命令行编译环境的规则,规则在开头我已经说的很清楚了,”Visual Studio命令提示工具”其实和”vcvarsall.bat”是一样的。所以不要因马虎而犯错了。
五、winafl编译
进入C:\my_winafl_fuzz目录,通过下列命令下载winafl代码:
git clone–recursive
https://github.com/googleprojectzero/winafl
1. 编译winafl 的 x32 版本
// 1. 切换 x86 编译环境
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC>vcvarsall.bat x86
// 2. 进行winafl源码的下载目录
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC>cd C:\my_winafl_fuzz\winafl
// 3. 创建目录,用于保存winafl编译好的二进制等文件
C:\my_winafl_fuzz\winafl>md b32 && cd b32
// 4. 进行配置,DDynamoRIO_DIR 填写我们编译好的build32\cmake的绝对路径
C:\my_winafl_fuzz\winafl\b32>cmake -G"Visual Studio 12 2013" -A Win32 .. -DDynamoRIO_DIR=C:\my_winafl_fuzz\dynamorio-release_7.1.0\build32\cmake
// 5. 编译生成
C:\my_winafl_fuzz\winafl\b32>cmake --build . --config Release
配置winafl时,cmake的参数说明:
cmake 参数说明:
-G"Visual Studio 12 2013" // 使用什么版本的 Visual Studio 进行编译源码
-A Win32 // 编译什么架构的版本,也可以用下列标准的形式
************************************************************************
C:\my_winafl_fuzz\winafl\b64>cmake -G"Visual Studio 2013"
CMake Error: Could not create named generator Visual Studio 2013
Generators
Visual Studio 16 2019 = Generates Visual Studio 2019 project files.
Use -A option to specify architecture.
Visual Studio 15 2017 [arch] = Generates Visual Studio 2017 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 14 2015 [arch] = Generates Visual Studio 2015 project files.
Optional [arch] can be "Win64" or "ARM".
* Visual Studio 12 2013 [arch] = Generates Visual Studio 2013 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 11 2012 [arch] = Generates Visual Studio 2012 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 10 2010 [arch] = Generates Visual Studio 2010 project files.
Optional [arch] can be "Win64" or "IA64".
Visual Studio 9 2008 [arch] = Generates Visual Studio 2008 project files.
Optional [arch] can be "Win64" or "IA64".
****************************************************************************
-DDynamoRIO_DIR=..\path\to\DynamoRIO\cmake // 生成 DynamoRIO 客户端: winafl.dll
-DINTELPT=1 // 启用 Intel PT 模式.
参考: https://github.com/googleprojectzero/winafl/blob/master/readme_pt.md
-DUSE_COLOR=1 // 颜色支持, 只对 Windows 10周年纪念版或更高版本有效
-DUSE_DRSYSMS=1 // 开启 Drsyms 模式,但在 Windows 10 v1809 下加该参数会出错.
参考:https://github.com/googleprojectzero/winafl/issues/145
进入winafl\b32\bin\Release下面就是我们编译好的winafl_x32:
下面演示可能出现的问题,有一些人在下载winafl代码的时候,可能习惯性的会直接这样操作:
git clone
https://github.com/googleprojectzero/winafl
编译时候就会出现这样的错误,这是由于winalf源代码没有下载完整,缺少依赖文件,在winafl\third_party\processor-trace目录下是空的。
解决的办法:
https://github.com/googleprojectzero/winafl/issues/184
方法一: git clone https://github.com/googleprojectzero/winafl cd winafl git submodule update --init --recursive //即可将子模块内容下载下来后工程才不会缺少相应的文件 方法二: //加上 --recursive 参数。它会自动初始化并下载每一个子模块,包括第三方的库文件 git clone --recursive https://github.com/googleprojectzero/winafl
2.winafl的 x64 版本
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC>vcvarsall.bat amd64_x86
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC>cd C:\my_winafl_fuzz\winafl
C:\my_winafl_fuzz\winafl>md b64 && cd b64
C:\my_winafl_fuzz\winafl\b64>cmake -G"Visual Studio 12 2013" -A x64 .. -DDynamoRIO_DIR=C:\my_winafl_fuzz\dynamorio-release_7.1.0\build64\cmake
// cmake -G"Visual Studio 12 2013 Win64" .. -DDynamoRIO_DIR=C:\my_winafl_fuzz\dynamorio-release_7.1.0\build64\cmake
C:\my_winafl_fuzz\winafl\b64>cmake --build . --config Release
编译完成后:
六、测试DynamoRIO 和 winafl
官方的使用文档,主要是DynamoRIO插桩参数和winafl运行参数的说明:
https://github.com/googleprojectzero/winafl/blob/master/readme_dr.md
1. DynamoRIO是否编译后可用
winafl动态插桩是调用DynamoRIO下的 “drrun.exe” 进行的。我们可以简单使用”drrun.exe”来获取目标程序执行过程中所加载的模块,从而推断DynamoRIO编译是成功并可用的,这也是官方教程里的做法。
任意找一个bmp格式的图片放到上面我们编译后的winafl\b32\bin\Release目录下。然后运行下面命令:
C:\my_winafl_fuzz\dynamorio-release_7.1.0\build32\bin32\drrun.exe -c winafl.dll -debug -target_module test_gdiplus.exe -target_method main -fuzz_iterations 10 -nargs 2 -- test_gdiplus.exe input.bmp
显示报错了,官方的说法是这样的,-target_method main 这里有找到,是由于没有目标程序的调试符号文件。所以解决的办法,就是用 target_offset 替换掉 target_method,或者编译的使用生成调试符号:
https://github.com/googleprojectzero/winafl/issues/199
// target_offset 替换掉 target_method 后的命令
C:\my_winafl_fuzz\dynamorio-release_7.1.0\build32\bin32\drrun.exe -c winafl.dll -debug -target_module test_gdiplus.exe -target_offset 0x10D0 -fuzz_iterations 10 -nargs 2 -- test_gdiplus.exe input.bmp
对 “drrun.exe” 参数说明:
// 1. 后面跟 <客户端> <客户端 参数> --(分割线) <目标程序 和 目标程序参数>
-c <client> [client options] -- <app and args to run>
// 2.1 winafl.dll 参数说明。这也是插桩参数的使用[instrumentation options]
-debug # debug模式, 它会生成一个log文件
-target_module # 目标程序(只能有一个), 也是target_offset所在的模块
-target_offset # 目标程序偏移,相对于target_module的偏移,在method无法导出的时候使用
-fuzz_iterations # 目标程序重新启动一次内运行目标函数(即target_method)的最大迭代数
-nargs # 目标程序执行所需要的参数个数(包括目标程序本身)
-target_module # 目标函数,需要export或者调试符号(pdb)
-coverage_module # 计算覆盖率的模块,也就是目标程序会调用的模块(dll); (可以有多个)
可以看到我写的是-target_offset 0x10D0 ,而官网写的是-target_offset 0x16e0,这里是因为我的系统是win7_x64环境,所以编译出来的程序的地址就会有所不同;不管怎么说,还是以IDA给出的偏移而定。
如果偏移不对,winafl运行时,有时就会出现下列情况:
通过上面的测试,说明我们自己编译的DynamoRIO是没问题的。
2.winafl是否编译后可用
在winafl\b32\bin\Release目录下,分别新建 in、out 文件夹;然后把bmp格式图片放到 in 文件夹下。然后运行下面命令。
afl-fuzz.exe -i in -o out -D C:\my_winafl_fuzz\dynamorio-release_7.1.0\build32\bin32 -t 20000 -- -coverage_module gdiplus.dll -coverage_module WindowsCodecs.dll -fuzz_iterations 5000 -target_module test_gdiplus.exe -target_offset 0x10D0 -nargs 2 -- test_gdiplus.exe @@
这里说明下winafl的参数:
-i # 存放样本的目录
-o # 保存输出数据,包括 crash文件、测试用例等
-D # DynamoRIO的路径 (drrun, drconfig)
-t msec # 每一次样本执行的超时时间
-- # 分割符
****************************
第一个"--"分割符:后面跟的是插桩的参数
第二个"--"分割符:后面跟的是目标程序的参数
****************************
winafl正常运行:
x64测试:
// 1. drrun.exe 测试
C:\my_winafl_fuzz\dynamorio-release_7.1.0\build64\bin64\drrun.exe -c winafl.dll -debug -target_module test_gdiplus.exe -target_offset 0x1110 -fuzz_iterations 10 -nargs 2 -- test_gdiplus.exe input.bmp
// 2. winafl 测试
afl-fuzz.exe -i in -o out -D C:\my_winafl_fuzz\dynamorio-release_7.1.0\build64\bin64 -t 20000 -- -coverage_module gdiplus.dll -coverage_module WindowsCodecs.dll -fuzz_iterations 5000 -target_module test_gdiplus.exe -target_offset 0x1110 -nargs 2 -- test_gdiplus.exe @@
七、总结
按上文的步骤操作,我们就完成了winafl的整个编译。当然了,也可以直接使用官网编译好的,如果大家是在win10下编译的,就需要注意cmake、DynamoRIO的版本问题了,会出现编译不过、兼容性等问题,这些github上都有解决的办法。
再来说说我对winafl的看法,winafl给我的感觉整体上是有好有坏的,它设计的思维肯定是新颖的,但有一点局限性,体现在如果fuzzing的目标程序,没有函数导出表(dll)、不接受命令行参数、源代码也没有、环境变量也不调用的话,就很难fuzzing。解决的办法就只有hook和逆向,只是相对来说比较麻烦一点而已,但是在半自动化fuzz测试工具则已经很优秀了。由于篇幅有限,遗传算法、bitmap算法、插桩机制、管道通信fuzzing模型在这里都没有涉及,这也是afl-fuzz在设计时,最新颖的四大模型。后续我将进行更多的详细解说,大家敬请期待吧~~
来源:freebuf.com 2020-08-05 17:44:33 by: 极光无限SZ
请登录后发表评论
注册