首页
社区
课程
招聘
[翻译]攻击互通性-以OLE为例
发表于: 2017-7-2 23:25 16966

[翻译]攻击互通性-以OLE为例

2017-7-2 23:25
16966

攻击互通性:以OLE为例

翻译 by 银雁冰

 

说明:本文为Haifei Li (haifei.li@intel.com)Bing Sun (bing.sun@intel.com2015年美国黑帽大会(BlackHat)的演讲PPT。该PPT对历史Office漏洞的原因做了深度探讨,是Office漏洞分析领域的经典paper。对Office漏洞有兴趣的小伙伴可以认真读一下这篇文章。

 

原文链接:https://www.blackhat.com/docs/us-15/materials/us-15-Li-Attacking-Interoperability-An-OLE-Edition.pdf


相关译文链接:http://bbs.pediy.com/thread-219234.htm

Ø  尽管我们要讨论的是OLE,代表对象链接与嵌入(Object Linking and Embedding),本次演讲我们只讨论嵌入(Embedding)

Ø  限于演讲时间

Ø  这真是个很大的领域

Ø  什么是OLE

Ø  历史上与OLE相关的0day

Ø  深入解析OLE

Ø  攻击面

Ø  结论


Ø  对象链接与嵌入

Ø  基于组件对象模型(COM)

 

Ø  它服务于Office/WordPad的大部分互通性

Ø  与默认/第三方应用程序一起工作,以给Office/WordPad用户丰富的文档特性


Ø  将一个文档嵌入另一个文档

                                            

Ø  通过双击清单里的文档,读者将能够打开另一个文档

Ø  Office用户来说非常方便

 

Ø  几乎所有之前的严重的Office/WordPad零日漏洞都涉及到OLE

Ø  CVE-2014-4114/6352(又名沙虫零日漏洞)

Ø  报告于201410月,非常严重的逻辑漏洞

Ø  在原始样本里面发现两个OLE对象

Ø  在对CVE-2014-4114的初次修复中,微软并没有做到有效修复(译者注:这直接导致了CVE-2014-6352的公告)


Ø  CVE-2014-1761

Ø  20143月被谷歌报告,是一起高度针对性的攻击

Ø  RTF文件格式解析错误,并不是一个位于OLE对象的漏洞,但是利用了OLE机制来加载一个未开启ASLR的模块”MSCOMCTL.DLL”,用来绕过ASLR

 

Ø  CVE-2013-3906

Ø  20138月被我们检测到并报告

Ø  微软图形组件错误,并不是一个位于OLE对象的漏洞,但是利用了ActiveX/OLE机制来进行Office中的堆喷射


Ø  CVE-2012-0158/CVE-2010-3333

Ø  位于MSCOMCTL.OCX中的多年的老漏洞(译者注:CVE-2010-3333应位于mso.dll中,这里或许CVE-2012-1856更为合适,后者是MSCOMCTL.OCX中的一个UAF漏洞)

Ø  经典OLE漏洞

Ø  到今天还可以看到野外的样本


Ø  补充一下:一个相似的0day攻击,也位于MSCOMCTL.OCX(CVE-2015-2424)

Ø  2014615日被iSight的小伙伴公布

Ø  http://www.isightpartners.com/2015/07/microsoft-office-zero-day-cve-2015-2424-leveraged-by-tsar-team

 

Ø  OLE对象不仅制造严重的零日漏洞,也在另外的Office/WordPad漏洞利用中起到了极大的帮助作用

Ø  加载未开启ASLR的模块

Ø  Office进程中进行堆喷射

Ø  

Ø  漏洞类别覆盖从内存破坏到逻辑漏洞

 

Ø  之前几乎没有关于于OLE内部机制的研究,但是我们要提到两个:

Ø  “Attacking Interoperability”

Ø  http://hustlelabs.com/stuff/bh2009_dowd_smith_dewey.pdf

Ø  Mark Dowd, Ryan Smith, and David Dewey 写于2009

Ø  我们这次演讲的题目是为了纪念这篇paper里面的伟大工作

Ø  Parvez Anwar的博客上有一些与Office/OLE相关的工作

Ø  https://www.greyhathacker.net/

 


 

Ø  为了解释OLE的内部原理,首先我们需要理解当一个用户打开一个含有OLE的文档时会发生什么

 

Ø  初始化/加载一个OLE对象可以通过ole32!OleLoad()这一API来简单实现



Ø  我们关注两个主要步骤

Ø  步骤1:调用CoCreateInstance来初始化OLE对象

Ø  步骤2:调用IPersistStorage来初始化OLE对象的初始状态(数据)

Ø  接下来我们详细分析这两个步骤

 

ole32!wCreateObject+0x101:

75b41553 e8b387feff call ole32!CoCreateInstance (75b29d0b)

0018de38 0018de98 00000000 00000403 64c0c954

0:000> k

75b3f2af ole32!wCreateObject+0x101

75b3f1d4 ole32!OleLoadWithoutBinding+0x9c

632c4eb4 ole32!OleLoad+0x37

0:000> db poi(esp)

0018de98 02 26 02 00 00 00 00 00-c0 00 00 00 00 00 00 46

0:000> db poi(esp+4*3)

64c0c954 12 01 00 00 00 00 00 00-c0 00 00 00 00 00 00

 

 

Ø  CLSID来自文档,指明用户想要初始化哪一个OLE对象

Ø  因为Office/WordPad支持一系列的文档类型,不同类型定位CLSID的方式都不一样

Ø  Office Open-XML格式(.docx, .xlsx, .pptx, 等等)

Ø  RTF(.rtf)

Ø  Office二进制格式(.doc, .xls, .ppt, .pps, 等等)

Ø  Office甚至支持HTML格式

Ø  我们只举例给出Open-XML格式和RTF格式里面的CLSID来源

 

Ø  对于Open-XML格式,CLSIDOLESS二进制数据文件中读入

 

Ø  RTF文档用过时的OLE1.0格式来定义一个OLE对象

Ø  https://msdn.microsoft.com/en-us/library/dd942402.aspx

Ø  指定一个CLSID是通过指定位于\objdata控制字中相应的ProgID来完成的

Ø  在运行时,ProgID将会通过CLSIDFromProgID被“转换”成CLSID(如果ProgID不合法,而且接下来的native数据遵循OLESS格式,CLSID将会从OLESS native数据中读取)

 

ole32!wCreateObject+0x1f9:

75b3eb41 ff5118 call dword ptr [ecx+18h]

ds:0023:6fb614a8={packager!CPackage::Load (6fb66171)}

0:000> k

75b3f2af ole32!wCreateObject+0x1f9

75b3f1d4 ole32!OleLoadWithoutBinding+0x9c

5c0e4eb4 ole32!OleLoad+0x37

 

Ø  容器调用OLE对象的IPersistStorage接口中的Load()方法来初始化OLE对象的初始状态


Ø  https://msdn.microsoft.com/en-us/library/windows/desktop/ms679731(v=vs.85).aspx

Ø  IID0000010a-0000-0000-C000-000000000046

 


当初始化的时候为OLE对象加载其初始“状态”

Ø  如何处理IStorage—加载它的初始状态,其实取决于OLE对象

Ø  因为执行IPersistStorage接口的代码位于OLE提供者(OLE对象)

Ø  Storage Data(” IStorage”参数提供)是存储在文档文件里的

Ø  ”CLSID”域一样,它也来自文档文件(这可以由攻击者提供)

Ø  但是两者也有一些不同

Ø  OLE容器(Office/WordPad)读取CLSID是为了去初始化OLE对象

Ø  OLE容器读取Storage Data并将它传递给OLE对象,由OLE对象负责处理读入的数据

 

Office Open-XML 格式中的Storage Data

Ø  OLESS数据文件提供

Ø  下面的例子展示了Flash Player OLE对象的Storage Data

Ø  D27CDB6E-AE6D-11CF-96B8-444553540000

Ø  OLESS数据文件(oleObject.bin)中读入Storage Data

Ø  ”Contents”节里面读入

 

RTF中的Storage Data

Ø  OLE1 Native Data提供

Ø  相关描述见这里:https://msdn.microsoft.com/en-us/library/dd942053.aspx

 

Ø  我们已经解释了OLE初始化过程中的两个关键步骤

Ø  接下来,让我们看一下”Verb”动作

 


Ø  本质上,执行”Verb”动作其实只是调用了OLE对象的IOleObject::DoVerb方法

Ø  IOleObject

Ø  https://msdn.microsoft.com/en-us/library/windows/desktop/dd542709(v=vs.85).aspx

Ø  IID: 00000112-0000-0000-C000-000000000046

Ø  这个接口上有24个方法

Ø  这个IOleObject::DoVerb方法有一些参数,但是我们只需要关注其中一个,即第一个参数:”iVerb”,这个参数在特定场景下可以被攻击者控制

Ø  举个例子,通过提供PowerPoint放映文件(.ppsx, .pps)

packager!CPackage::DoVerb:

731e580c 8bff mov edi,edi

0:000> dd esp

0031c89c 660651c6 0054ec80 FFFFFFFD 00000000

Ø  所以,什么是攻击者可能会在一次基于文档的攻击中使用的呢?

Ø  我们需要理解一个攻击者可以从文档中提供什么数据

Ø  攻击者是否能够提供在OLE初始化过程中CoCreateInstance函数所需的CLSID

Ø  答案是:Yes(前面已经解释)

Ø  攻击者是否能够提供在OLE初始化过程中的IPersistStorage::Load所需的Storage

Ø  答案是:Yes(前面已经解释)

Ø  攻击者是否能够提供在OLE”Verb”动作执行时所需的”Verb”id

Ø  答案是:Yes(前面已经解释)

 

Ø  这是最常见的的一种

Ø  你想要去解析一些数据;我给你伪造的数据

Ø  有时候这会导致内存破坏,有时候这可能会变成一个逻辑漏洞

Ø  事实上,大多数之前被公开的OLE漏洞都位于IPersistStorage::Load方法

Ø  让我们来给出几个例子

 

Ø  大多数之前的分析已经展现过下图了,在MSCOMCTL.OCX模块中

 

Ø  但是,漏洞函数究竟来自哪里?

Ø  往前追踪,我们到了这里


Ø  sub_276008D9函数到底是什么?

Ø  在一番逆向后,我们意识到这其实是IPersistStorage::Load方法


Ø  事实上,这个基于栈的溢出位于IPersistStorage::Load方法

 

Ø  20147月的McAfee实验室博客上被报告

Ø  https://blogs.mcafee.com/mcafee-labs/dropping-files-temp-folder-raises-security-concerns

Ø  Demo: http://justhaifei1.blogspot.com/2014/08/demonstration-of-windowsoffice-insecure.html

Ø  还未被修复!

Ø  最近,(谷歌的)James Forshaw在他发现的一个NTLM反射权限提升漏洞中的利用中利用了这个特性:

https://code.google.com/p/google-security-research/issues/detail?id=325


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 4
支持
分享
最新回复 (3)
雪    币: 207
活跃值: (356)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习了,非常感谢!
2017-7-24 16:29
0
雪    币: 346
活跃值: (62)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
very good,学习了,希望作者继续翻译有关文章
2019-7-2 22:15
0
雪    币: 1139
活跃值: (171)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
Thanks !!!
2019-12-19 17:23
0
游客
登录 | 注册 方可回帖
返回
//