*本文作者:兰云科技银河实验室,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。
1.引言
在一个利用CVE-2017-11292的APT样本技术分析(一)中我们简要讨论了这个APT 样本攻击的流程。而CVE-2017-11292 漏洞利用则是该APT攻击中的精华。
CVE-2017-11292 是个较为复杂的类型混淆漏洞,目前尚未有公开的分析报告。本文试图对这个漏洞利用的细节进行深入分析。
该漏洞利用用到了Adobe PrimeTime SDK 中的某些类,比如BufferControlParameters。Adobe 公司似乎并未提供PrimeTimeSDK 的公开下载。经过大量逆向分析尝试,我们发现PrimeSDK 的运行时(runtime)支持并不依赖于PrimeTimeSDK, 运行时(runtime)代码已经直接包含在FlashPlayer的代码中。(这也是合理的,因为用户无需再额外安装PrimeTime SDK)
2. 类型混淆初探
对Flash的整个即时编译JIT过程进行观察和分析,可以发现,类型混淆发生在这里:
在callmethod 29 0这条指令处,
调用的函数是P0::f2(),然而传入的参数却是P3 类型的。也就是说P3 类型在这里被混淆成了P0类型。
P0定义如下
而P3 的定义
可以看出P3 是PrimeTime SDK包中的com.adobe.tvsdk.mediacore.BufferControlParametersObject. 的子类。而P0 则是完全不相干的类型。
3. “我像是一个你可有可无的影子”
下面我们进一步分析是如何通过类型混淆来操控内存的。根据上面的分析,我们看到, 传入的类型是P3,却实际上却是按照类型 P0类来操作。可以这么理解,P3就好象是P0的影子一般,对P0的操作,会直接反映在P3上面。
我们先讨论一下P0和P3的内存布局,就对这个漏洞的利用就豁然开朗了。
其中标为黄色的部分是可以通过Action来控制的类成员变量。
注意到在P3的偏移为16的地方,存在一个指针,这个指针是父类BufferControlParametersObject的成员, 指向BufferControlParameter类。
根据这张图,我们可以很容易的类型混淆是如果工作的。
首先,漏洞利用程序会测试Flash Player的版本是否存在漏洞:
var_13是 P3 类型,首先将其oAddr设成值0×1111。
在windbg中dump var_13 确认,如下图
然后调用type_confusion()函数尝试是否能通过类型混淆将其值修改。
type_confusion() 是如何工作的呢? 答案在 P0::f2()这个函数中,其代码如下图所示:
这里将 P0.u5-1的值赋给了P0.u3。 如果从Action的层面来理解,这行代码似乎很费解。 然而参照 P0以及 P3的内存布局就明白了,表面上是对P0的对象操作,事实上受影响的是其影子P3。从影子P3的角度来看,这里就是通过类型混淆将P3.o的值赋给了P3.oAddr,使得其值变成type_confusion()调用的第二个参数的值即custom_byte_array。在windbg中验证一下:
可能有人会问,为什么是u5需要减去1 再赋给u3而不是u5的值直接赋给u3呢。经调试会发现,u5的值是个Atom(也就是P3.o),二进制的最后三位为001(表示Object类型),减去1后正好为其真正的对象地址。
4. 任意内存访问原语的实现
通过上面的分析,我们发现可以通过类型混淆来操纵P3 类型的对象的内存。那么如何能够进一步的实现对任意内存的读写原语呢。仔细观察内存布局图,我们发现在P3 偏移16处存放了一个指针,而该指针可以通过类型混淆后的P0的u0进行操控。这个指针指向BufferControlParameter类,BufferControlParameter的内存布局如下图:
根据 https://help.adobe.com/en_US/primetime/api/psdk/browser_tvsdk/AdobePSDK.BufferControlParameters.html 提供的API信息
initialBufferTime 和playBufferTime 是两个Number类型(每个8个字节,共16字节)。可以通过Action直接进行读写操作。现在我们看到希望了,通过类型混淆,我们可以通过操控
P0.u0来修改P3.ptr指针的值, 使得ptr + 8 开始的16 个字节 (4 个DWORD) 可以完全被控制(读写)。也就是说,对于给定地址addr, 我们只需将P3.ptr 设成 addr -8 的值,即可完全控制addr 开始的16个字节。
理论上来说,这里已经完全实现了对任意内存的访问。然后攻击者似乎还意犹未尽,可能是出于效率或者其他方面的因素考虑,攻击代码中通过修改一个ByteArray的对象,将其m_buffer.array 设成0,而length设置成0xffffffff, 从而实现了对任意内存的访问。注意,在较新的Flash Player 版本中,引入了一些简单的保护机制,不能仅修改length 的值 ,还需要同时修改另外一个用于校验的成员变量。在攻击代码中 ,我们看到了对此保护机制的妥善处理。
5. 其它信息
该Adobe Flash Player 漏洞利用模块的类结构具有非常清晰的可扩展的跨平台支持。类层次结构定义如下图所示:
处于顶部的是ExploitCommon类,然后有2个子类,分别是32位和64位硬件平台的攻击代码类Exploit32和Exploit64 。而Exploit32, Exploit64又有相应的不同软件平台的攻击代码类,如ExploitWin32,ExploitMac32, ExploitWin64,ExploitMac64等。
漏洞利用模块中包含有大量的冗余代码,例如Mac的shellcode。我们有理由怀疑该攻击模块是从漏洞军火商处购买来的。
5. 结束语
这个漏洞跟CVE-2016-4117有异曲同工之妙,都是利用了Adobe PrimeTime SDK 的类进行攻击。我们大胆的预测,在未来的APT攻击中,我们还会看到利用PrimeTime SDK 中的类进行攻击的实例。
对这个漏洞的分析,我们花费了大量的时间进行逆向与调试。然而鉴于AVM2整个虚拟机的复杂性,错误纰漏在所难免。还有很多漏洞的技术细节我们至今尚未完全了解,欢迎这方面的高手斧正指教。
*本文作者:兰云科技银河实验室,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。返回搜狐,查看更多
责任编辑: