看雪ctf和游戏安全系列

看雪ctf与游戏安全系列

由于感觉自己练习的实在还是很少,打算找一些经典题目做做,目前选定就是历年的看雪ctf和游戏安全的题目,每天可以保持两道题目左右的进度,不说了,先上题。
第一题直接定位字符串就可以找到了

123

下面看下第二题,当时没做出来,现在再来做看看,无壳,直接放入ida分析

123

发现main函数不能f5,很快发现了原因,三个连续的call(不像是编译器生成的),中间没有参数传递或者清理,自然不能f5,只好对这个三个函数一个个看

123

这里输出了一些字符和提示,并且用scanf把输入读入v1里,然后继续看后面的两个sub,似乎是四个二元一次方程

123

123

这里的v0和v1都是相同的值,动调下看看,这里可以看到v0和v1是输入的前4位和4-8位(这里local1和loacl2可以看到),整理下方程,用z3求解尝试

123

123

z3果断的告诉你是没解的(当时做到这就放弃了),后来发现是真正的判断点不在这,通过栈溢出可以走到真正的判断处(栈溢出原理可以去ctfwiki上看看),先尝试下是否可以栈溢出,就先尝试下是否可以溢出到程序的O成功点也就是0040102f处,先看下超出多少会发生溢出吧

123

这里输入了12位,发现又进入了OEP,输入13或者更多位都会爆出异常

123

123

可以猜到输入的位数上限是12位,这里分配的应该是16h大小,(12位的参数加上4h的返回地址),这点从栈区分布上也可以看出来,我输入了11位发现栈中从上到下依旧是scanf的第一个参数,输入的(也就是第二个参数),然后是从左到右从上到下依旧是4,3,2,1,8,7,6,5,11,10,9位输入,再下面就是返回地址了,也就是说输入超出12位的部分都会覆盖到返回地址从而控制程序流程,想要把返回地址变成0040102f,也就是要构造的输入4,3,2,1位分别是ascii表示的00,40,10,2f,也就是@,^P和/,

123

发现直接走到了成功点,说明栈溢出可以成功到达,但是怎么才能找到key呢,emmm这里我想了好久,不知道哪里才是真正的判断点,后来知道正常程序中不会有一大串的不被ida识别的垃圾指令,

123

这段应该是加了花指令,具体这段做了什么跟一下就行了,直接溢出到00413131出,可以看到这一段在od里被识别成了数据,不管,在00413131下个断点,构造RA为413131后成功断在了这段数据上,使用hit跟踪可以粗略判断某些call是否被调用,使用run跟踪可以观察寄存器的值的变化,这里使用run跟踪

123

将这段数据选择并加入run跟踪,run trace窗口就可以看到一清二楚

123

这时就需要手动整理下有用的指令=.=(绿色字体我眼快看瞎了),可以看到一开始输入被分成了三组,eax以小端序保存了前四位,设为x,同理,ebx设为y,edx设为z。第一部分汇编为以下

sub eax,ebx
shl eax.0x2
add eax,ecx
add eax,edx
sub eax,0xeaf917e2

可以整理出方程(x-y)*4+x+z==0xeaf917e2,三个元必须有三个方程,首先可以找到第一个判断点是0x413420,为了拿到第二个方程,需要nop掉判断

123

nop掉之后成功走到第二处判断,老样子run追踪,判断下有用的汇编代码是

add eax,ecx //eax=x+0
sub eax,ebx //eax=x-y
mov ebx,eax 
shl eax,1   //(x-y)*2
add eax,ebx //(x-y)*2+x-y
add eax,ecx //(x-y)*2+x-y+x
mov ecx,eax
add eax,edx //(x-y)*2+x-y+x+z
sub eax,0xe8f598c8

可以列出第二个方程(x-y)3+x+z==0xe8f508c8,并且可以找到第二个判断点是0x413b03,老样子可以得到第三个方程,这里就不放了,方程是(x-y)3+x-z==0x0c0a3c68,然后就要再次使用神奇z3

123

输入的三组已经知道了,现在只需要每两位转成ascii就行了(别忘了注意小端序),得到flag是Just0For0Fun11A(11A为溢出地址)

123

下面继续看第三道,拖入peid,发现无壳,直接拖入ida分析,通过定位字符串“crack me”找到了主函数sub_434ef0,并且发现结果是由函数sub_42D9AB判断的

123

接着向上分析,其实理论上调试一下在memcmp下个断点直接去看参数就行了,但是这个cm的反调多到令人发指,有我见过的有我没见过的,虽说strongOD可以patch掉很多,但是还是很麻烦,下面是部分反调截图

123

123

还是静态分析逆算法吧,先看第一个对输入处理的函数sub_42D267,发现就是base64,并且接连调用了两次

123

然后就**一堆我看不懂的操作,算了还是动调吧(真香),过了几处反调,这里我给一个过了反调版本的crackme(其实只要patch三四处吧大概),然后就直接去看下ida里memcmp的地址

123

就可以顺利看到了memcmp的内容,反正这题目思路很简单,要么怼反调,要么逆算法

123

这一段就是memcmp的内容

123

后来看wp,听说这题有多解,看来还是得回头逆下算法,在进行两次base64操作之后又调用了两个函数进行操作

123

进去第一个看下,不动调下完全不知道这是摩尔斯编码函数=.=,我还是太菜了,下面就是一个sm3函数,之前只听说过国密4(国产des),后来查了下,才知道sm3是一种摘要算法,类似md5

123

下面看下sm3的流程,和md5十分相似(md5细节可以在我之前一篇post里找到),也是分成了3个部分,第一个部分是幻数的装载,也就是初始化,然后也是update和final,主要识别依旧是通过几个幻数,

123

最后一段函数可以看出来是迷宫函数,控制由108,122,113,112(ascii码),并且可以看到迷宫数组

123

总结下,sm3((base64(base64(str))),再加上迷宫,这题到这里差不多了,夜已深,睡啦