今天打算写点题,没得指导下写题才能清楚知道自己水平orz
平台:
babystack
先看看保护
1 | checksec babystack |
然后ida打开分析。
程序流程很简单,就是对给定的缓冲区进行输入和输出。然后有栈溢出漏洞。
1 | __int64 __fastcall main(__int64 a1, char **a2, char **a3) |
很显然,缓冲区只有0x90大小,但是可以输入0x100个字节,而我一开始脑子不清醒,以为只能溢出0x10个字节。。。再考虑了构造fake frame无果(不知道可不可以。。。没想出来orz)。然后发现这好像不止0x10个字节= =
知道溢出字节足够的情况下确实就很简单了,大致思路如下:
- 由于程序开了canary,所以要先泄露canary
- 覆盖返回地址到puts函数上,泄露库函数的地址,然后计算one gadget的地址
- 程序再次执行,将返回地址修改成one gadget地址
在写的过程中,由于选择了功能后是直接输入,输入是由read函数完成的,就会导致下一次的输入会输入到上一次输入的缓冲区里,这样就导致输入乱套orz。解决办法比如在第一次输入以后sleep(1),这样就能隔开,或者在输入选择的时候,用\x00字节将缓冲区填满。这两个方式怎么选。。。那当然是我全都要orz
还有就是在泄露库函数的时候,由于程序是64位的,所以前6个参数是通过寄存器传递的(在这里调试好久,太菜了orz),可以借助ROPgadget找到合适的指令来完成修改寄存器值
1 | ROPgadget --binary babystack --only 'pop|ret' |
0x400a93刚好就合适。
exp如下:
1 | #!/usr/bin/env python |
mary_morton
先看保护
1 | checksec mary_morton |
这个题目就很善良2333可以选择两种漏洞,一个是栈溢出,一个是格式化字符串。而且还给了获取flag的函数
1 | int target_4008DA() |
程序利用思路也比较直白:
- 由于程序开了canary保护,通过格式化字符串漏洞,可以泄露canary的值
- 得到canary后,直接通过栈溢出,将返回地址该成target函数地址
这个也没什么坑,exp如下:
1 | #!/usr/bin/env python |
monkey
这个题,emmm由于命令行有os.system()
这个函数调用,所以直接get shell就可以了。。。
第一次做这种类型的pwn题,完全摸不着头脑orz