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

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

2021-2-8 02:05
20190

一、漏洞挖掘目标

打开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


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2021-3-5 02:51 被昵称好麻烦编辑 ,原因:
上传的附件:
收藏
点赞9
打赏
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  demoscene   +1.00 2021/02/25
最新回复 (18)
雪    币: 12075
活跃值: (15434)
能力值: ( LV12,RANK:240 )
在线值:
发帖
回帖
粉丝
pureGavin 2 2021-2-8 14:29
2
0
感谢分享
雪    币: 2425
活跃值: (2844)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
boursonjane 2021-2-8 15:44
3
1
要对宅男下手了吗
雪    币: 4083
活跃值: (3748)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
昵称好麻烦 2021-2-8 15:50
4
0
boursonjane 要对宅男下手了吗
没错,想象一下,你拿到一个torrent种子文件,一看3M多,激动得不行,一打开,啪得一下,电脑就中毒了,你电脑上所有的片都被锁了,需要购买比特币才能获取密钥
雪    币: 4789
活跃值: (2169)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
梦醒花败 2021-2-8 17:12
5
0
昵称好麻烦 没错,想象一下,你拿到一个torrent种子文件,一看3M多,激动得不行,一打开,啪得一下,电脑就中毒了,你电脑上所有的片都被锁了,需要购买比特币才能获取密钥
一个3M的种子不会很奇怪吗?
雪    币: 4083
活跃值: (3748)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
昵称好麻烦 2021-2-8 20:26
6
0
梦醒花败 一个3M的种子不会很奇怪吗?[em_4]
奇怪?兴奋到爆炸 :-)
雪    币: 883
活跃值: (884)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jacker78 2021-2-8 23:25
7
0
发现现在下载软件开始扫码下载功能了。
雪    币: 54
活跃值: (115)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
荒huang 2021-2-12 19:39
8
0
这篇文章让我认识到了学好 栈溢出的重要性
雪    币: 67
活跃值: (730)
能力值: ( LV7,RANK:150 )
在线值:
发帖
回帖
粉丝
shuozhang 2 2021-2-15 19:08
9
0
强呀~  楼主写这种fuzz_program.cpp有没有什么心得
雪    币: 4083
活跃值: (3748)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
昵称好麻烦 2021-2-16 14:19
10
0
shuozhang 强呀~ 楼主写这种fuzz_program.cpp有没有什么心得[em_76]
只要把winafl源码读一遍,就知道这种程序怎么写了
雪    币: 67
活跃值: (730)
能力值: ( LV7,RANK:150 )
在线值:
发帖
回帖
粉丝
shuozhang 2 2021-2-16 19:05
11
0
厉害了~
雪    币: 4083
活跃值: (3748)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
昵称好麻烦 2021-3-3 01:36
12
0
荒huang 这篇文章让我认识到了学好 栈溢出的重要性
多谢提醒,因为这个东西是我去年搞的,过年才想起来要做个分享,写文章的时候忘了当时具体是什么原因导致的crash了,才发现crash的具体原因,文章已经修改了,欢迎提出问题
雪    币: 0
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
不知道起啥 2021-3-4 18:59
13
0
爱奇艺
雪    币: 3
活跃值: (65)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
finger_xyz 2021-3-8 10:23
14
0
雪    币: 2604
活跃值: (231)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
星雪鸢尾 2021-3-10 21:45
15
0
昵称好麻烦 没错,想象一下,你拿到一个torrent种子文件,一看3M多,激动得不行,一打开,啪得一下,电脑就中毒了,你电脑上所有的片都被锁了,需要购买比特币才能获取密钥
惨,宅男,惨,唯一的快乐都要剥夺的吗
雪    币: 188
活跃值: (373)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xkkhh 2021-4-2 20:24
16
0
按照大佬的姿势fuzz出来了循环call导致的栈溢出
雪    币: 3
活跃值: (49)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
overXsky 2022-5-26 10:07
17
0
师傅当时用的迅雷版本号是多少?
雪    币: 576
活跃值: (2035)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kakasasa 2022-5-26 12:54
18
0
mark一下
雪    币: 4083
活跃值: (3748)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
昵称好麻烦 2022-6-16 10:53
19
0
overXsky 师傅当时用的迅雷版本号是多少?
现在的版本好像依然有这个问题
游客
登录 | 注册 方可回帖
返回