2025腾讯游戏安全初赛PC
1 .exe初探
下发了一个.exe和一个.sys,在真机不太敢直接调.sys文件,丢到调试环境里面去
在调试环境里面能跑起来,随便给点输入回显Flag not correct!
.exe丢进IDA看看
找到输入逻辑和检测前缀的逻辑
然后发现后面一堆混淆,静态不太好看,调试一下.exe程序看看
发现调试的时候经常进一个abort()
怀疑有反调试,稍微找找常见的调试检测函数,发现用了CheckRemoteDebuggerPresent
把所有引用都扬了,就可以欢乐的调试了
调试过程中拿到这里的key_maybe是字符串”sxx”
这里的new_input是输入去掉前缀”ACE_“
之后的字符串
encode函数通过这里的经典特征%58和/58可以看出来有用到base58
同时调试一下可以看出来输入的流程是
input → base58 → 字符串反转
顺带一提base58是经过变表的,变表的逻辑在SEH里面,
然后继续调试可以发现输入又和上面提到的key_maybe变量进行了异或,异或之后被送到驱动里面进行check,所以完整的逻辑是
input → base58 → reverse → xor “sxx” → check
这里的vtable结构如下,前面几个应该是注册服务的函数,由于和flag没什么关系就没细致分析
最后通过FilterSendMessage函数和驱动交互
2 分析.sys
所以进一步就要去.sys文件里面分析逻辑了
不过没什么头绪,DriverEntry有点太干净了,没头绪就一顿找,找到注册消息回调函数的地方
MessageNotifyCallback就是处理.exe里面发的函数,但是点进去发现
注意到段名是tvm0,搜索一下发现是TX自家的壳,github上可以找到一个xx_tvm
https://github.com/wbaby/xx_tvm
但是跑不动,疑似tvm升级了,没办法只能手动改花指令
这里用到的花指令基本上都如下这种
把jmp改成两个数相加或者相减然后再jmp寄存器,干扰ida,一般来说从一个push XXX 到下一个 pop XXX之间的都是可以扬掉的无用指令,有些jmp的比较远的就得自己手动计算一下还原了
还原后找到处理指令码的地方,这里的0x154004就是我们FilterSendMessage发过去的指令码
然后逻辑就很清晰了大概
encrypt像个tea,手动还原一下发现不对
之所以能确定不对,是因为输入的是uint8,但是把密文解密回去发现是个完整的uint32
3 调试.sys
首先怀疑是有程序修改了密文,或者encrypt里面的密钥,结果找了一圈也没找到,但是再找encrypt引用的时候,发现
在某个地方似乎对encrypt的代码做了修改,照着它改看看
….
这去哪了?
0FFFFB0035F716000h是个什么鬼地方,找了半天也没找到这个数字出现在哪里
(注:看别的师傅的题解说是可以静态把这个代码填回去,不太清楚怎么静态看的,以后再看看)
没办法只能调试一下.sys函数了
用windbg调.sys,真机加载调试环境里面的虚拟机
在encrypt函数里面下个断点,然后运行.exe文件,输入flag后如愿以偿的断下来了,至少出题人没在这里整选手一手
看一下0FFFFB0035F716000h的地址,发现了新的代码
把这些代码在.sys源文件里面随便找个地方patch回去,再改改之前的jmp地址,可以看到新的encrypt函数
好家伙完全不一样呢
根据改后的encrypt写出脚本
1 | #include<bits/stdc++.h> // C++头文件 |
然后把这套流程返回去
input ← base58 ← reverse ← xor “sxx”
1 | ACE_We1C0me!T0Z0Z5GamESecur1t9*CTf |