打开torrent文件时,迅雷会对torrent文件进行解析,得到需要下载的内容,所以想要对迅雷解析torrent文件的逻辑进行尝试二进制漏洞挖掘。
经过使用procmon抓包以及逆向分析,发现迅雷对torrent文件的解析流程在动态链接库AssistantTools.dll的导出函数XL_ParseTorrentFileW中。 所以目标模块就是AssistantTools.dll,接口就是XL_ParseTorrentFileW。
(1)winafl目录在“D:__workspace__\fuzz\winafl”
(2)dynamorio目录在“D:__workspace__\fuzz\dynamorio”
注:编译winafl和dynamorio请参考这篇文章
1.源文件fuzz_program.cpp
2.编译源文件fuzz_program.cpp得到fuzz_program.exe
1、准备在目录“D:__workspace__\fuzz\test_winafl\thunder_torrent”下进行fuzz;
2、将AssistantTools.dll拷贝到目录下; (AssistantTools.dll来自“D:\softwares\Thunder Network\Thunder\Program\resources\bin\SDK\AssistantTools.dll”)
3、由于AssistantTools.dll依赖P2PBase.dll,所以也需要将P2PBase.dll拷贝到目录下; (P2PBase.dll来自“D:\softwares\Thunder Network\Thunder\Program\resources\bin\SDK\P2PBase.dll”)
4、将winafl.dll拷贝到目录下; (winafl.dll来自"D:__workspace__\fuzz\winafl\build_Win32\bin\Release\winafl.dll")
5、准备一个语料库目录samples,里面塞满各种地方找来的torrent文件;
6、最后目录下如图所示;
1、通过dynamorio工具对fuzz_program.exe在解析torrent文件时的执行流程进行污点跟踪,得到二进制的覆盖率文件,执行命令如下;
2、之后在当前目录下会看到生成的drcov前缀的log文件;
3、使用32位ida打开AssistantTools.dll,使用ida插件lighthouse打开刚才生成的log文件;
4、简单检查一下目标函数XL_ParseTorrentFileW的代码覆盖情况,绿色的为覆盖的部分;
可以看到,原本samples目录中有92个测试样本,最小化到minset目录后得到13个测试样本;
之后生成afl前缀的log文件,运行afl-fuzz.exe前设置的coverage_module参数和target_module参数的值只能从log文件中列出的模块里获取。
计划使用一个master,两个slave分别为slave01和slave02; 1、master
2、slave01
3、slave02
Ctrl+C
恢复fuzz只需要将原命令的“-i”参数修改为“-”即可,其他参数不变; 1、master
2、slave01
3、slave02
1、查看单个fuzzer的状态 以查看master的状态为例,将master状态输出到目录stat下;
在stat目录下输出的是index.html文件和三张png图片,直接拉到浏览器中查看即可;
2、查看所有fuzzer状态
输出内容会直接打印在屏幕上; 如上图所示,目前有3个fuzzer在运行,共产生了17个crash文件;
共得到两类crash;
1、除零异常导致的crash 这类样本占了大多数,一般来说很难利用,意义不大;
2、栈溢出导致的crash 别激动,经过分析,很难利用,原因如下: 在解析torrent文件的过程中,每次文件中出现一个‘d’字符,都会导致程序递归调用同一个函数,最终导致栈溢出;
我将得到的两类crash分别取出一个样本放到了附件crash.7z中; 只要双击运行crash样本文件即可触发迅雷去解析,然后就会得到如下错误提示框;
希望大家能发现更多不同类型的crash
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
;
}
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;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-3-5 02:51
被TechForBad编辑
,原因:
上传的附件: