Fastbin Attack 2
glibc2.23 源碼 https://ftp.gnu.org/gnu/glibc/glibc-2.23.tar.gz
建議搭配食用,效果更好
hourse of spirit
該技術的核心在于在目標位置處偽造 fastbin chunk,并將其釋放,從而達到分配指定地址的 chunk 的目的。
要想構造 fastbin fake chunk,并且將其釋放時,可以將其放入到對應的 fastbin 鏈表中,需要繞過一些必要的檢測,即
- fake chunk 的 ISMMAP 位不能為 1,因為 free 時,如果是 mmap 的 chunk,會單獨處理。
- fake chunk 地址需要對齊, MALLOC_ALIGN_MASK
- fake chunk 的 size 大小需要滿足對應的 fastbin 的需求,同時也得對齊。
- fake chunk 的 next chunk 的大小不能小于
2 * SIZE_SZ,同時也不能大于av->system_mem。 - fake chunk 對應的 fastbin 鏈表頭部不能是該 fake chunk,即不能構成 double free 的情況。
#include <stdio.h>
#include <stdlib.h>
int main() {
malloc(1);
fprintf(stderr, "We will overwrite a pointer to point to a fake 'fastbin' region. This region contains two chunks.\n");
unsigned long long *a, *b;
unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));
fprintf(stderr, "The first one: %p\n", &fake_chunks[0]);
fprintf(stderr, "The second one: %p\n", &fake_chunks[4]);
fake_chunks[1] = 0x20; // the size
fake_chunks[5] = 0x1234; // nextsize
fake_chunks[2] = 0x4141414141414141LL;
fake_chunks[6] = 0x4141414141414141LL;
fprintf(stderr, "Overwritting our pointer with the address of the fake region inside the fake first chunk, %p.\n", &fake_chunks[0]);
a = &fake_chunks[2];
fprintf(stderr, "Freeing the overwritten pointer.\n");
free(a);
fprintf(stderr, "Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunks[0], &fake_chunks[2]);
b = malloc(0x10);
fprintf(stderr, "malloc(0x10): %p\n", b);
b[0] = 0x4242424242424242LL;
}
gcc -g house_of_spirit.c

可以看出,想要使用該技術分配 chunk 到指定地址,其實并不需要修改指定地址的任何內容,關鍵是要能夠修改指定地址的前后的內容使其可以繞過對應的檢測。
house-of-spirit 是一種 fastbins 攻擊方法,通過構造 fake chunk,然后將其 free 掉,就可以在下一次 malloc 時返回 fake chunk 的地址,即任意我們可控的區域。house-of-spirit 是一種通過堆的 fast bin 機制來輔助棧溢出的方法,一般的棧溢出漏洞的利用都希望能夠覆蓋函數的返回地址以控制 EIP 來劫持控制流,但如果棧溢出的長度無法覆蓋返回地址,同時卻可以覆蓋棧上的一個即將被 free 的堆指針,此時可以將這個指針改寫為棧上的地址并在相應位置構造一個 fast bin 塊的元數據,接著在 free 操作時,這個棧上的堆塊被放到 fast bin 中,下一次 malloc 對應的大小時,由于 fast bin 的先進后出機制,這個棧上的堆塊被返回給用戶,再次寫入時就可能造成返回地址的改寫。所以利用的第一步不是去控制一個 chunk,而是控制傳給 free 函數的指針,將其指向一個 fake chunk。所以 fake chunk 的偽造是關鍵。
Alloc to Stack
該技術的核心點在于劫持 fastbin 鏈表中 chunk 的 fd 指針,把 fd 指針指向我們想要分配的棧上,從而實現控制棧中的一些關鍵數據,比如返回地址等。
我們所介紹的問題的本質都在于 fastbin 鏈表的特性:當前 chunk 的 fd 指針指向下一個 chunk。
typedef struct _chunk
{
long long pre_size;
long long size;
long long fd;
long long bk;
} CHUNK,*PCHUNK;
int main(void)
{
CHUNK stack_chunk;
void *chunk1;
void *chunk_a;
stack_chunk.size=0x21;
chunk1=malloc(0x10);
free(chunk1);
*(long long *)chunk1=&stack_chunk;
malloc(0x10);
chunk_a=malloc(0x10);
return 0;
}
通過該技術我們可以把 fastbin chunk 分配到棧中,從而控制返回地址等關鍵數據。要實現這一點我們需要劫持 fastbin 中 chunk 的 fd 域,把它指到棧上,當然同時需要棧上存在有滿足條件的 size 值。
chunk_a=malloc(0x10);返回棧上的指針
Arbitrary Alloc
顧名思義,這里的套路其實與 Alloc to stack 是完全相同的,唯一的區別是分配的目標不再是棧中。事實上只要滿足目標地址存在合法的 size 域(這個 size 域是構造的,還是自然存在的都無妨),我們可以把 chunk 分配到任意的可寫內存中,比如 bss、heap、data、stack 等等。并且該技術在 CTF 中用地更加頻繁。我們可以利用字節錯位等方法來繞過 size 域的檢驗,實現任意地址分配 chunk,最后的效果也就相當于任意地址寫任意值。
參考