首页
论坛
课程
招聘
[原创]使用winafl对迅雷的torrent解析逻辑进行fuzz
2021-2-8 02:05 7742

[原创]使用winafl对迅雷的torrent解析逻辑进行fuzz

2021-2-8 02:05
7742

一、漏洞挖掘目标

打开torrent文件时,迅雷会对torrent文件进行解析,得到需要下载的内容,所以想要对迅雷解析torrent文件的逻辑进行尝试二进制漏洞挖掘。

二、目标模块与接口

经过使用procmon抓包以及逆向分析,发现迅雷对torrent文件的解析流程在动态链接库AssistantTools.dll的导出函数XL_ParseTorrentFileW中。
所以目标模块就是AssistantTools.dll,接口就是XL_ParseTorrentFileW。

三、部署winafl环境

(1)winafl目录在“D:__workspace__\fuzz\winafl”

 

(2)dynamorio目录在“D:__workspace__\fuzz\dynamorio”

 

注:编译winafl和dynamorio请参考这篇文章

四、编写fuzz主程序并编译

1.源文件fuzz_program.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#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;
}

2.编译源文件fuzz_program.cpp得到fuzz_program.exe

1
g++ -g -o fuzz_program.exe fuzz_program.cpp

五、准备fuzz

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文件时的执行流程进行污点跟踪,得到二进制的覆盖率文件,执行命令如下;

1
"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目录下

1
"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个测试样本;

八、获取fuzz_program.exe在运行时的模块加载状况、文件打开状况、网络连接状况

1
"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

1
"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

1
"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

1
"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

1
"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

1
"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

1
"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下;

1
"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状态

1
"C:\python27-x64\python.exe" "D:\__workspace__\fuzz\winafl\winafl-whatsup.py" "D:\__workspace__\fuzz\test_winafl\thunder_torrent\result"

输出内容会直接打印在屏幕上;
图片描述
如上图所示,目前有3个fuzzer在运行,共产生了17个crash文件;

十三、fuzz结果

共得到两类crash;

 

1、除零异常导致的crash
这类样本占了大多数,一般来说很难利用,意义不大;

 

2、栈溢出导致的crash
别激动,经过分析,很难利用,原因如下:
在解析torrent文件的过程中,每次文件中出现一个‘d’字符,都会导致程序递归调用同一个函数,最终导致栈溢出;

十四、crash样本

我将得到的两类crash分别取出一个样本放到了附件crash.7z中;
图片描述
只要双击运行crash样本文件即可触发迅雷去解析,然后就会得到如下错误提示框;
图片描述

十五、迅雷官方反馈

图片描述

 

希望大家能发现更多不同类型的crash


[培训] 优秀毕业生寄语:恭喜id:一颗金柚子获得阿里offer《安卓高级研修班》火热招生!!!

最后于 2021-3-5 02:51 被昵称好麻烦编辑 ,原因:
上传的附件:
收藏
点赞7
打赏
分享
打赏