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

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

2021-2-8 02:05
24377

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

 
 
#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;
}
#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;
    }

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-3-5 02:51 被TechForBad编辑 ,原因:
上传的附件:
收藏
免费 9
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  demoscene   +1.00 2021/02/25
最新回复 (20)
雪    币: 14517
活跃值: (17538)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2021-2-8 14:29
0
雪    币: 2337
活跃值: (3059)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
要对宅男下手了吗
2021-2-8 15:44
1
雪    币: 4094
活跃值: (4205)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
boursonjane 要对宅男下手了吗
没错,想象一下,你拿到一个torrent种子文件,一看3M多,激动得不行,一打开,啪得一下,电脑就中毒了,你电脑上所有的片都被锁了,需要购买比特币才能获取密钥
2021-2-8 15:50
0
雪    币: 5639
活跃值: (3010)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
昵称好麻烦 没错,想象一下,你拿到一个torrent种子文件,一看3M多,激动得不行,一打开,啪得一下,电脑就中毒了,你电脑上所有的片都被锁了,需要购买比特币才能获取密钥
一个3M的种子不会很奇怪吗?
2021-2-8 17:12
0
雪    币: 4094
活跃值: (4205)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
梦醒花败 一个3M的种子不会很奇怪吗?[em_4]
奇怪?兴奋到爆炸 :-)
2021-2-8 20:26
0
雪    币: 883
活跃值: (884)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
发现现在下载软件开始扫码下载功能了。
2021-2-8 23:25
0
雪    币: 54
活跃值: (115)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
这篇文章让我认识到了学好 栈溢出的重要性
2021-2-12 19:39
0
雪    币: 86
活跃值: (1220)
能力值: ( LV7,RANK:150 )
在线值:
发帖
回帖
粉丝
9
强呀~  楼主写这种fuzz_program.cpp有没有什么心得
2021-2-15 19:08
0
雪    币: 4094
活跃值: (4205)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
10
shuozhang 强呀~ 楼主写这种fuzz_program.cpp有没有什么心得[em_76]
只要把winafl源码读一遍,就知道这种程序怎么写了
2021-2-16 14:19
0
雪    币: 86
活跃值: (1220)
能力值: ( LV7,RANK:150 )
在线值:
发帖
回帖
粉丝
11
厉害了~
2021-2-16 19:05
0
雪    币: 4094
活跃值: (4205)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
12
荒huang 这篇文章让我认识到了学好 栈溢出的重要性
多谢提醒,因为这个东西是我去年搞的,过年才想起来要做个分享,写文章的时候忘了当时具体是什么原因导致的crash了,才发现crash的具体原因,文章已经修改了,欢迎提出问题
2021-3-3 01:36
0
雪    币: 0
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
爱奇艺
2021-3-4 18:59
0
雪    币: 3
活跃值: (65)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
2021-3-8 10:23
0
雪    币: 2604
活跃值: (231)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
昵称好麻烦 没错,想象一下,你拿到一个torrent种子文件,一看3M多,激动得不行,一打开,啪得一下,电脑就中毒了,你电脑上所有的片都被锁了,需要购买比特币才能获取密钥
惨,宅男,惨,唯一的快乐都要剥夺的吗
2021-3-10 21:45
0
雪    币: 188
活跃值: (373)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
按照大佬的姿势fuzz出来了循环call导致的栈溢出
2021-4-2 20:24
0
雪    币: 3
活跃值: (49)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
师傅当时用的迅雷版本号是多少?
2022-5-26 10:07
0
雪    币: 576
活跃值: (2035)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
mark一下
2022-5-26 12:54
0
雪    币: 4094
活跃值: (4205)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
19
overXsky 师傅当时用的迅雷版本号是多少?
现在的版本好像依然有这个问题
2022-6-16 10:53
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
请问我输入了正确的target_offset或者正确的target_method,在第八步生成的 afl前缀的log文件 都会出现“WARNING: Target function was never called. Incorrect target_offset?”是什么情况?后面的coverage map也有一些内容。
2024-6-12 12:09
0
雪    币: 4094
活跃值: (4205)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
21
蓝莓黑巧 请问我输入了正确的target_offset或者正确的target_method,在第八步生成的 afl前缀的log文件 都会出现“WARNING: Target function was never ...
可能是因为找不到这个导出函数导致的,C++名称修饰?
2024-6-13 20:50
0
游客
登录 | 注册 方可回帖
返回
//