Microsoft Office 的 wwlib 中的一个漏洞允许攻击者实现 以打开恶意软件的受害者的权限远程执行代码 RTF 文档。攻击者可以将此文件作为电子邮件附件(或 其他方式)。
Microsoft Word 是 Microsoft 附带的文字处理应用程序 办公室。根据默认安装,Microsoft Word 处理 RTF 格式 (RTF) 文档。这些文档主要由基于 7 位 ASCII 的 关键字组合在一起可以封装各种各样的丰富内容。
Microsoft Word 中的 RTF 解析器在以下情况下包含堆损坏漏洞
处理包含过多字体的字体表 (*\fonttbl*)
(*\F###*)
。处理字体时,字体id值(*\f*后面的数字)
由以下代码处理:
{% highlight asm %}
0d6cf0b6 0fbf0e movsx ecx,word ptr [esi] ; load base idx
0d6cf0b9 0fbf5602 movsx edx,word ptr [esi+2] ; load font idx
0d6cf0bd 8d1451 lea edx,[ecx+edx*2] ; multiply by ~3
0d6cf0c0 668b08 mov cx,word ptr [eax] ; load the codepage value
0d6cf0c3 66894c5604 mov word ptr [esi+edx*2+4],cx ; write the code page
{% endhighlight %}
如图所示,字体 ID 值由 0xd6cf0c3 处的"movsx"指令加载。该指令符号扩展了加载的值,从而填充了*edx*与 **ffff**
。以下调试器摘录说明了运行时
行为:
<pre>
*** edx will become: 0x17fc8 (from 0x7fec+0x7fee*2)
*** edx will become: 0x17fc9 (from 0x7fed+0x7fee*2)
*** edx will become: 0x17fde (from 0x7fee+0x7ff8*2)
*** edx will become: 0x17fdf (from 0x7fef+0x7ff8*2)
*** edx will become: 0x17fe0 (from 0x7ff0+0x7ff8*2)
*** edx will become: 0x17fe1 (from 0x7ff1+0x7ff8*2)
*** edx will become: 0x17fe2 (from 0x7ff2+0x7ff8*2)
*** edx will become: 0x17fe3 (from 0x7ff3+0x7ff8*2)
*** edx will become: 0x17fe4 (from 0x7ff4+0x7ff8*2)
*** edx will become: 0x17fe5 (from 0x7ff5+0x7ff8*2)
*** edx will become: 0x17fe6 (from 0x7ff6+0x7ff8*2)
*** edx will become: 0x17fe7 (from 0x7ff7+0x7ff8*2)
*** edx will become: 0xffff7ffc (from 0x7ff8+0xffff8002*2)
</pre>
发生这种情况时,0xd6cf0c3 处的内存写入指令会破坏堆
通过将字体代码页写入 *esi*
中保存的内存的负偏移量。以下调试器摘录显示了越界内存写入。
<pre>
*** writing 0x4e4 to 0xd35ddb4 [0xd32de20+0x17fc8*2+4]
*** writing 0x4e4 to 0xd35ddb6 [0xd32de20+0x17fc9*2+4]
*** writing 0x4e4 to 0xd35dde0 [0xd32de20+0x17fde*2+4]
*** writing 0x4e4 to 0xd35dde2 [0xd32de20+0x17fdf*2+4]
*** writing 0x4e4 to 0xd35dde4 [0xd32de20+0x17fe0*2+4]
*** writing 0x4e4 to 0xd35dde6 [0xd32de20+0x17fe1*2+4]
*** writing 0x4e4 to 0xd35dde8 [0xd32de20+0x17fe2*2+4]
*** writing 0x4e4 to 0xd35ddea [0xd32de20+0x17fe3*2+4]
*** writing 0x4e4 to 0xd35ddec [0xd32de20+0x17fe4*2+4]
*** writing 0x4e4 to 0xd35ddee [0xd32de20+0x17fe5*2+4]
*** writing 0x4e4 to 0xd35ddf0 [0xd32de20+0x17fe6*2+4]
*** writing 0x4e4 to 0xd35ddf2 [0xd32de20+0x17fe7*2+4]
*** writing 0x4e4 to 0xd31de1c [0xd32de20+0xffff7ffc*2+4]
</pre>
在此内存损坏之后,将进行其他处理。与 精心设计的堆布局,攻击者导致堆损坏产生 任意代码执行。
使用下面提供的概念验证代码,处理最终达到
后处理清理代码。正如预期的那样,*RtlFreeHeap*
被调用并且
检测堆损坏,如下所示。
<pre>
Critical error detected c0000374
(3ba8.21f4): WOW64 breakpoint - code 4000001f (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll_77a40000!RtlReportCriticalFailure+0x4b:
77b27012 cc int 3
0:000:x86> kv
# ChildEBP RetAddr Args to Child
00 008f3834 77b30114 00000001 77b63990 77b2e009 ntdll_77a40000!RtlReportCriticalFailure+0x4b (FPO: [Non-Fpo])
01 008f3840 77b2e009 70dcf286 00000000 1ff78c20 ntdll_77a40000!RtlpReportHeapFailure+0x2f (FPO: [0,0,4])
02 008f3870 77b36480 00000003 00a50000 1ff78c20 ntdll_77a40000!RtlpHpHeapHandleError+0x89 (FPO: [Non-Fpo])
03 008f3888 77b2dd17 1ff78c20 0000000a 00000000 ntdll_77a40000!RtlpLogHeapFailure+0x43 (FPO: [Non-Fpo])
04 008f38ec 77a83f8d 00a50258 70dcf0be 1ff78c20 ntdll_77a40000!RtlpAnalyzeHeapFailure+0x281 (FPO: [Non-Fpo])
05 008f3a48 77ac7b9d 1ff78c20 1ff78c28 1ff78c28 ntdll_77a40000!RtlpFreeHeap+0x24d (FPO: [Non-Fpo])
06 008f3aa4 77a83ce6 00000000 00000000 00000000 ntdll_77a40000!RtlpFreeHeapInternal+0x783 (FPO: [Non-Fpo])
07 008f3ac4 05343c06 00a50000 00000000 1ff78c28 ntdll_77a40000!RtlFreeHeap+0x46 (FPO: [Non-Fpo])
08 008f3adc 06e6e330 1ff78c28 06c8dc6d 08a11040 mso20win32client!Mso::Memory::Free+0x47 (FPO: [Non-Fpo])
09 008f3b0c 0430b5af 08a1104c 08a11040 08a11044 mso!MsoFreePpv+0x84 (FPO: [Non-Fpo])
0a 008f3b28 0430bed0 008f9f0c 008f586c ffffffff wwlib!FreeHribl+0x8c (FPO: [Non-Fpo])
0b 008f3b70 033be323 40280000 00200002 1a772b98 wwlib!PdodCreateRtf+0x243 (FPO: [6,13,4])
0c 008f52bc 02e465db 04012000 20280000 00200002 wwlib!``Osf::SimpleFlight::Details::SetupFlight_String'::`3'::<lambda_1>::operator()'::`2'::`dynamic atexit destructor for 'scopes''+0x1e0966
0d 008f5600 03031155 00000000 ffffffff 00000000 wwlib!PdodCreatePfnCore+0x321 (FPO: [Non-Fpo])
0e 008f5680 0301583a 00000000 ffffffff 00000000 wwlib!PdodCreatePfnBPPaapWithEdpi+0x75 (FPO: [18,3,4])
0f 008f8c4c 030175d4 04012000 00000000 00000002 wwlib!PdodOpenFnmCore2+0xf3b (FPO: [Non-Fpo])
10 008f8d14 03c43d9b 04012000 00000000 00000002 wwlib!PdodOpenFnmCore+0xb9 (FPO: [15,30,0])
11 008f9e40 03c43a92 00000000 00000000 00000002 wwlib!FFileOpenXszCore+0x2f6 (FPO: [Non-Fpo])
12 008f9e7c 0343bd43 00000000 00000000 00000002 wwlib!FFileOpenXstzCore+0x3d (FPO: [6,4,0])
13 008fb31c 02d17666 00000001 00000000 02d17609 wwlib!``Osf::SimpleFlight::Details::SetupFlight_String'::`3'::<lambda_1>::operator()'::`2'::`dynamic atexit destructor for 'scopes''+0x271a8e
14 008fb554 02c594f5 71fc93df 7625f550 0000000a wwlib!Boot::IfrParseCommandLine2+0x5d (FPO: [Non-Fpo])
15 008fb5c8 02c59317 008fb5f8 02c50000 02c58ff4 wwlib!Boot::FRun+0xb4 (FPO: [Non-Fpo])
16 008ff684 02c59058 96c6d88c 000800e4 71fcd0a7 wwlib!FWordBoot+0x5a (FPO: [Non-Fpo])
17 008ff6b8 00dd1917 00dd0000 00000000 0000000a wwlib!FMain+0x64 (FPO: [Non-Fpo])
18 008ff908 00dd114a 00dd0000 00000000 00a54944 winword!WinMain+0x146 (FPO: [Non-Fpo])
19 008ff954 7625fa29 0069a000 7625fa10 008ff9c0 winword!std::_Deallocate<8,0>+0x1e3 (FPO: [Non-Fpo])
1a 008ff964 77aa7bbe 0069a000 70dc3336 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
1b 008ff9c0 77aa7b8e ffffffff 77ac8d0f 00000000 ntdll_77a40000!__RtlUserThreadStart+0x2f (FPO: [SEH])
1c 008ff9d0 00000000 00dd1000 0069a000 00000000 ntdll_77a40000!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
</pre>
分析师还可以使用页面堆来验证代码是否尝试写出 的界限。这样做会导致以下结果:
<pre>
(afe8.9a5c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
wwlib!FSearchFtcmap+0x150:
0dc1f0c3 66894c5604 mov word ptr [esi+edx*2+4],cx ds:002b:1ebf2fec=????
0:000:x86> kv
# ChildEBP RetAddr Args to Child
00 0135135c 0dc0fa17 013513ec 00000001 013513d8 wwlib!FSearchFtcmap+0x150 (FPO: [Non-Fpo])
01 01353828 0dc0ddb5 ddc5a2cb 0b3d3028 000ad400 wwlib!RtfInRare+0x1845 (FPO: [Non-Fpo])
02 01353c5c 0ef5c473 00000200 0b3d3028 66565a58 wwlib!CchRtfInCore+0x28df (FPO: [Non-Fpo])
03 01353eac 0ef5be04 0b3d302c 0135a294 01355bf4 wwlib!RtfGetChars+0x183 (FPO: [Non-Fpo])
04 01353ef8 0e00e323 40280000 00200002 45646f10 wwlib!PdodCreateRtf+0x177 (FPO: [6,13,4])
05 01355644 0da965db 04012000 20280000 00200002 wwlib!``Osf::SimpleFlight::Details::SetupFlight_String'::`3'::<lambda_1>::operator()'::`2'::`dynamic atexit destructor for 'scopes''+0x1e0966
06 01355988 0dc81155 00000000 ffffffff 00000000 wwlib!PdodCreatePfnCore+0x321 (FPO: [Non-Fpo])
07 01355a08 0dc6583a 00000000 ffffffff 00000000 wwlib!PdodCreatePfnBPPaapWithEdpi+0x75 (FPO: [18,3,4])
08 01358fd4 0dc675d4 04012000 00000000 00000002 wwlib!PdodOpenFnmCore2+0xf3b (FPO: [Non-Fpo])
09 0135909c 0e893d9b 04012000 00000000 00000002 wwlib!PdodOpenFnmCore+0xb9 (FPO: [15,30,0])
0a 0135a1c8 0e893a92 00000000 00000000 00000002 wwlib!FFileOpenXszCore+0x2f6 (FPO: [Non-Fpo])
0b 0135a204 0e08bd43 00000000 00000000 00000002 wwlib!FFileOpenXstzCore+0x3d (FPO: [6,4,0])
0c 0135b6a4 0d967666 00000001 00000000 0d967609 wwlib!``Osf::SimpleFlight::Details::SetupFlight_String'::`3'::<lambda_1>::operator()'::`2'::`dynamic atexit destructor for 'scopes''+0x271a8e
0d 0135b8dc 0d8a94f5 ddc527df 7625f550 0000000a wwlib!Boot::IfrParseCommandLine2+0x5d (FPO: [Non-Fpo])
0e 0135b954 0d8a9317 0135b984 0d8a0000 0d8a8ff4 wwlib!Boot::FRun+0xb4 (FPO: [Non-Fpo])
0f 0135fa10 0d8a9058 cbd5c9e4 00080138 ddc564d3 wwlib!FWordBoot+0x5a (FPO: [Non-Fpo])
10 0135fa44 00dd1917 00dd0000 00000000 0000000a wwlib!FMain+0x64 (FPO: [Non-Fpo])
11 0135fc94 00dd114a 00dd0000 00000000 05e18ff4 winword!WinMain+0x146 (FPO: [Non-Fpo])
12 0135fce0 7625fa29 011cf000 7625fa10 0135fd4c winword!std::_Deallocate<8,0>+0x1e3 (FPO: [Non-Fpo])
13 0135fcf0 77aa7bbe 011cf000 96082e8a 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
14 0135fd4c 77aa7b8e ffffffff 77ac8d34 00000000 ntdll_77a40000!__RtlUserThreadStart+0x2f (FPO: [SEH])
15 0135fd5c 00000000 00dd1000 011cf000 00000000 ntdll_77a40000!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
</pre>
此漏洞至少影响以下版本的 Microsoft Office:
旧版本也可能受到影响但未经过测试。此外, 这个漏洞的技术细节多年来一直在发展。
Microsoft Office 2010 及更高版本使用受保护的视图来限制由 从不受信任的来源获取的恶意文件。受保护的视图是 当此漏洞出现时生效,因此会出现一个额外的沙箱 需要逃逸漏洞才能获得全部权限。
删除 RTF 扩展名的文件关联是无效的,因为 使用 DOC 扩展仍然会到达易受攻击的代码。
这个问题是由 Joshua J. Drake (@jduck) 发现、分析和报告的。
使用此格式错误的输入重复运行 Microsoft Word 将触发“安全 模式”以及特定于文件的阻止列表。观察行为 受害者用户会看到,测试人员应该刷新“安全模式”标志并且 重新测试前的特定文件阻止列表。否则,只需拒绝“安全 模式”并单击“仍然打开”足以进行重新测试。
在 WinDbg 中使用重断点(例如下面提供的断点)并启用 页面堆会显着减慢启动过程。研究人员观察到 测试期间未到达易受攻击代码的情况。最小的 努力确定原因,但它似乎与 页面堆、重断点和“新增功能”对话框弹出窗口的组合。
在 WinDbg 中使用了以下脚本来生成上述输出。全部 摘录是使用 Office 365 Insider Preview 2211 Build 15831.20122 获得的点击率。
<pre>
* clear all breakpoints
bc *
* hide the debugger
e ebx+2 00
* run until wwlib is loaded
xe ld:wwlib
g; wait
* make the breakpoints
* watch index calculations
bp wwlib+0x37f0bd ".printf \"*** edx will become: 0x%x (from 0x%x+0x%x*2)\\n\", (ecx+edx*2), ecx, edx;gc"
* watch the writes
bp wwlib+0x37f0c3 ".printf \"*** writing 0x%x to 0x%x [0x%x+0x%x*2+4] (div 3: 0x%x)\\n\", ecx & 0xffff, (esi+(edx*2)+4), esi, edx, edx/3;gc"
g
</pre>
翻到文章最底部点击“阅读原文”下载链接
★
欢 迎 加 入 星 球 !
代码审计+免杀+渗透学习资源+各种资料文档+各种工具+付费会员
进成员内部群
星球的最近主题和星球内部工具一些展示
关 注 有 礼
还在等什么?赶紧点击下方名片关注学习吧!
推荐阅读