- ciscn_2019_es_2——wp
查看程序,32位程序,开启了NX。
拖入IDA反汇编。
Main主函数:
Hack函数:存在system函数,但不能直接得到flag。
Vul函数:
发现s距离ebp为0x28个字节,而read函数只能输入0x30个字节大小的数据,所以垃圾数据只能刚好填充到ret,而不能改变ret的值,因此不能栈溢出。现在这种情况应该用栈迁移,先构造rop链,写入system(/bin/sh),然后再通过栈迁移到我们写入的地方,最后getshell。所以我们需要解决的问题有:1.知道我们写入数据的地址,2.构造rop链。
第一个问题,我们写入数据的地址即参数s在栈上的地址=ebp-偏移量。(1).获得ebp指针的地址:vul函数刚好有两次输入和printf输出,可以通过第一次输入输出获得ebp地址(printf函数在输出时遇到’\0’会停止,那么我们可以将s参数填满,这样就没法在尾部添上’\0’)。(2)偏移量由pwndbg调试出为0x38(我还没搞明白pwndbg)。
第二个问题,构造payload。这里用leave_ret(leave_ret的地址随便找一个就可以)来进行栈迁移。
第一个’aaaa’随便输,这里是因为用leave_ret进行迁移时esp会+4字节。然后输入system函数的地址,再后面的’aaaa’为system的返回地址。然后p32(ebp_addr-0x28)+’/bin/sh\x00’)即跳到ebp-0x28的地址上写入’/bin/sh\x00’。再将s参数的0x28空间补齐,然后在ebp_addr的地址上写为参数s的地址即ebp_addr-0x38,最后加上leave_ret的地址。
栈迁移
leave
//move esp ebp 将ebp指向的地址给esp
//pop ebp 将esp指向的地址存放的值赋值给ebp(然后esp+4)
ret
//pop eip 将esp指向的地址存放的值赋值给eip
栈迁移的过程(萌新自己作图可能有错的地方)
最终的exp
萌新的·第一篇小水文。