电脑疯子技术论坛|电脑极客社区

微信扫一扫 分享朋友圈

已有 1313 人浏览分享

WinAFL模糊测试之代码覆盖率学习

[复制链接]
1313 0
本帖最后由 zhaorong 于 2021-9-11 16:42 编辑

DynamoRIO 是一个动态的动态插桩/翻译平台。
DynamoRIO 用于对程序进行动态分析 优化和翻译。DynamoRIO 可以运行在 Windows
和 Linux 操作系统上。并且支持 IA-32 和 AMD64 平台。

著名的模糊测试神器WinAFL使用DynamoRIO进行动态插桩。大家在使用WinAFL进行模糊测试时
通常使用DynamoRIO中提供的工具Dr.run来查看代码覆盖率。

一、实验环境
  1. Windows 7 X64
  2. WinAFL 1.16
  3. DynamoRIO-Windows-6.2.0-2
  4. IDA Pro 6.8(Lighthouse插件v0.6)
  5. Visual C++6.0
复制代码

注意:关闭360等杀毒软件 部分杀毒软件会误报。

2、验证模糊测试时的偏移量偏移

为了测试dr.run,写随测试代码 编译环境为Visual C++6.0。
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>

  4. #define PASSWORD "1234567" // 默认密码
  5. int g_execute_count = 0; // 变量,是为了记录执行次数

  6. int verify_password (char *password)
  7. {
  8.     printf("输入密码 = %s\n", 密码); // 用于调试
  9.     int 认证;
  10.     字符缓冲区[8];
  11.     认证=strcmp(密码,密码);
  12.     strcpy(缓冲区,密码);//这里溢出了!
  13.     返回已验证;
  14. }

  15. int main(int argc, char* argv[])
  16. {
  17.     printf("g_execute_count = %d\n", g_execute_count);
  18.     g_execute_count = g_execute_count + 1;
  19.     int valid_flag=0;
  20.     字符密码[1024];
  21.     文件 * fp;
  22.    
  23.     如果(argc!= 2)
  24.     {
  25.         printf("用法:%s input_file\n", argv[0]);
  26.         返回 1;
  27.     }
  28.     // argv[1]为文件名
  29.     if(!(fp=fopen(argv[1],"rw+")))
  30.     {
  31.         printf("打开 %s 失败!\n\n", argv[1]);
  32.         退出(0);
  33.     }
  34.     fscanf(fp,"%s",password);
  35.     valid_flag = verify_password(密码);
  36.     如果(有效标志)
  37.     {
  38.         printf("密码错误!\n\n");
  39.     }
  40.     别的
  41.     {
  42.         printf("恭喜!您已通过验证!\n\n");
  43.     }
  44.     fclose(fp);
  45.     返回0;
  46. }
复制代码

然后将上述代码编译为推出模式32位的可执行文件readFile.exe。
在本机实验环境中
  1. WinAFL 路径:D:\winAFL\;DynamoRIO 的路径:D:\DynamoRIO-Windows-6.2.0-2\。
复制代码

步骤如下:
首先将编译出的readFile.exe文件和要读取的文件input.txt,复制到D:\winAFL\bin32\下
input.txt中可以输入字符串ABCDEF。
使用IDA Pro查看readFile.exe函数的地址 如图1所示 可以看到main函数地址为0x00401080。

QQ截图20210911163035.png

图1主要函数地址

使用IDA Pro查看基址 可以打开基础菜单Edit->Seg->Rebase程序 如图2所示。可见地址为0x400000
则主函数偏移量偏移= 0x00401080 - 0x400000 = 0x1080。

QQ截图20210911163133.png

图2 查看基址

然后构造如下所示命令行 其中target_offset为偏移量 fuzz_iterations为执行次数。
  1. [b]注意:[/b] target_offset为文件中的偏移量。因为readFile.exe为32位程序 所以使用bin32文
  2. 件夹下的drrun.exe,而不是bin64文件夹下的drrun.exe。
复制代码
  1. D:\DynamoRIO-Windows-6.2.0-2\bin32\drrun.exe -c winafl.dll -debug -target_module readFil
  2. e.exe -target_offset 0x1080 -fuzz_iterations 5 -nargs 2 -- readFile.exe input.txt
复制代码

然后切换到D:\winAFL\bin32\目录下。执行上述命令 执行结果如图3所示。
(因为g_execute_count为单位变量,可以记录执行次数)可以看出我们设置的偏移量0x1080是正确的。

QQ截图20210911163505.png

图3 drrun执行截图

D:\winAFL\bin32目录下生成afl.readFile.exe.01016.0000.proc.log之类的日志文件。日志文件如下所示。
  1. 模块加载,readFile.exe
  2. 模块加载,drx.dll
  3. 模块加载,drreg.dll
  4. 模块加载,drwrap.dll
  5. 模块加载,winafl.dll
  6. 模块加载,drmgr.dll
  7. 模块加载,dynamorio.dll
  8. 模块加载,KERNELBASE.dll
  9. 模块加载,KERNEL32.dll中
  10. 模块加载,NTDLL.DLL
  11. 在pre_fuzz_handler
  12. 在OpenFileA,读input.txt中
  13. 在OpenFileW,读input.txt中
  14. 在post_fuzz_handler
  15. 在pre_fuzz_handler
  16. 在OpenFileA,读input.txt中
  17. 在OpenFileW,读input.txt中
  18. 在post_fuzz_handler
  19. 在pre_fuzz_handler
  20. 在OpenFileA ,
  21. 在 OpenFileW 中读取 input.txt ,
  22. 在 post_fuzz_handler 中读取 input.txt
  23. 在 pre_fuzz_handler
  24. 在 OpenFileA 中,读取 input.txt
  25. 在 OpenFileW 中,
  26. 在 post_fuzz_handler 中读取 input.txt在 pre_fuzz_handler

  27. OpenFileA 中,读取 input.txt
  28. 在 OpenFileW 中,读取 input.txt
  29. 在 post_fuzz_handler 中的
  30. 一切似乎都在正常运行。
  31. 覆盖图如下:
  32. ...
复制代码

可以看到很多行开始都是模块加载 也就是说参数coverage_module和target_module指定
的模块必须出现在这里。

如果-target_offset设置不正确 查看日志文件中 警告提示如下。
  1. ...
  2. 在 OpenFileA 中,读取 input.txt
  3. 在 OpenFileW 中,读取 input.txt
  4. 警告:从未调用过目标函数。target_offset 不正确?
  5. 覆盖图如下:
  6. ...
复制代码

3、生成代码覆盖文件

切换到 D:\DynamoRIO-Windows-6.2.0-2\bin32目录下 执行如下命令。
  1. D:\DynamoRIO-Windows-6.2.0-2\bin32>drrun.exe -t drcov -- ..\..\winafl\bin
  2. 32\readFile.exe ..\..\winafl\bin32\input.txt
复制代码

QQ截图20210911163750.png

图4 drrun执行截图

在D:\DynamoRIO-Windows-6.2.0-2\bin32目录下 生成drcov.readFile.exe.12800.0000.proc.log类似文件。
使用IDA Pro加载上述代码生成的readFile.exe文件IDA Pro已经安装Lighthouse插件v0.6 待文件加载完成后。
打开IDA Pro菜单File -> Load File -> Code coverage file...加载drcov.readFile.exe.12800.0000.proc.log
文件如图5所示。 Lighthouse 插件将不同覆盖率的函数变化不同。

QQ截图20210911163854.png

图5函数视角的代码覆盖率

题6所示 可以看到某个函数中的基本块是否能覆盖到。

QQ截图20210911163941.png

图6某个函数的基本块覆盖

在模糊测试中 如果要测试的函数覆盖率 则可进行数据下一步操作。既专业输入集。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

关注

0

粉丝

9021

主题
精彩推荐
热门资讯
网友晒图
图文推荐

Powered by Pcgho! X3.4

© 2008-2022 Pcgho Inc.