flare-on 2023 第四题aimbot分析

查看 27|回复 0
作者:失神我醉了   
前言
我手贱看了一眼官网的荣誉榜,发现前几名神仙打架,第一名只用了2天的时间解决了所有的题,神的世界真离谱。。。想了解一下神的思路,在推上找到了第一名(jimo123),大概率韩国人,可惜推上显示没时间写writeup。不能了解神的思想,很痛苦。。。
回归正题,这题主要考验反反调试能力和对shellcode的理解力。这题也有点俄罗斯套娃,与第三题不相上下。。第三题更像是恶意软件在隐藏自身,而这题就是干会坏事了,
这个题的程序表面是个外挂程序,但它在后台默默偷取数据。
文件分析
exeinfo PE 显示文件用 x64 - MinGW-w64 GCC编译的,resources显示99%(有东西),用ResourceHacker得到三个文件,加密了识别不了。
运行程序后,有个按钮,点击没反应。
aimbot.exe的ida分析
跟着窗口函数,来到主要逻辑地方sub_402150函数,分析sub_402150函数,它主要做了以下几件事:
1. 打开"%PROGRAMFILES(X86)%\\Sauerbraten\\bin64\\sauerbraten.exe"文件,我将aimbot.exe和三个资源文件都试了不对,后面才知道是个游戏得下载(http://sauerbraten.org/)。
2. 计算sauerbraten.exe的md5 与硬编码比较


QQ图片20240505184233.png (20.75 KB, 下载次数: 0)
下载附件
2024-5-6 20:40 上传

3.
[color=]通过
AES
[color=]使用密钥
"yummyvitamincjoy"
[color=]解密三个资源,并将
3
[color=]个文件
miner.exe、config.json、aimbot.dll
[color=]提取到文件夹
%APPDATA%\BananaBot  
[color=]中
4. 从文件sauerbraten.exe(游戏)创建一个进程,然后调用函数sub_401E80,sub_401E80函数使用先前解密的aimbot.dll ,将 DLL 注入到文件刚创建的游戏进程中


QQ图片20240505184818.png (42.86 KB, 下载次数: 0)
下载附件
2024-5-6 20:40 上传

所以我们在aimbot.exe按下按钮后,会执行几个操作,1. 在%APPDATA%\BananaBot 文件夹中创建三个文件。2.运行文件miner.exe。 3.运行游戏 ,注入aimbot.dll 。
miner是个开源,跨平台的挖矿程序,不用分析,接下来分析aimbot.dll。
aimbot.dll 分析
来到dllmain,aimbot.dll 创建了三个线程,分别查看每个线程:


QQ图片20240505192720.png (30.37 KB, 下载次数: 0)
下载附件
2024-5-6 20:41 上传

[color=]第一个线程包含对
GetAsyncKeyState
[color=] 的调用,并在用户按下 5 小键盘数字键和 6 小键盘数字键时执行某些操作(作弊),
[color=]当在游戏过程中按下小键盘数字键5时,玩家角色锁定最近的敌人并执行射击。当按下 6 小键盘的数字键时,每当敌人经过玩家的目标时,玩家角色就会开枪。游戏里试了下,5的功能勉强能玩玩。。6有点废物。所以第一个线程不重要pass。
[color=]第三个线程执行调试反操作。它运行一个无限循环来检查进程是否处于调试状态,如果是,则调用
ExitProcess
[color=]函数并结束进程。
aimbot.dll
[color=]用了许多反调试技术,明面的
Windows api: IsDebuggerPresent, CheckRemoteDebuggerPresent, DbgBreakPoint 全与反调试相关。
第二个线程是主要的逻辑,
[color=]sub_62F43070函数
最后的shellcode 被解码后运行。为了获得解码后的代码需要动态调试对其进行分析。但由于第三个线程中的反调试,不可能直接附加到游戏进程。为了解决这个问题,我们将在游戏进程创建之后,在第三个线程开始运行之前附加到游戏进程。
我对反反调试技术一知半解,所以我打算使用ScyllaHide插件,然后结合nop大法和改rip来实现动态反调试,后面的方法要注意堆栈平衡,不然容易崩。。。为了防止不知道什么情况导致程序崩了,从头再来,使用虚拟机快照保存每个值得快照的阶段。
[color=]为了能附加到游戏进程,在aimbot.exe进程中的sub_401E80 函数上设置断点。运行程序并按下 BananaAimBot 窗口中的按钮。游戏打开后,aimbot.exe进程会停在断点处。我们将附加到游戏进程,并在 CreateThread 函数上设置断点。然后继续运行游戏进程,直到在
CreateThread 函数上
[color=]的断点处停止。我们将继续运行直到创建第二个线程之前。在创建它之前,我们将在它的线程函数的开头设置一个断点,即 sub_62F43070。我们将继续运行,直到创建第三个线程之前。在创建第三个线程之前,我们将跳过对 CreateThread 的调用(通过编辑 rip 寄存器或将调用 CreateThread 的代码更改为 NOP)
接下来分析第二个进程的主要逻辑sub_62F43070函数。
[color=]该函数开头是检查当前时间,休眠 5 分钟,并检查已经过去的时间确实至少为 5 分钟。如果测试通过,则执行该函数的逻辑(rip大法)。
然后它
[color=]创建文件夹“C:\depot”。接着调用函数 sub_62F43A20,分析后改为requestData_fromUrl。


QQ图片20240505212422.png (54.15 KB, 下载次数: 0)
下载附件
2024-5-6 20:41 上传

get_key1_62F42300函数被多次用到,需重点分析一下。
[color=]requestData_fromUrl函数里也用到它,通过它解密url相关的字符串。在
get_key1_62F40230里,先是反调试,然后调用了sub_62F42020,主要逻辑就在这个函数。在这个函数中,使用了更多的反调试技术:
[color=]1. NtQueryInformationProcess 反调试。
[color=]2. 使用 PEB 结构中的 BeingDebugged 标志并检查其值是否为零
[color=]3. 该函数对计算机上运行的所有进程执行枚举过程,计算每个进程名称的哈希值,并在预定义的哈希值数组中查找哈希值。当数组中的哈希值与计算机上运行的进程名称匹配时,该函数会增加计数器并重置数组中与该进程相对应的值。可以调试得到相关进程的名字(如果你有运行的话),例如explorer.exe、x64dbg.exe ,ida.exe,在0x62F42246 上设置断点,查看相关的进程名称


QQ图片20240505221311.png (34.86 KB, 下载次数: 0)
下载附件
2024-5-6 20:41 上传



QQ图片20240505221603.png (45.62 KB, 下载次数: 0)
下载附件
2024-5-6 20:41 上传



QQ图片20240505221645.png (30.59 KB, 下载次数: 0)
下载附件
2024-5-6 20:42 上传

[color=]函数的最后会通过相加以下几个值,作为返回值。
[color=]1. 从父进程(aimbot.exe 进程)内存中偏移量0x406220 处读取 4个字节
[color=]2. 常数 0x1337+程序计数
[color=]3. 从当前进程(游戏)内存中偏移量 0x138E 处读取 4个字节
[color=]动态变化的只有程序计数。通过动态调试,当程序计数为1时(即只检测到
explorer.exe,没有其他的调试进程),
[color=]函数的返回值为0x6499F8A9,这个值可以解密字符串。
[color=]为了防止反调试干扰,直接在get_key1_62F42300函数开头修改:
mov eax, 0x6499F8A9
ret
调试过后,可以知道
[color=]requestData_fromUrl主要作用是:将
[color=]字符串
"
[color=]Bananabot 5000
"
[color=]解码,传递给 InternetOpenA 函数。然后,将字符串"http://127.0.0.1:57328/2/summary"解码并传递给 InternetOpenUrlA 函数,
最后调用 InternetReadFile 函数获取数据,在游览器访问"http://127.0.0.1:57328/2/summary"可以看到。这其实是miner.exe 进程的 http 服务器,其定义可以在 config.json文件中看到。
[color=]随后回到
[color=]sub_62F43070函数,该函数后面通过从url读取的数据作为密钥来解码shellcode,shellcode使用密钥
[color=]"version": "6.20 进行AES ECB解码,其实不用关心,因为程序没蹦。。
[color=]调试到call rdi,使用scylla插件或者命令savedata从内存dump 0x4470数据,保存为bin1,接下来就是分析bin1。
bin1分析
[color=]将bin1放入ida,结合动态调试,可以知道第一个函数resolve_function为了解析函数地址,写入到word_836所在位置。也可以通过汇编代码"mov rax,gs:[60]"知道是在获得PEB地址,恶意软件技术获取函数地址的常用技术开头。


QQ图片20240505003651.png (39.22 KB, 下载次数: 0)
下载附件
2024-5-6 20:46 上传



QQ图片20240504234712.png (59.14 KB, 下载次数: 0)
下载附件
2024-5-6 20:42 上传

[color=]bin1的主要逻辑在bin1_main, 该函数逻辑:
[color=]读取"C:\Program Files (x86)\Steam\config\config.vdf"打开的文件(虚拟机没有steam,伪造一下),然后从中获得
"
[color=]SentryFile
"
[color=]字段对应的文件的路径(
SentryFile对应值是路径),并将 SentryFile 文件复制到"C : \depot\ssfn_steam"。最后,该函数使用 config.vdf.文件的前 16个字节作为key使用rc4算法来解码额外的 shellcode并跳转。


QQ图片20240506010416.png (91.29 KB, 下载次数: 0)
下载附件
2024-5-6 20:44 上传



QQ图片20240505014042.png (72.8 KB, 下载次数: 0)
下载附件
2024-5-6 20:47 上传

[color=]使用同样的方法dump  bin2,接着分析bin2
bin2分析
bin2 与bin1差不多,第一步也是解析函数,然后这次针对的是discard平台,主要逻辑:在 C:\Users\invoker\AppData\Roaming\Discord\Local Storage\leveldb 中搜索 .ldb 文件(Microsoft Access 锁定信息文件),然后在每个 .ldb 文件的内容中搜索 dQw4w9WgXcQ (youtube)( Never Gonna Give You Up  经典名曲。。) 复制到
[color=]"C:\depot"。
最后从 Cookies 文件中读取 16个字节(SQLite format 3\0)并将其用作密钥解码下一阶段的shellcode。


QQ图片20240506010416.png (91.29 KB, 下载次数: 0)
下载附件
2024-5-6 21:17 上传

bin3分析
bin3,和bin2一样,经典套娃。。这次针对的是
[color=]Sparrow 数字钱包文件(得下载),
主要逻辑:
[color=]在 C:\Users\three\AppData\Roaming\Sparrow\wallets 中搜索数据库文件,将文件复制到
"C:\depot",最后用17字节"
[color=]recentWalletFiles" 解码下一个阶段shellcode


QQ图片20240506014250.png (60.87 KB, 下载次数: 0)
下载附件
2024-5-6 20:44 上传

bin4分析
[color=]bin4 将之前偷的东西发给服务器,主要逻辑:函数收集前面步骤中保存在
[color=]C:\depot
[color=]文件夹中的所有文件,并将它们组合成一个名为“output”的文件。并通过 HTTP POST转发到 https://bighackies.flare-on.com/stolen。
[color=]然后,它读取对发送的 HTTP 请求的响应,对输出内容与响应接收到的字节数执行多次 32CRC。如果所有比较都成功通过,则将执行解码阶段。这次解密用的xor ,xor的key与
[color=]http
[color=]_
[color=]response
[color=]_
[color=]size相关,我们可以直接推出key,不用执行http请求。因为解码后的bin前4个字节为"the ",即
[color=] 0x20656874,而加密的bin
[color=]前4个字节为
[color=]0x32513E04,两者异或为0x12345670,所以key=
[color=]0x12345670,即
[color=]http
[color=]_
[color=]response
[color=]_
[color=]size=0x10。


QQ图片20240506120524.png (52.73 KB, 下载次数: 0)
下载附件
2024-5-6 20:44 上传

bin5分析
[color=]bin5最后的阶段,方式和之前一样,主要逻辑:从当前进程(即游戏)的内存中读取字节,比较当前地图名称的前 4个字节是"spcr",从
[color=]地图的
[color=]spcr2.cfg
[color=]文件中读取数据,因为选完地图可能改变内存或配置文件,我又重新来了一遍(在选完地图后附加,都是泪),然后忽略if条件(没有影响数据变化)。后面会计算 flag的CRC32 并将结果与​​常量 0xA5561586进行比较,最后得到flag



QQ图片20240506145334.png (62.54 KB, 下载次数: 0)
下载附件
2024-5-6 20:44 上传

Flag: [email protected]
参考链接
Anti-Debug Tricks
writeup

微软, 函数

您需要登录后才可以回帖 登录 | 立即注册

返回顶部