2022腾讯游戏安全技术竞赛初赛-题解
初赛题
这里有一个画了flag的小程序,可好像出了点问题,flag丢失了,需要把它找回来。
题目:
找回flag样例:
要求:
1、不得直接patch系统组件实现绘制(如:直接编写D3D代码绘制flag),只能对题目自身代码进行修改或调用。
2、找回的flag需要和预期图案(包括颜色)一致,如果绘制结果存在偏差会扣除一定分数。
3、赛后需要提交找回flag的截图和解题代码或文档进行评分。
题解:
首要思路:找到绘画的部分,看下黄色为什么不显示
拿到题目ida打开搜索WinMain,可以找到关键函数Drawing
然后可以看到
做了一个时间检测,应该是作图四秒后清空内存,这与直接打开exe得到的情况是一样的。这里可以直接把0XFA0 patch成 0xFFFFA0
然后看到关键函数Shell_Code
可以看到大段的D3D的code
下断点动调之后不难发现 在Drewing_main这个函数进行了绘制
1 |
|
可以发现这个里面只要是一个Switch在对一个opcode进行选择利用,类似于一个虚拟机,而v15是这个虚拟机的几个寄存器
看到dword_23A30421301里面的内容
十分标准的opcode,所以我们可以用python对dword_23A30421301进行简单的转换,变成可以运行的python脚本
1 |
|
然后看到case 4 的时候对regs进行了一个加密(这个也需要复现
1 |
|
拼接完后的结果可以运行出每次要用的 a,b,c,d
1 |
|
然后就是可以对着所给的预料的答案,可以猜到a是x坐标,b是y坐标
不难发现,前11个坐标有一些负数,而后面没有。所以猜测前11个坐标是没有显示的黄色的点(也就是要画的FLAG),后31个坐标是画出来的‘ACE’
那么刚好42个点,和预料一样。
根据黄色的旗帜有六个点是相同的x坐标,不难猜出我们的第一个点应该是(0x32,0x32),所以直接在绘画的时候patch掉这个点的坐标
发现并没有出现点,所以后两个数其实对前两个数有一个check的功能,不能简单的改坐标
后面两个数在经过多次尝试,并没有理解是什么,在偶然的一次测试中,将后两个数交换
发现已经出现了黄块,所以我们推测后两个数在负数的时候被交换了,同时修改前面的坐标就可以了
那么思路就出来了:直接重写需要的Shellcode就可以了
给出shellcode的exp
1 |
|
前面的几个坐标有误的点,手动修改一下就可以了。
我们直接重写shellcode,并且写回到shellcode相应的地址处,通过ida的python执行之后
1 |
|
在apply一下patch掉的内容,就可以得到修正后的程序了
结果:
小记
这次还是顺利地晋级了决赛,但是决赛确实没办法进入前五拿到一个很好的名次,这次比赛还是比较有趣地。
题目附件地址:https://gslab.qq.com/html/competition/2022/race-pre.htm
希望能在鹅厂和你们相遇(虽然想去网易
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!