Title : W32dsm v8.93漏洞可利用性分析 Author : XCyber e-mail : [email protected] Date : 2005-01-28 最近的W32dsm v8.93漏洞: "The program uses the wsprintf() function to copy the name of the imported/exported functions of the analyzed file into a buffer of only 256 bytes, with the possibility for an attacker to execute malicious code." http://marc.theaimsgroup.com/?l=bugtraq&m=110661194108205&w=2 验证了一下,W32dsm处理导入函数时确实存在栈溢出漏洞,但是很长的导入函数名会造成PE文件无效,所以用作Anti-W32dsm可能性不大。仔细 看看漏洞说明"imported/exported functions...",如果导出函数也有同样漏洞那就...嘻嘻...因为很长的导出函数名不会导致PE文件无效, 而且一般人也不会注意一个.exe文件的导出表,所以有利用价值。 废话少说,先分析一下W32dsm对导入/导出函数的处理。 W32dsm对导入函数处理的分析: 0045D805 |> \6A 00 ||push 0 ; /Origin = FILE_BEGIN 0045D807 |. 6A 00 ||push 0 ; |pOffsetHi = NULL 0045D809 |. 8B45 E0 ||mov eax,dword ptr ss:[ebp-20] ; | 0045D80C |. 8B55 EC ||mov edx,dword ptr ss:[ebp-14] ; | 0045D80F |. 03C2 ||add eax,edx ; | 0045D811 |. 8B4D FC ||mov ecx,dword ptr ss:[ebp-4] ; | 0045D814 |. 2BC1 ||sub eax,ecx ; | 0045D816 |. 50 ||push eax ; |OffsetLo 0045D817 |. FFB3 12596000 ||push dword ptr ds:[ebx+605912] ; |hFile 0045D81D |. E8 1E130500 ||call W32dsm8_.004AEB40 ; \SetFilePointer 0045D822 |. 6A 00 ||push 0 ; /pOverlapped = NULL 0045D824 |. 8D45 F4 ||lea eax,dword ptr ss:[ebp-C] ; | 0045D827 |. 50 ||push eax ; |pBytesRead 0045D828 |. 6A 02 ||push 2 ; |BytesToRead = 2 0045D82A |. 69D6 CEEA0200 ||imul edx,esi,2EACE ; | 0045D830 |. 03D3 ||add edx,ebx ; | 0045D832 |. 6BCF 5B ||imul ecx,edi,5B ; | 0045D835 |. 03D1 ||add edx,ecx ; | 0045D837 |. 81C2 F26A1700 ||add edx,176AF2 ; | 0045D83D |. 52 ||push edx ; |Buffer 0045D83E |. FFB3 12596000 ||push dword ptr ds:[ebx+605912] ; |hFile 0045D844 |. E8 CD120500 ||call W32dsm8_.004AEB16 ; \ReadFile 【1】:读入导入函数字符串的偏移 0045D849 |. 6A 00 ||push 0 ; /Origin = FILE_BEGIN 0045D84B |. 6A 00 ||push 0 ; |pOffsetHi = NULL 0045D84D |. 8B45 E0 ||mov eax,dword ptr ss:[ebp-20] ; | 0045D850 |. 8B55 EC ||mov edx,dword ptr ss:[ebp-14] ; | 0045D853 |. 03C2 ||add eax,edx ; | 0045D855 |. 8B4D FC ||mov ecx,dword ptr ss:[ebp-4] ; | 0045D858 |. 2BC1 ||sub eax,ecx ; | 0045D85A |. 83C0 02 ||add eax,2 ; | 0045D85D |. 50 ||push eax ; |OffsetLo 0045D85E |. FFB3 12596000 ||push dword ptr ds:[ebx+605912] ; |hFile 0045D864 |. E8 D7120500 ||call W32dsm8_.004AEB40 ; \SetFilePointer 0045D869 |. 6A 00 ||push 0 ; /pOverlapped = NULL 0045D86B |. 8D45 F4 ||lea eax,dword ptr ss:[ebp-C] ; | 0045D86E |. 50 ||push eax ; |pBytesRead 0045D86F |. 68 2C010000 ||push 12C ; |BytesToRead = 12C (300.) 0045D874 |. FFB3 A5726000 ||push dword ptr ds:[ebx+6072A5] ; |Buffer 0045D87A |. FFB3 12596000 ||push dword ptr ds:[ebx+605912] ; |hFile 0045D880 |. E8 91120500 ||call W32dsm8_.004AEB16 ; \ReadFile 【2】:从【1】得到的偏移开始,读入12C字节。注意是12c字节! 0045D885 |. FFB3 A5726000 ||push dword ptr ds:[ebx+6072A5] ; /String2 0045D88B |. 8D93 2B0A6400 ||lea edx,dword ptr ds:[ebx+640A2B] ; | 0045D891 |. 52 ||push edx ; |String1 0045D892 |. E8 C3130500 ||call W32dsm8_.004AEC5A ; \lstrcpyA ... 0045D8C8 |> 8D83 2B0A6400 ||lea eax,dword ptr ds:[ebx+640A2B] 0045D8CE |. 50 ||push eax ; /<%s> 0045D8CF |. 68 18384C00 ||push W32dsm8_.004C3818 ; |Format = "%s" 0045D8D4 |. 8D95 04FFFFFF ||lea edx,dword ptr ss:[ebp-FC] ; | 0045D8DA |. 52 ||push edx ; |s 0045D8DB |. E8 A0170500 ||call W32dsm8_.004AF080 ; \wsprintfA ★ 注意wsprintfA函数的第一个参数,[ebp-F4],这是函数名字符串开始覆盖的地方,由于读入字符串最大是12C > FC,所以只要导入函数名 足够长就会产生栈溢出。 W32dsm对导出函数处理的分析: 0045DD72 |> /6A 00 /push 0 ; /Origin = FILE_BEGIN 0045DD74 |. |6A 00 |push 0 ; |pOffsetHi = NULL 0045DD76 |. |8B45 FC |mov eax,dword ptr ss:[ebp-4] ; | 0045DD79 |. |03C7 |add eax,edi ; | 0045DD7B |. |50 |push eax ; |OffsetLo 0045DD7C |. |FFB3 12596000 |push dword ptr ds:[ebx+605912] ; |hFile 0045DD82 |. |E8 B90D0500 |call W32dsm8_.004AEB40 ; \SetFilePointer 0045DD87 |. |6A 00 |push 0 ; /pOverlapped = NULL 0045DD89 |. |8D55 E4 |lea edx,dword ptr ss:[ebp-1C] ; | 0045DD8C |. |52 |push edx ; |pBytesRead 0045DD8D |. |6A 04 |push 4 ; |BytesToRead = 4 0045DD8F |. |8D4D F0 |lea ecx,dword ptr ss:[ebp-10] ; | 0045DD92 |. |51 |push ecx ; |Buffer = 006DBF1C 0045DD93 |. |FFB3 12596000 |push dword ptr ds:[ebx+605912] ; |hFile 0045DD99 |. |E8 780D0500 |call W32dsm8_.004AEB16 ; \ReadFile 【3】:读入导出函数字符串的偏移 0045DD9E |. |8B45 E4 |mov eax,dword ptr ss:[ebp-1C] 0045DDA1 |. |85C0 |test eax,eax 0045DDA3 |. |75 07 |jnz short W32dsm8_.0045DDAC 0045DDA5 |. |33C0 |xor eax,eax 0045DDA7 |. |E9 BB020000 |jmp W32dsm8_.0045E067 0045DDAC |> |83C7 04 |add edi,4 0045DDAF |. |8B93 DC376F00 |mov edx,dword ptr ds:[ebx+6F37DC] 0045DDB5 |. |2955 F0 |sub dword ptr ss:[ebp-10],edx 0045DDB8 |. |8B8B D8376F00 |mov ecx,dword ptr ds:[ebx+6F37D8] 0045DDBE |. |014D F0 |add dword ptr ss:[ebp-10],ecx 0045DDC1 |. |6A 00 |push 0 ; /Origin = FILE_BEGIN 0045DDC3 |. |6A 00 |push 0 ; |pOffsetHi = NULL 0045DDC5 |. |FF75 F0 |push dword ptr ss:[ebp-10] ; |OffsetLo 0045DDC8 |. |FFB3 12596000 |push dword ptr ds:[ebx+605912] ; |hFile 0045DDCE |. |E8 6D0D0500 |call W32dsm8_.004AEB40 ; \SetFilePointer 0045DDD3 |. |6A 00 |push 0 ; /pOverlapped = NULL 0045DDD5 |. |8D45 E4 |lea eax,dword ptr ss:[ebp-1C] ; | 0045DDD8 |. |50 |push eax ; |pBytesRead 0045DDD9 |. |6A 4F |push 4F ; |BytesToRead = 4F (79.) 0045DDDB |. |8D55 8C |lea edx,dword ptr ss:[ebp-74] ; | 0045DDDE |. |52 |push edx ; |Buffer 0045DDDF |. |FFB3 12596000 |push dword ptr ds:[ebx+605912] ; |hFile 0045DDE5 |. |E8 2C0D0500 |call W32dsm8_.004AEB16 ; \ReadFile 【4】:从【3】得到的偏移开始,读入4F字节 0045DDEA |. |8B4D E4 |mov ecx,dword ptr ss:[ebp-1C] 0045DDED |. |85C9 |test ecx,ecx 0045DDEF |. |75 07 |jnz short W32dsm8_.0045DDF8 0045DDF1 |. |33C0 |xor eax,eax 0045DDF3 |. |E9 6F020000 |jmp W32dsm8_.0045E067 0045DDF8 |> |C645 DB 00 |mov byte ptr ss:[ebp-25],0 0045DDFC |. |0FBE55 8C |movsx edx,byte ptr ss:[ebp-74] 0045DE00 |. |83FA 40 |cmp edx,40 0045DE03 |. |75 22 |jnz short W32dsm8_.0045DE27 0045DE05 |. |8B8B 74116F00 |mov ecx,dword ptr ds:[ebx+6F1174] 0045DE0B |. |85C9 |test ecx,ecx 0045DE0D |. |74 18 |je short W32dsm8_.0045DE27 0045DE0F |. |6A 01 |push 1 0045DE11 |. |8D85 3CFFFFFF |lea eax,dword ptr ss:[ebp-C4] 0045DE17 |. |50 |push eax 0045DE18 |. |8D55 8C |lea edx,dword ptr ss:[ebp-74] 0045DE1B |. |52 |push edx 0045DE1C |. |53 |push ebx 0045DE1D |. |E8 6F2C0000 |call W32dsm8_.00460A91 0045DE22 |. |83C4 10 |add esp,10 0045DE25 |. |EB 18 |jmp short W32dsm8_.0045DE3F 0045DE27 |> |8D4D 8C |lea ecx,dword ptr ss:[ebp-74] 0045DE2A |. |51 |push ecx ; /<%s> 0045DE2B |. |68 60384C00 |push W32dsm8_.004C3860 ; |Format = "%s" 0045DE30 |. |8D85 3CFFFFFF |lea eax,dword ptr ss:[ebp-C4] ; | 0045DE36 |. |50 |push eax ; |s 0045DE37 |. |E8 44120500 |call W32dsm8_.004AF080 ; \wsprintfA ★ 注意wsprintfA函数的第一个参数,[ebp-C4],这是函数名字符串开始覆盖的地方,由于函数名最大只读入4F,无法覆盖到ebp-C4, 所以无法产生栈溢出。 结论:W32dsm只是在处理导入函数时有可能导致栈溢出,由于windows loader会对导入函数进行有效性判断,所以利用该漏洞设计 Anti-W32dsm可能不大。 水平有限,不对之处请指正。

|