本文为看雪论坛优秀文章
看雪论坛作者ID:昵称好麻烦
一、漏洞挖掘目标
二、目标模块与接口
三、部署winafl环境
四、编写fuzz主程序并编译
#include <stdio.h>
#include <Windows.h>
#define ASSISTANTTOOLS_DLL "AssistantTools.dll"
extern "C" __declspec(dllexport) VOID fuzz_method(CHAR * filePath);
// AssistantTools.dll
static HMODULE hAssistantTools = NULL;
// AssistantTools!XL_ParseTorrentFileW
signed int __cdecl XL_ParseTorrentFileW(CHAR* aFileName, PVOID* a1);
using Fun_XL_ParseTorrentFileW = decltype(&XL_ParseTorrentFileW);
static Fun_XL_ParseTorrentFileW fun_XL_ParseTorrentFileW = NULL;
// AssistantTools!XL_ReleaseTorrentFileInfoW
void __cdecl XL_ReleaseTorrentFileInfoW(PVOID a1);
using Fun_XL_ReleaseTorrentFileInfoW = decltype(&XL_ReleaseTorrentFileInfoW);
static Fun_XL_ReleaseTorrentFileInfoW fun_XL_ReleaseTorrentFileInfoW = NULL;
VOID fuzz_method(CHAR* filePath)
{
PVOID a1 = NULL;
fun_XL_ParseTorrentFileW(filePath, &a1);
if (a1)
{
fun_XL_ReleaseTorrentFileInfoW(a1);
}
return;
}
int main(int argc, char* argv[])
{
CHAR assistantTools_path[MAX_PATH] = {0};
CHAR* pTemp = NULL;
if (2 != argc)
{
printf("Parameter Error\n");
goto End;
}
// 获取AssistantTools.dll的全路径
if(0 == GetModuleFileNameA(NULL, assistantTools_path, sizeof(assistantTools_path)))
{
printf("GetModuleFileNameA Error\n");
goto End;
}
pTemp = strrchr(assistantTools_path, '\\');
if(NULL == pTemp)
{
printf("strrchr Error\n");
goto End;
}
++pTemp;
*pTemp = '\0';
strcat(pTemp, ASSISTANTTOOLS_DLL);
// 加载AssistantTools.dll并获取函数地址
hAssistantTools = LoadLibraryA(assistantTools_path);
if (NULL == hAssistantTools)
{
printf("LoadLibraryA fail: 0x%x\n", GetLastError());
goto End;
}
fun_XL_ParseTorrentFileW = (Fun_XL_ParseTorrentFileW)GetProcAddress(hAssistantTools, "XL_ParseTorrentFileW");
if (NULL == fun_XL_ParseTorrentFileW)
{
printf("GetProcAddress fail\n");
goto End;
}
fun_XL_ReleaseTorrentFileInfoW = (Fun_XL_ReleaseTorrentFileInfoW)GetProcAddress(hAssistantTools, "XL_ReleaseTorrentFileInfoW");
if (NULL == fun_XL_ParseTorrentFileW)
{
printf("GetProcAddress fail\n");
goto End;
}
fuzz_method(argv[1]);
End:
if(hAssistantTools)
{
FreeLibrary(hAssistantTools);
}
return 0;
}
g++ -g -o fuzz_program.exe fuzz_program.cpp
五、准备fuzz
6. 最后目录下如图所示:
六、生成覆盖率文件
1. 通过dynamorio工具对fuzz_program.exe在解析torrent文件时的执行流程进行污点跟踪,得到二进制的覆盖率文件,执行命令如下;
"D:\__workspace__\fuzz\dynamorio\build_Win32\bin32\drrun.exe" -t drcov -- "fuzz_program.exe"
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\samples\test.torrent"
2. 之后在当前目录下会看到生成的drcov前缀的log文件;
3. 使用32位ida打开AssistantTools.dll,使用ida插件lighthouse打开刚才生成的log文件;
4. 简单检查一下目标函数XL_ParseTorrentFileW的代码覆盖情况,绿色的为覆盖的部分;
七、对语料库samples最小化到minset目录下
"C:\Python27\python.exe" "D:\__workspace__\fuzz\winafl\winafl-cmin.py" --working-dir "D:\__workspace__\fuzz\winafl\build_Win32\bin\Release" -D
"D:\__workspace__\fuzz\dynamorio\build_Win32\bin32" -t 9000 -i
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\samples" -o
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\minset" -coverage_module
AssistantTools.dll -coverage_module P2PBase.dll -target_module fuzz_program.exe -target_method fuzz_method -nargs 1 --
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\fuzz_program.exe" @@
可以看到,原本samples目录中有92个测试样本,最小化到minset目录后得到13个测试样本;
"D:\__workspace__\fuzz\dynamorio\build_Win32\bin32\drrun.exe" -c winafl.dll -debug -coverage_module AssistantTools.dll -coverage_module P2PBase.dll -target_module fuzz_program.exe -target_method fuzz_method -fuzz_iterations 10 -nargs 1 --
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\fuzz_program.exe"
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\samples\test.torrent"
之后生成afl前缀的log文件,运行afl-fuzz.exe前设置的coverage_module参数和target_module参数的值只能从log文件中列出的模块里获取。
八、开始fuzz
计划使用一个master,两个slave分别为slave01和slave02;
1. master
"D:\__workspace__\fuzz\winafl\build_Win32\bin\Release\afl-fuzz.exe" -i
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\minset" -M master -o
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\result" -D
"D:\__workspace__\fuzz\dynamorio\build_Win32\bin32" -I 100000+ -t 9000 -- -coverage_module AssistantTools.dll -coverage_module P2PBase.dll -target_module fuzz_program.exe -target_method fuzz_method -fuzz_iterations 5000 -nargs 1 --
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\fuzz_program.exe" @@
2. slave01
"D:\__workspace__\fuzz\winafl\build_Win32\bin\Release\afl-fuzz.exe" -i
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\minset" -S slave01 -o
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\result" -D
"D:\__workspace__\fuzz\dynamorio\build_Win32\bin32" -I 100000+ -t 9000 -- -coverage_module AssistantTools.dll -coverage_module P2PBase.dll -target_module fuzz_program.exe -target_method fuzz_method -fuzz_iterations 5000 -nargs 1 --
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\fuzz_program.exe" @@
3. slave02
"D:\__workspace__\fuzz\winafl\build_Win32\bin\Release\afl-fuzz.exe" -i
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\minset" -S slave02 -o
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\result" -D
"D:\__workspace__\fuzz\dynamorio\build_Win32\bin32" -I 100000+ -t 9000 -- -coverage_module AssistantTools.dll -coverage_module P2PBase.dll -target_module fuzz_program.exe -target_method fuzz_method -fuzz_iterations 5000 -nargs 1 --
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\fuzz_program.exe" @@
九、中断fuzz过程
Ctrl+C
十、恢复fuzz
恢复fuzz只需要将原命令的“-i”参数修改为“-”即可,其他参数不变;
1. master
"D:\__workspace__\fuzz\winafl\build_Win32\bin\Release\afl-fuzz.exe" -i - -M master -o
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\result" -D
"D:\__workspace__\fuzz\dynamorio\build_Win32\bin32" -I 100000+ -t 9000 -- -coverage_module AssistantTools.dll -coverage_module P2PBase.dll -target_module fuzz_program.exe -target_method fuzz_method -fuzz_iterations 5000 -nargs 1 --
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\fuzz_program.exe" @@
2. slave01
"D:\__workspace__\fuzz\winafl\build_Win32\bin\Release\afl-fuzz.exe" -i - -S slave01 -o
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\result" -D
"D:\__workspace__\fuzz\dynamorio\build_Win32\bin32" -I 100000+ -t 9000 -- -coverage_module AssistantTools.dll -coverage_module P2PBase.dll -target_module fuzz_program.exe -target_method fuzz_method -fuzz_iterations 5000 -nargs 1 --
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\fuzz_program.exe" @@
3. slave02
"D:\__workspace__\fuzz\winafl\build_Win32\bin\Release\afl-fuzz.exe" -i - -S slave02 -o
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\result" -D
"D:\__workspace__\fuzz\dynamorio\build_Win32\bin32" -I 100000+ -t 9000 -- -coverage_module AssistantTools.dll -coverage_module P2PBase.dll -target_module fuzz_program.exe -target_method fuzz_method -fuzz_iterations 5000 -nargs 1 --
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\fuzz_program.exe" @@
十一、查看运行状态
1. 查看单个fuzzer的状态
以查看master的状态为例,将master状态输出到目录stat下;
"C:\python27-x64\python.exe"
"D:\__workspace__\fuzz\winafl\winafl-plot.py"
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\result\master"
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\stat"
在stat目录下输出的是index.html文件和三张png图片,直接拉到浏览器中查看即可;
2. 查看所有fuzzer状态
输出内容会直接打印在屏幕上;
"C:\python27-x64\python.exe" "D:\__workspace__\fuzz\winafl\winafl-whatsup.py"
"D:\__workspace__\fuzz\test_winafl\thunder_torrent\result"
十二、fuzz结果
共得到两类crash;
1. 除零异常导致的crash
2. 栈溢出导致的crash
希望大家能发现更多不同类型的crash。
看雪ID:昵称好麻烦
https://bbs.pediy.com/user-home-825829.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!