2025腾讯游戏安全技术竞赛 PC客户端安全 初赛WP
2025腾讯游戏安全技术竞赛 PC客户端安全 初赛WP
前言
这也是本菜鸡第一次参加该比赛,之前是有看过前几年比赛的WP,感觉难度不小,这次来尝试一下,由于是纯CTF类型,做起来还算顺手,不过也是遇到不少问题。经过半天的奋战最后还是解了出来,综合体验下来收获还是不少的。
R3分析
将ACEFirstRound.exe放入IDA分析,在main函数可以看到一个虚表,根据里面各个函数内容,将每个虚表函数都重新命名为对应功能。
发现是运行了ACEDriver驱动,与r3程序之间进行通信。
尝试动调发现没办法,发现程序退出,根据CheckRemoteDebuggerPresent的交叉引用发现一个反调试函数。
找该函数的交叉调用,发现是这边启了一个线程来启动反调试。
在该函数这边进行条件断点,修改rip,让代码直接执行到函数结束处,跳过中间反调试相关代码,即可绕过反调试。
动调分析,然后这边输入flag要求是以”ACE_”开头,然后去掉前面这四个字符,首先进行Base58加密,然后再将数据倒转。这边Base58是变表,和标准不一样,提取得:abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789
与”sxx”进行循环xor。
最后通信发送到ACEDriver,命令码是0x154004。
至此R3层分析完毕。
R0分析
IDA载入ACEDriver.sys,发现有几个消息的Callback,但是跳转过来发现有混淆和花指令。
该驱动的混淆和花指令都是一个类型的,花指令是最基础的。
以下图为例子:
对41e9按u再跳过e9字节按c还原,即可pass花指令。
然后截图处是一块,将地址计算完进行jmp,计算出来实际就是jmp到下面pop处,说明这一段是无用的,可以直接将push到pop全部nop即可。其他地方都和这地方混淆差不多类型,都直接跳过花指令后nop即可。
但有一种比较特殊,并不是跳转到下面邻近代码处,而是jmp到其他代码处,观察push和底下pop寄存器是否一致就可以判断是哪一种类型,该种就得手动计算地址然后写jmp。
手动去除大部分混淆后,就可以看到几个回调的里面代码,MessageNotifyCallback里面的代码如下:
进入几层call就可以看到这边就是判断命令码执行,下面就是接收R3发送来的密文数据。
进入call发现就是关键处,unk_140004064那边就是flag密文,使用的是tea加密,key是[‘A’,’C’,’E’,’6’],然后边加密边判断密文是否相等。
查看tea函数的交叉调用,发现有其他地方有出现。
在第四个call处,发现一个函数传入了tea加密的函数地址,然后进行了一系列变换,应该是对tea函数本体进行了修改。
将该函数代码和相关数据进行提取,对tea函数字节进行本地模拟操作。
1 | // tea函数原字节 |
编译使用IDA动调,并按c分析tea数组处的代码,发现分成了三块,手动将三块合并到一块代码,并修复部分跳转的地址,即可得到完整的代码。
合并完的代码如下:
反编译得到修改后的魔改tea加密
即可编写得到对应的解密代码:
1 | void tea_decrypt(unsigned int* Input, int* Key) |
进行对unk_140004064密文解密即可,不过注意一点,这边是从-1处开始判断,也就是unk_140004064-4处开始是密文。
提取出来就是42的DWORD数据,和上面的判断数值对应上了。
解密
1 |
|
Out
33 28 13 0 2D 16 40 41 13 2A 12 4F 45 4B 1F 14 39 49 3B 34 3A 26 3B 19 24 2B 22 5 4C E 0 4C 3B 4 2B 1D 5 39 16 22 3D B
CyberChef
xor(‘sxx’) -> Reverse -> Base58 Decode(换表)
密文:We1C0me!T0Z0Z5GamESecur1t9*CTf
Flag
flag{ACE_We1C0me!T0Z0Z5GamESecur1t9*CTf}