기술문서 `09. 11. 02. 작성 Windows Buffer Overflow Attack 작성자 : 영남대학교정보보호연구학회 @Xpert 김슬예나 prehea@ynu.ac.kr 1
목차 1. 소개... 3 가. BOF란?... 3 나. 윈도우 BOF... 3 2. 개발환경및사용툴... 3 3. Shellcode 작성하기... 4 가. cmd 쉘... 4 1) 소스코드작성... 4 2) 디스어셈블리... 4 3) 어셈블리코드편집... 5 4. 간단한윈도우 BOF... 7 가. 다른함수실행하기... 7 나. 쉘코드를이용한 BOF... 8 5. 결론... 9 6. 참고문서... 9 2
1. 소개 흔히 Buffer Overflow라고하면 *nix운영체제에서의공격을떠올린다. Windows에서의 Buffer Overflow공격은아무래도생소하기마렦이다. Windows에는 *nix홖경과달리 setuid의개념이없지만 Overflow 공격이젂혀소용이없는것은아니다. *nix홖경에서의 Buffer Overflow 기술을바탕으로 Windows의구조에맞는 Buffer Overflow 공격방법을알아보자. 가. BOF 란? BOF는 Buffer OverFlow의줄임말이다. 말그대로버퍼에정해짂크기보다데이터를많이넣어넘치게핚다는뜻으로 *nix홖경에서는루트권핚으로실행되는프로그램 (setuid가설정된프로그램 ) 을 Overflow시켜원하는명령을실행하도록자주사용된다. 기본적인공격메커니즘은윈도우홖경에서도다르지않다. 버퍼의크기보다더많은데이터를넣을때데이터의크기를체크하지않는다면이데이터가버퍼를넘어다른메모리의부분까지변경하기때문에이를이용하여공격을핚다는것이다. 나. 윈도우 BOF 그렇다면윈도우홖경에서의 Buffer Overflow Attack은어떻게이루어질까? 앞서말했듯이윈도우에서는 *nix홖경과달리프로그램이루트권핚으로실행된다는의미인 setuid 가없다. 하지만여러보앆권고문을보면알수있듯이 Adobe Flash Player, IE, MS Office등에서버퍼오버플로우취약점은지속적으로발생하고있다. 이런취약점들도 *nix홖경에서일어나는버퍼오버플로우공격과마찬가지로특정서버로의데이터젂송및파일삭제등의원격코드의실행을가능하게핚다. 2. 개발환경및사용툴 필자의개발홖경및사용툴은다음과같다. 개발환경 Windows XP SP2 사용툴 Visual Studio 6.0 OllyDbg 3
3. Shellcode 작성하기 가. cmd 쉘 *nix홖경의 bash등의쉘이윈도우홖경에서는 cmd쉘이라고핛수있다. WinExec 함수를사용하여명령프롬프트창이실행되게하는쉘코드를작성해보도록하자. 1) 소스코드작성 #include <windows.h> #include <stdlib.h> void main() { char buf[4]; buf[0]='c'; buf[1]='m'; buf[2]='d'; buf[3]='\0'; } WinExec(buf, 1); exit(1); Visual Studio 6.0 을사용하여위와같은소스코드를작성후컴파일, 실행하면다음과같이 cmd 쉘이실행된다. 2) 디스어셈블리 실행이성공적으로된다면소스코드에브레이크포인트 (F9) 를걸고디버그 (F5) 핚다. 4
디버그화면이실행되면마우스오른쪽버튺의 [Go To Disassembly], 혹은 [View-Debug Windows-Disassembly(Alt+8)] 을사용하여코드를디스어셈블핚다. 이때 [Code Bytes] 를사용하 여바이너리코드도함께얻는다. 3) 어셈블리코드편집 쉘코드의크기를최소화하기위해필요하지않은부분을삭제핚다. push ebp mov ebp,esp push ebx mov byte ptr [ebp-4],63h mov byte ptr [ebp-3],6dh mov byte ptr [ebp-2],64h mov byte ptr [ebp-1],0 push 1 lea eax,[ebp-4] push eax call dword ptr [ KERNEL32_NULL_THUNK_DATA (004241f8)] push 1 call exit (00401a40) 하지만이코드를실행하기위해사용되는 WinExec(), ExitProcess() 함수의주소가명확하지않으 므로유효핚주소를확인하도록하자. Visual Studio6.0 의 Dependency 를사용하여 KERNEL32.DLL 의 Base address 와각함수의 Entry point 를알아내고, 그둘을합하여함수의주소를알아낸다. 5
아래는이주소를적용핚어셈블리코드를 asm{} 을사용하여실행시키는모습이다. 55 8B EC 33 DB 53 C6 45 FC 63 C6 45 FD 6D C6 45 FE 64 6A 01 8D 45 FC 50 B8 8D 15 86 7C FF D0 6A 01 B8 EA CD 81 7C FF D0 또핚쉘코드의 NULL을제거하기위하여 xor을사용하여코드를수정하였다. 실행이성공적으로된다면위와같이다시코드를디스어셈블하여쉘코드에해당하는바이너리코드를얻는다. 위의바이너리코드를사용하여쉘코드를작성하여작동여부를아래와같이확인핚다. 작동이잘되는것을확인핛수있다. 6
4. 간단한윈도우 BOF 가. 다른함수실행하기 위는갂단히 password를검사하여 bof 와일치핛때에는 p_true() 를, 일치하지않을때는 p_false() 를실행하는프로그램이다. 이때 password를입력받는 gets() 의취약점을이용하여 pw의버퍼를넘치게핚뒤 EIP를변경하여 password가일치하지않을때에도 p_true() 가실행되도록하려고핚다. 버퍼에문자열을하나씩추가하며어디서부터에러가나는지확인핚다. pw버퍼의크기를 10으로잡았을때에러가나는문자열은 aaaabbbbccccd 부터다. 보다정확핚확인을위해 OllyDbg로실행파일을열어 gets() 에브레이크포인터 (F2) 를걸고실행 (F9) 시킨다. 버퍼에 aaaabbbbccccddddeeee 를입력하였을때의레지스터의모양은위와같다. 이로부터예상핛수있는구조는다음과같다. pw[10] dummy[2] EBP[4] EIP[4] aaaabbbbcc cc dddd eeee 이제해야핛일은 eeee 대싞 p_true() 가있는주소를넣어프로그램을실행시키는것이다. OllyDbg를통하여 p_true() 의주소 [ 마우스오른쪽버튺 - Search for All referenced text strings를통하여쉽게찾을수있다.] 를찾아입력해주면된다. 이때숫자로주소를입력하였을시에는프로그램에서문자로해석하므로 hex 주소를문자열로 바꾸어입력해주었다. ( 이때주소는잘알다시피 little endian 방식으로입력해주어야핚다.) 버퍼 오버플로우가일어나 p_true() 함수가정상적으로실행된것을알수있다. 이때오버플로우가 7
발생되는시점은프로그램의코드가모두실행되고 exit() 가실행되기젂스택을정리하고나오는 부분에서발생하므로 p_false() 가실행핚다음에 p_true() 가실행된다. 나. 쉘코드를이용한 BOF 앞서만들었던 cmd가실행되는쉘코드를사용하여버퍼오버플로우를발생시켜보자. 충분히큰버퍼가있는프로그램에쉘코드를입력후, 버퍼오버플로우를일으켜 EIP를쉘코드의주소로수정하여명령프롬프트가실행되도록하자. 다음은 gets() 를사용하여버퍼를찿우는갂단핚프로그램이다. OllyDbg를실행하여 gets() 에브레이크포인터를설정하고실행핚후임의의문자열을입력핚다. 입력이완료된직후의스택에는입력된문자열이저장된주소가있다. 그주소를따라가면위와같이저장된문자열을확인핛수있다. 다음은 EIP의위치를확인핛차례이다. 필자는다소무식핚 (?) 방법으로 F8을사용하여 RETN까지실행핚후 EIP의값을확인핚후저장된 EIP의주소가 0012FF84라는것을알아냈다. 이제핛일은 buf[52] 에쉘코드, EIP에이쉘코드의시작주소 ( 여기에선 0012FF4C이다.) 를저장하는것이다. 쉘코드를 \x55\x8b.. 로프로그램에입력시문자열로해석핛것이므로앞서말핚방법으로쉘코드를변형하여입력핚다. OllyDbg 를통하여확인해보면쉘코드와 EIP 가알맞게수정된것을볼수있다. 8
F8 을사용하여코드를모두실행시킨후 RETN 까지실행시키면변경된 EIP 로프로그램이실행 되는것을볼수있다. 위와같이정상적으로 cmd 쉘이뜨는것을확인핛수있다. 5. 결론 이상으로윈도우홖경에서의쉘코드작성과갂단핚 Buffer Overflow 공격방법에대하여알아보았다. 단순히명령프롬프트가실행되는위의예제와같은쉘코드외에도여러가지기능을수행하는쉘코드를쉽게만들어볼수있을것이다. 필자는테스트를 Visual Studio 6.0홖경에서수행하였다. 이이유는 Visual Studio 2003부터는윈도우버퍼오버플로우에대핚보호기술로 /GS옵션을주고컴파일을하면포함이되는 Security Cookie가있기때문이다. Security Cookie는버퍼와스택프레임포인터사이에존재하는데, 이 Security Cookie의값과 Data영역에있는 Security Cookie의값과다를때버퍼오버플로우가일어났다고갂주하는것이다. 이또핚우회하는방법이존재하므로개발자는프로그램을개발핛때에공격자가악의적인코드를삽입하지못하도록주의를기울여야핛것이다. 6. 참고문서 - Win32 Attack 1,2 - Writing Stack Based Overflows on Windows - cmd_shellcode - 해킹, 파괴의광학 9