手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ

摘要:

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即可。

图片[1]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

三、cmake安装

同样直接双击 cmake-3.18.0-rc3-win64-x64.msi 进行安装,然后一直next即可。

图片[2]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

四、DynamoRIO编译

在 C:\ 盘下新建 my_winafl_fuzz 文件夹,并把下载好的DynamoRIO 源码(dynamorio-release_7.1.0.zip)解压并放入到my_winafl_fuzz目录下。

图片[3]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

找到vcvarsall.bat ,并使用vcvarsall.bat来设置命令行的编译环境。下面是我的vcvarsall.bat所在目录。

图片[4]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

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版本

图片[5]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科图片[6]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

解决 “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环境变量即可。

图片[7]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科图片[8]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

然后重新启动cmd,重复上述命令即可:

图片[9]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

经过上面的步骤,我们就完成了DynameRIO x32的编译,在build32\bin32目录下可以看到drrun.exe程序。

图片[10]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

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】目录下可以找到。

图片[11]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

 双击上面的”Visual Studio Tools”目录后,会看到下列内容:

图片[12]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

这里对于新手来说,这里有个坑。但是我们先操作正确的步骤,然后演示遇到的坑。由于我们的系统是windos_x64的,所以必须选 “VS2013 x64 兼容工具命令提示”,双击”VS2013 x64 兼容工具命令提示”会弹出一个cmd。

图片[13]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科图片[14]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

经过上面步骤x64就编译完成了。可以看到”build64\bin64″目录下已经有了”drrun.exe”等文件。

图片[15]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

通过上面步骤我们就完成了DynamoRIO的x32和x64的编译了。

现在我们来说说,新手可能会遇到的坑。我们先把”dynamorio-release_7.1.0″目录下的”build64″文件全部删除掉。双击”VS2013 x64 本机工具命令提示”,然后运行下面命令:

图片[16]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

最后会报下列错误:

图片[17]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

还有一种就是用最原始的来切换编译环境:

图片[18]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

 它也会出现下列错误:

图片[19]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

为了避免这个错误,必须遵守”vcvarsall.bat” 用于生成命令行编译环境的规则,规则在开头我已经说的很清楚了,”Visual Studio命令提示工具”其实和”vcvarsall.bat”是一样的。所以不要因马虎而犯错了。

五、winafl编译

进入C:\my_winafl_fuzz目录,通过下列命令下载winafl代码:

git clone–recursive

https://github.com/googleprojectzero/winafl

图片[20]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

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

图片[21]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

进入winafl\b32\bin\Release下面就是我们编译好的winafl_x32:

图片[22]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

下面演示可能出现的问题,有一些人在下载winafl代码的时候,可能习惯性的会直接这样操作:

git clone

https://github.com/googleprojectzero/winafl

图片[23]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

编译时候就会出现这样的错误,这是由于winalf源代码没有下载完整,缺少依赖文件,在winafl\third_party\processor-trace目录下是空的。

图片[24]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

解决的办法: 

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

图片[25]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

 编译完成后:

图片[26]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

六、测试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” 参数说明:

图片[27]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

// 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); (可以有多个)

图片[28]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

可以看到我写的是-target_offset 0x10D0 ,而官网写的是-target_offset 0x16e0,这里是因为我的系统是win7_x64环境,所以编译出来的程序的地址就会有所不同;不管怎么说,还是以IDA给出的偏移而定。

图片[29]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

如果偏移不对,winafl运行时,有时就会出现下列情况:

图片[30]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

通过上面的测试,说明我们自己编译的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 # 每一次样本执行的超时时间
-- # 分割符
****************************
第一个"--"分割符:后面跟的是插桩的参数
第二个"--"分割符:后面跟的是目标程序的参数
****************************

图片[31]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

winafl正常运行:

图片[32]-手把手教你 | 漏洞挖掘系列之WinAFL从安装到使用 – 作者:极光无限SZ-安全小百科

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

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论