ciscn_2019_es_2
Ubuntu 18
checksec
1 | [*] '/home/zelas/Desktop/pwn/ciscn_2019_es_2/ciscn_2019_es_2' |
IDA
vul()
1 | int vul() |
可疑函数hack()
1 | int hack() |
//0x804854B
//system() 0x8048400
0x02
思路
发现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
0x03
exp
1 | from pwn import * |