writeup for whctf2017 re

writeup for whctf re部分

花了一天时间试了下whctf的水,比赛第一天做了两个题,后面的题连是啥也不知道,自己还是太菜,后来比赛快结束的时候去看了下题,发现又出了一道题,esayhook,当时太忙,没做,抽空逆了下这道题
算上这题的话,总共三个题的writeup,一直没写wp,写这个writeup算是对这个比赛做一点总结吧,顺便把坑填上,当然也给奋斗在二进制这条道路的小伙伴们一些帮助吧,虽然网上早已有writeup,但是我觉得还是很有必要分享下我自己的逆向思路,如果有朋友发现有错误遗漏之处,或者说是有更好的思路,咱们可以相互之间交流讨论下。

Crackme

直接OD,先试着输入123456789
然后弹出一个对话框,一看就是messagebox,然后查看调用模块,Messagebox,发现有两个,两个都试着调试,然后你就会调试到下面的地方:

这里其实是先比较flag的长度,33.

在调试过程中,直接把它nop掉往后调,你就会发现,伪输入会一个一个的与flag比较,动态调的话,flag直接就出来!

re2 BabyRE

  • 试运行

和常规的re一样,一个叫你输入flag然后判断flag的正误。

  • 静态分析

因为个人不擅长使用Linux所以很少使用Linux做re题,我看到网上大佬是用gdb动态调试然后在适当的地方下断点做出来的。
在这里小膜一下,那些大师傅们!所以我用Ida64打开看了下。

graph模式:(如图)



习惯看汇编就直接看,读的多了,能力就上升得很快了。
我在做题的时候采用边f5边用汇编看

ps:注意下面的小红字sp analysis failed
出现这种情况就是出题人使用了特殊的一些指令或者代码使得ida分析时堆栈不平衡了,以至于Ida不认为它是一个函数。所以使用f5的时候,会出现错误提示。

怎么解决这种问题?

只要手动使堆栈平衡就行

1.按下空格转换到文本模式,拖到loc40062这个函数的附近如图:
2.打开ida上方的Option->General->将stack pointer 给勾上如图:

勾上后就会显示sp的值如图:

注意我划线的地方,一个call之后的,栈指针就显示得很大了。
这就是为什么Ida不能自动识别的原因。
怎么办呢?

如果想修改某条指令的sp值的话,将鼠标指向他的上一条指令,然后按alt+k修改栈指针。修改的是时候需要根据堆栈平衡原理来改变相应指令的堆栈指针的值。

修改好的如下:

然后就可以f5了,如图:

只能说有一点用,对新手友好一点而已,关键的地方还是要看汇编才能解决问题的。

关键的地方:

程序大致逻辑原理

将一个数据段的内容,一字节形式与0xc相与,然后这个数据段变化成代码,然后调用这个函数,这个函数的参数就是我们输入的flag,其实质就是在比较我们的flag。

  • 3写keygen

按我们之前的分析的话,得将那个数据段的内容分别与oxc想与,然后将处理后的内容作为一个函数调用,因此我们想写keygen的话必须把数据处理了来。

目前我知道的有两种方法:

-1.使用idapython(因为个人实在太菜,花了一个多小时看,还写不了,只能往后补坑了)

-2.使用winhex(这个是我无计可施的情况下,兔师傅告诉我的,感谢兔师傅,不然这题只能干瞪眼了)

使用winhex修改代码
在ida中找到相应的偏移地址,然后在winhex里面选中那一块,然后将其与oxc异或。就不细说了!
然后ida识别就行。

修改,识别之后如图:

EasyHook

1.试运行

没有什么特别的地方

2.IDA静态分析

由于之前分析了,后把文件给删了,逆向的注释都没有了,所以写的比较简洁。

先获得进程ID,然后打开对应的PID的进程获得句柄,然后,加载库文件,获得库文件中write函数的地址,然后将sub_401080-write函数的偏移地址-5传入 那个4010D0,然后修改当前进程中write函数的地址对应内存保护权限,然后调用writememory函数将传入的偏移地址的内容传送到write函数中,但是写入0个字节,所以根本没做什么实质性改变,然后调用write函数假装要些什么,实际上啥也没写,然后 401240这个函数 比较flag了,比较成功的话,就返回一,就验证成功了,网上的wp中都是用OD,调到那个函数里面去的,如果真的修改了,函数的内容,OD调试的话,难度还是很大的!