攻击互通性:以 OLE为例
翻译 by 银雁冰
说明:本文为 Haifei Li (haifei.li@intel.com )和 Bing Sun (bing.sun@intel.com ) 在 2015年美国黑帽大会 (BlackHat)的演讲 PPT。该 PPT对历史 Office漏洞的原因做了深度探讨,是 Office漏洞分析领域的经典 paper。对 Office漏洞有兴趣的小伙伴可以认真读一下这篇文章。
原文链接: 4d0K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2T1L8r3q4U0K9$3S2S2N6q4)9J5k6h3y4G2L8g2)9J5c8X3c8G2j5%4y4Q4x3V1k6#2M7#2)9J5k6o6p5#2i4K6u0r3L8h3q4@1k6i4u0A6j5h3I4K6i4K6u0r3N6i4y4Q4x3X3b7I4y4g2)9J5k6p5I4A6i4K6u0V1b7i4c8@1j5h3y4C8K9h3&6Y4i4K6u0V1d9h3&6@1k6i4u0G2M7r3g2J5j5h3u0A6L8r3W2@1P5g2)9J5k6p5q4F1i4K6u0V1e0@1I4q4i4K6u0V1c8h3c8A6N6r3W2G2L8W2)9J5k6i4m8V1k6R3`.`.
相关译文链接: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( 又名 ” 沙虫 ” 零日漏洞 )
Ø 报告于 2014年 10月,非常严重的逻辑漏洞
Ø 在原始样本里面发现两个 OLE对象
Ø 在对 CVE-2014-4114 的初次修复中,微软并没有做到有效修复 (译者注:这直接导致了 CVE-2014-6352的公告 )
Ø CVE-2014-1761
Ø 2014年 3月被谷歌报告,是一起高度针对性的攻击
Ø RTF 文件格式解析错误,并不是一个位于 OLE 对象的漏洞,但是利用了 OLE 机制来加载一个未开启 ASLR 的模块 ”MSCOMCTL.DLL” ,用来绕过 ASLR
Ø CVE-2013-3906
Ø 2013年 8月被我们检测到并报告
Ø 微软图形组件错误,并不是一个位于 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 )
Ø 在 2014年 6月 15日被 iSight的小伙伴公布
Ø aacK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3W2K6K9h3N6Z5N6s2m8S2M7Y4c8F1k6i4u0K6i4K6u0W2j5$3!0E0i4K6u0r3x3U0l9I4y4g2)9J5c8U0l9%4i4K6u0r3L8h3W2U0M7X3!0K6L8$3k6@1i4K6u0V1L8$3k6X3K9h3y4W2i4K6u0V1P5X3g2J5L8#2)9J5k6r3c8S2P5g2)9J5k6r3y4$3k6g2)9J5k6o6t1H3x3e0g2Q4x3X3b7J5y4o6t1@1i4K6u0V1L8r3g2$3k6i4u0S2k6$3g2V1i4K6u0V1j5Y4W2Q4x3X3c8@1M7$3q4J5i4K6u0V1N6r3g2S2L8b7`.`.
Ø OLE对象不仅制造严重的零日漏洞,也在另外的 Office/WordPad漏洞利用中起到了极大的帮助作用
Ø 加载未开启 ASLR 的模块
Ø 在 Office 进程中进行堆喷射
Ø …
Ø 漏洞类别覆盖从内存破坏到逻辑漏洞
Ø 之前几乎没有关于于 OLE内部机制的研究,但是我们要提到两个:
Ø “Attacking Interoperability”
Ø 54dK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3S2#2M7%4c8D9k6h3I4S2j5Y4y4Q4x3X3g2U0L8$3#2Q4x3V1k6K6N6s2g2X3k6W2)9J5c8X3u0Z5x3U0l9H3z5g2)9#2k6X3c8G2N6$3c8Q4y4h3k6K6L8h3W2@1K9q4)9#2k6X3c8W2N6$3g2&6i4K6u0W2M7r3c8X3
Ø Mark Dowd, Ryan Smith, and David Dewey 写于 2009年
Ø 我们这次演讲的题目是为了纪念这篇 paper里面的伟大工作
Ø Parvez Anwar的博客上有一些与 Office/OLE相关的工作
Ø b81K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2Y4M7X3g2&6K9r3q4@1K9r3q4U0K9$3g2J5i4K6u0W2L8X3g2@1i4K6u0r3
Ø 为了解释 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格式, CLSID从 ”OLESS ”二进制数据文件中读入
Ø RTF文档用过时的 OLE1.0格式来定义一个 OLE对象
Ø f05K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0M7$3c8F1i4K6u0W2L8h3W2U0M7X3!0K6L8$3k6@1i4K6u0W2j5$3!0E0i4K6u0r3k6h3&6Q4x3X3c8#2M7#2)9J5c8X3I4A6j5Y4u0S2M7Y4W2Q4x3V1k6V1k6o6V1@1x3U0b7H3x3W2)9J5k6h3q4K6M7s2R3`.
Ø 指定一个 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对象的初始状态
Ø 39cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0M7$3c8F1i4K6u0W2L8h3W2U0M7X3!0K6L8$3k6@1i4K6u0W2j5$3!0E0i4K6u0r3k6h3&6Q4x3X3c8#2M7#2)9J5c8X3I4A6j5Y4u0S2M7Y4W2Q4x3V1k6%4K9h3&6V1L8%4N6K6i4K6u0r3k6r3g2K6K9%4c8G2M7q4)9J5c8X3#2K6y4U0M7&6y4K6x3I4i4K6t1^5N6W2)9K6c8s2k6K6i4K6u0W2z5o6g2Q4x3U0W2Q4x3X3g2S2M7%4m8^5
Ø IID: 0000010a-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 Ope n-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 提供
Ø 相关描述见这里: fe2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0M7$3c8F1i4K6u0W2L8h3W2U0M7X3!0K6L8$3k6@1i4K6u0W2j5$3!0E0i4K6u0r3k6h3&6Q4x3X3c8#2M7#2)9J5c8X3I4A6j5Y4u0S2M7Y4W2Q4x3V1k6V1k6o6V1@1x3U0l9#2x3#2)9J5k6h3q4K6M7s2R3`.
Ø 我们已经解释了 OLE 初始化 过程中的两个关键步骤
Ø 接下来,让我们看一下 ”Verb” 动作
Ø 本质上,执行 ”Verb”动作其实只是调用了 OLE对象的 IOleObject::DoVerb 方法
Ø IOleObject
Ø a12K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0M7$3c8F1i4K6u0W2L8h3W2U0M7X3!0K6L8$3k6@1i4K6u0W2j5$3!0E0i4K6u0r3k6h3&6Q4x3X3c8#2M7#2)9J5c8X3I4A6j5Y4u0S2M7Y4W2Q4x3V1k6%4K9h3&6V1L8%4N6K6i4K6u0r3k6r3g2K6K9%4c8G2M7q4)9J5c8X3c8V1y4e0b7J5y4K6l9&6i4K6t1^5N6W2)9K6c8s2k6K6i4K6u0W2z5o6g2Q4x3U0W2Q4x3X3g2S2M7%4m8^5
Ø 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 方法
Ø 在 2014年 7月的 McAfee实验室博客上被报告
Ø 448K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4M7#2)9J5k6h3#2U0j5h3k6W2k6g2)9J5k6h3y4G2L8g2)9J5c8X3#2U0j5h3k6W2k6g2)9J5k6r3I4S2j5Y4y4Q4x3V1k6V1M7X3!0H3M7r3W2F1k6#2)9J5k6r3k6A6L8r3g2K6i4K6u0V1N6r3g2E0M7q4)9J5k6r3k6G2L8r3c8W2M7W2)9J5k6s2u0S2K9i4y4W2M7#2)9J5k6s2y4W2j5%4g2J5K9i4c8&6i4K6u0V1j5$3!0F1j5$3g2J5L8Y4x3`.
Ø Demo: 5a5K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3A6#2M7%4c8Z5j5h3W2X3k6h3V1I4i4K6u0W2j5X3I4G2k6%4y4H3L8%4c8Q4x3X3g2U0L8$3#2Q4x3V1j5J5x3o6p5@1i4K6u0r3x3o6S2Q4x3V1k6V1k6h3#2G2L8Y4y4@1M7X3q4@1K9h3!0F1i4K6u0V1L8$3k6Q4x3X3c8%4K9h3&6V1L8%4N6K6L8$3k6X3K9h3y4W2i4K6u0V1K9h3&6K6k6h3y4#2M7X3g2Q4x3X3g2Z5N6r3#2D9
Ø 还未被修复!
Ø 最近, (谷歌的 )James Forshaw在他发现的一个 NTLM反射权限提升漏洞中的利用中利用了这个特性:
4a0K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0L8$3c8W2i4K6u0W2k6$3!0G2k6$3I4W2i4K6u0W2j5$3!0E0i4K6u0r3M7q4)9J5c8X3N6G2L8$3N6D9k6g2)9J5k6s2y4W2j5%4g2J5K9i4c8&6i4K6u0V1M7X3g2K6k6h3q4J5j5$3S2Q4x3V1k6A6M7%4y4#2k6i4y4Q4x3V1k6V1k6i4c8S2K9h3I4Q4x3@1k6A6k6q4)9K6c8o6x3J5y4b7`.`.
[培训]传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!
上传的附件: