天天看點

how2heap(5):tcache_poisoning 2.31tcache_poisoning 2.31

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,其位址如下:

how2heap(5):tcache_poisoning 2.31tcache_poisoning 2.31

接下來在第28行下斷點,申請兩個0x90(data部分為0x80)大小的堆塊chunk_a和chunk_b:

how2heap(5):tcache_poisoning 2.31tcache_poisoning 2.31

34行下斷點,先釋放chunk_a在釋放chunk_b:

how2heap(5):tcache_poisoning 2.31tcache_poisoning 2.31

37行下斷點,将chunk_b的位置修改成stack_var的位址

how2heap(5):tcache_poisoning 2.31tcache_poisoning 2.31

接下來在40行下斷點,重新申請一個0x90大小的堆塊,将bin中的chunk_b申請出來,由于chunk_b的fd指針指向的是stack_var,是以在bin中的表現形式為chunk_b --> stack_var。是以當chunk_b被啟用後,挂在tcache bin頭部的堆塊就變成了stack_var:

how2heap(5):tcache_poisoning 2.31tcache_poisoning 2.31

最後在44行下斷點,申請一個0x90大小的堆塊chunk_c,這個時候由于tcache bin的頭部為stack_var,并且stack_var挂在的0x90這串連結清單中,是以stack_var就被作為一個堆塊啟用了:

how2heap(5):tcache_poisoning 2.31tcache_poisoning 2.31

總結

  • 比較基礎的修改堆塊fd指針的操作
  • 如果想要利用該技巧,需要能夠對釋放堆塊進行寫操作,那麼就說明釋放之後堆塊的malloc指針沒有被清空
how2heap(5):tcache_poisoning 2.31tcache_poisoning 2.31