链接:http://pan.baidu.com/s/1hshVzvu 密码:sd4d
非常非常坑爹的一道题目,看似非常简单,实则有很深的套路
我会综合写出三种方法,包括 结合ascii码值范围的爆破,动态调试解法,静态调试解法
(感谢我xx学长的支持和某位网友的writeup)
1.首先拿到该程序,丢进ida会发现这是个linux程序,程序主体看起来也很简单,在ubuntu下也能正常跑起来
2.结合汇编语言,对程序可以做一个大致的分析,第二个if的判断是分别将输入的字符串的每一位和v4/v0(32位)的第一,二,三,四个字节做异或并将结果和0x80498f0起始处的字符串做比较,只有16位全相等时才会输出正确
3.瞄了一眼,v4和v0的值发现和输入字符串无关,应该是个固定值,而v4=v0对应的汇编语言是mov edx,eax,所以正常的想法是用gdb在0x08048416处下断点
4.如果你的思路和我一样,那么恭喜你入套了,不过还是先这样走完
5.用gdb下断点后可以得到eax的值,如图为:0xd90c5525
6.于是我尝试写了这样一个代码:
7.当然你得到的只会是乱码。。。
8.好吧,现在是早上01:43:32我就不废话了,我还要睡觉呢!错误的原因在于第一个if语句是对text段的读操作,并对读到的值进行一系列的运算操作,从main函数一直读到0x0804872A,当然也会读到你下断点的地方,而据网上资料所讲b *0x 操作是将相应处内存改为0xcc,这样一来你得到的eax和edx的值就会不对,那该怎么办呢
解法一:动态调试的方法
这期间我犯了很多很多的错误
错误一:我分别用了 b *0x08048418 if $eip==0x08048146//r 和b *0x080483fa//r//b *08048418 if $edx==$dbx这两种方法
错误的原因在于理解错了breakpoint指令的意思 我以为b if 是时时监控 条件成立就下断点 实际上是运行到断点处才判断。。
如果是犯同样错误的人自己理解吧,这样是不行的
错误二:watch $eip==0x08048418 也是错的 具体原因我还没有查
直接写出最终解法吧:内存访问监控 涉及到的gdb指令是awatch(awatch是读写断点,内存被读或着写时都会断。而rwatch是读时断,watch是写时断。)
我这里用到的是awatch
指令为awatch *0x08048148//r//info b//d 1//s//s//...//b *0x08048148//c
这样一开就能得到正确的eax值,再结合最开始写的脚本就可以得到flag
待续。。。