smallzhong 发表于 2021-4-12 14:28

2021腾讯游戏安全复赛PC客户端 WP(只做到算出flag,没有写外挂)

本帖最后由 smallzhong 于 2021-4-12 15:41 编辑

### WriteUp

+ 题目要求

!(https://cdn.jsdelivr.net/gh/smallzhong/new-picgo-pic-bed@master/image-20210412153925695.png)

+ 赛题下载地址: https://gslab.qq.com/html/competition/2021/race-final.htm ,选择 `PC客户端安全` 下载。

+ 拿到这道题目首先运行 `hack.exe` ,发现直接退出了。于是拖入ida查看。发现 `1400015e0` 处是主要函数。首先是遍历进程链表,然后通过 `OpenProcess` 打开进程,再通过 `WriteProcessMemory` 往进程中写入数据,再 `CreateRemoteThread` 开启远程线程。是标准远程线程注入模板。

!(https://cdn.jsdelivr.net/gh/smallzhong/new-picgo-pic-bed@master/image-20210410180411805.png)

+ 拖入 `x64dbg` ,发现程序开启了 `ASLR` 。关闭 `ASLR` 重新进行动态调试,在 调用 `OpenProcess` 处下断,发现程序并未跑到这里便死掉了。猜想前面有验证,估计跟 `flag` 有关。

!(https://cdn.jsdelivr.net/gh/smallzhong/new-picgo-pic-bed@master/image-20210412143217475.png)

+ 往前面看一下,发现调用了 `ReadFile` 从文件中读取数据。在 `CreateFileA` 处下断点发现打开的文件名为 `hack.dat` 。在程序目录下创建一个 `hack.dat` ,随便填入些数据,程序跑起来了,但是发现 `ProcName` 里面放了奇怪的数据。我填入 `hack.dat` 里面的数据是 `123123123123` ,而 `ProcName` 里面的数据也与其结构类似,猜测前面有一个函数将读取的内容进行了解密。

!(https://cdn.jsdelivr.net/gh/smallzhong/new-picgo-pic-bed@master/image-20210412143243862.png)

+ 往前面看发现在 `1400014d0` 有一个函数使用读入的数据作为参数且返回值赋给了 `v6` ,而 `v6` 的双数下标又赋给了 `ProcName` 。跟进这个函数发现有很多浮点运算,并不太能看懂。回想到之前经过函数解密的结果非常有规律,我猜测这个加密函数对字节的加密是一一对应的,是置换加密。通过以下代码构造一个输入数据 `hack.dat`

```cpp
FILE* fp = fopen("F:\\pc_saiti\\hack\\hack.dat", "w");
for (int i = 0; i <= 0xff; i++)
{
      fwrite(&i, 1, 1, fp);
}
```

把程序拖入OD进行动态调试,在 `1400016CE` 处下断,在解密函数调用结束之后查看返回值 `rax`

![](https://cdn.jsdelivr.net/gh/smallzhong/new-picgo-pic-bed@master/image-20210412142520956.png)

可以看到解密后的数据。通过 `x64dbg` 插件 `Scylla` 将其 `dump` 下来

!(https://cdn.jsdelivr.net/gh/smallzhong/new-picgo-pic-bed@master/image-20210412142556605.png)

+ 可以得到各个字节数据对应的数据。逐个比较可以得到 `ShooterClient.exe` 字符串对应的数据是

```cpp
char a[] = {0x59, 0x44, 0xbd, 0xbd, 0xb8, 0x47, 0xba, 0x69, 0x40, 0x43, 0x47, 0xbe, 0xb8, 0x7e, 0x47, 0xb4, 0x47, 0x2c};
```

看到程序中给 `ProcName` 赋值的时候是交替选取的

!(https://cdn.jsdelivr.net/gh/smallzhong/new-picgo-pic-bed@master/image-20210412142605936.png)

因此写了一段小程序

```cpp
FILE* fp = fopen("F:\\pc_saiti\\hack\\hack.dat", "w");
char t = 0x40;
fwrite(&t, 1, 1, fp);
for (int i = 0; i < sizeof(a); i++)
{
        t = 0x40;
        fwrite(&t, 1, 1, fp);
        t = a;
        fwrite(&t, 1, 1, fp);
}
```
来算得 `flag` 。在程序文件夹中放入对应 `hack.dat` 文件后外挂程序可正常运行, `dll` 成功注入到游戏中,外挂功能正常。

!(https://cdn.jsdelivr.net/gh/smallzhong/new-picgo-pic-bed@master/image-20210412142614198.png)

+ 在 `WriteProcessMemory` 处下断,根据 `x64` 调用约定查看 `rcx,rdx,r8,r9` ,可以看到第一次调用时注入的东西有明显的 `MZ` 头,应是一个 `dll` 文件。

!(https://cdn.jsdelivr.net/gh/smallzhong/new-picgo-pic-bed@master/image-20210412142629960.png)

+ ……本wp到此为止,外挂写不出来,还是太菜了,希望明年能打得更好吧。

xuanmo 发表于 2021-4-12 15:06

学到了,tql:Dweeqw

ztdf123 发表于 2021-4-14 17:25

发现 1400015e0 处是主要函数
楼主请问一下这个是怎么确定的,可以的话可以给个联系方式吗,想和大佬交流下

Qfrost 发表于 2021-4-12 14:45

师傅tql   学到了(

爱学习的秋秋 发表于 2021-4-12 15:21

Qfrost 发表于 2021-4-12 14:45
师傅tql   学到了(

逛论坛抓到了wzgg 好巧

Duzit 发表于 2021-4-12 16:08

优秀,学习了

w92vv 发表于 2021-4-12 16:35

这是高手,学习了!

yunruifuzhu 发表于 2021-4-12 17:17

所以这就是腾讯TP不断更新的成果,基于全网大家的努力

有、 发表于 2021-4-12 17:35

很牛鼻..学习了

swhyy 发表于 2021-4-12 17:55

这个方法很好,给你加分

sapin 发表于 2021-4-12 18:22

很好的分享,学到了~
页: [1] 2
查看完整版本: 2021腾讯游戏安全复赛PC客户端 WP(只做到算出flag,没有写外挂)