tcache_dup

oogu ㅣ 2023. 2. 1. 10:06

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

[그림 1-1]

Partial RELRO이고 PIE가 설정 안 되어있다. 따라서 GOT Overwrite가 가능하고, 코드, 데이터 섹션이 고정되어 있다.

 

코드를 보면 get_shell 함수가 존재한다. 따라서 특정 함수 got 값을 get_shell 주소로 바꾸고 함수를 실행하면 쉘이 실행이 될 것이다.

malloc과 free 함수가 존재하고 free 후 포인터를 초기화하지 않아 tcache duplication을 일으킬 수 있다.

tcache duplication을 하기 전 보호 기법이 적용되었는지 알아야 한다. -> 이것 때문에 삽질 엄청함... 리모트에서 확인을 먼저 하자.. 로컬에서 하니 당연히 보호 기법이 걸려있다..

[그림 1-2]

리모트에서 보호 기법이 적용되었는지 확인하기 위해 0번 index에 malloc 하고 3번 free를 해본다.

[그림 1-3]

프로그램이 계속 실행되는 걸 보니 보호 기법이 없는 걸 알 수 있다. 만약 있었다면 double free 어쩌고 문구 뜨면서 강제 종료가 되었을 것이다.

보호 기법이 없으므로 쉽게 tcache duplication이 가능하다.  -> 임의의 주소를 지정하고 쓰기가 가능하다.

[그림 1-4]

free_got 값을 get_shell 주소로 덮었다. 그 후 delete 함수를 호출해 free를 실행하면 get_shell 함수가 실행된다.

[그림 1-5]

성공!

 

사실 엄청 쉬운 문제인데 로컬에는 보호 기법이 걸려있다는 걸 인지하지 못하고 삽질을 엄청했다.. 

 

 

알게 된 점

1. tcache는 free를 하면 fd와 key 값이 들어가 총 16byte를 초기화하고 나머지 부분은 남겨둔다.

malloc으로 재할당시 key는 null로 초기화되고 나머지 부분은 남겨져있다.

'Dreamhack - pwnable' 카테고리의 다른 글

sint  (0) 2023.02.03
tcache_dup2  (0) 2023.02.01
tcache_poison  (0) 2023.01.30
uaf_overwrite  (0) 2023.01.28
ptmalloc2  (0) 2023.01.28