2025腾讯游戏安全竞赛技术竞赛初赛题解

2025腾讯游戏安全竞赛技术竞赛初赛题解

5m10v3

逆向分析

r3层分析

首先拿到赛题对r3的程序进行分析,发现在初始化函数这里有sub_140001000函数 正在进行异或操作

经过动态调试可得v0里面的变量为一张表

但我们对qword_7FF79B30AFD8这个地址进行交叉引用的时候我们发现在一个函数里面引用了它,并且这个函数好像是进行base58加密,因此我们知道这里应该是进行了base58换表加密,sub_7FF79B2D20D0

然后在初始化函数里面还存在另一个函数sub_7FF79B2D10D0,此函数里的sub_7FF79B2D1C90里面存在反调试函数

我们选择直接不走这个函数,在下图这里nop掉

然后我们就可以断在main函数

以下这个函数我们也要nop掉,因为我们只分析r3层的因此使用不到r0,之后就会检测我们输入的flag的前4位是否为ACE_

之后就是一个密钥的初始化

以下的两个函数分别为base58加密和异或,并且在在经过base58加密之后字符串的顺序还倒置了,异或的密钥为73787800(“sxx”)

因此r3的加密就是base58+reverse+xor

r0层分析

在很多函数里面都存在这样的花指令格式如下:

1
2
3
4
5
6
7
8
push reg
mov reg, xxxxxxx
pushfq
xxxx
popfq
jmp reg
xxxxx
pop reg

我们需要手动计算地址然后就能得到我们的真正逻辑,我们可以注意到我们的第一个函数sub_1400010A0,是一个典型的tea加密,但是解出来的是错的,然后我们对他进行交叉引用,发现多处引用了它,然后我们就猜测可能对这一处的函数进行了hook,果然待我们去除花指令之后就得到了真正的逻辑

但是我们可以在9B0A处下断点,然后直接定位到hook之后的地址处提取shellcode,这样我们就可以修复正确的tea加密

以下为去除花指令之后的效果:

然后就可以跟进去提取shellcode,然后修复回跳地址

解密代码

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
#include <stdio.h>
#include <stdint.h>
void decipher(unsigned int num_rounds, uint32_t *v, uint32_t key[4]) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], delta = 0x9E3779B9, sum = delta * num_rounds;
uint32_t v3 = key[0];
uint32_t v5 = key[1];
for (i = 0; i < num_rounds; i++) {
v1 -= (sum + key[(sum >> 11) & 3]) ^ (v0 + ((16 * v0) ^ (v0 >> 5)));
v0 -= (sum + v1) ^ (v3 + 16 * v1) ^ (v5 + (v1 >> 5));

sum -= delta;
}
v[0] = v0; v[1] = v1;
}

int main()
{
//密文
uint32_t v[42] = { 0x0EC367B8, 0xC9DA9044, 0xDA6C2DEB, 0x88DDC9C3, 0x32A01575, 0x231DD0B4, 0x4B9E8A74, 0xD75D3E74, 0xEAAB8712, 0xE704E888, 0xE01A31AC, 0xECAE205C, 0xA7BE7467, 0x0C6252A3, 0x1AEFEC4E, 0xC40DED44, 0xC3C842CC, 0xDE4A0C0E, 0x7C24F3FC, 0x8FB8D001, 0x11153E6E, 0x530ED15C, 0xF4214811, 0xBEB517E0, 0x63F91634, 0x4D96F8A5, 0xFE23EAC8, 0x2C607ADF, 0xCC43D85C, 0xFF186C5B, 0x8763E1A5, 0x9187BD58, 0x87D1069B, 0xD7878D7B, 0x836E6B68, 0x55A0C63F, 0xD979FDB3, 0x3E524DEE, 0x7AB35C82, 0xA2F4DA8D, 0x1708BA4C, 0x710653E6 };
//密钥
uint32_t k[4] = { 0x41,0x43,0x45,0x36 };
//轮数
unsigned int r = 32;
for (int i = 0; i < 42; i += 2)
{
decipher(r, v + i, k);
}
for (int i = 0; i < 42; i++)
{
for (int j = 0; j < 1; j++)
{
printf("%02x", (v[i] >> (8 * j)) & 0xff);
}
}
return 0;
}

得出来的十六进制数据再用cyberchef进行求解

验证

  • Title: 2025腾讯游戏安全竞赛技术竞赛初赛题解
  • Author: 5m10v3
  • Created at : 2025-03-31 00:00:00
  • Updated at : 2025-04-02 08:03:29
  • Link: https://redefine.ohevan.com/2025/03/31/2025腾讯游戏安全竞赛技术竞赛初赛题解/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
2025腾讯游戏安全竞赛技术竞赛初赛题解