2018年3月末,ESET研究人员发现了一款非常有趣的恶意PDF样本。经过仔细研究后,我们发现该样本利用了之前未知的两个漏洞:Adobe Reader中的一个远程命令执行漏洞以及Microsoft Windows中的一个权限提升漏洞。
这两个漏洞组合起来威力巨大,攻击者可以通过这种方式在存在漏洞的目标上以尽可能高的权限来运行任意代码,并且整个过程很少需要用户交互。APT组织通常会使用这种组合拳来发起攻击,比如去年的Sednit攻击活动就是非常好的一个例子。
在发现这款PDF样本后,ESET第一时间联系了微软安全响应中心(MSRC)、Windows Defender ATP研究团队以及Adobe Product安全事件响应团队,并与这些单位一起协作,直至漏洞被成功修复。
Adobe以及微软也提供了相应补丁及安全公告,分别如下:
受影响的相关产品版本信息如下:
Acrobat DC (2018.011.20038及更早版本)
Acrobat Reader DC (2018.011.20038及更早版本)
Acrobat 2017 (011.30079及更早版本)
Acrobat Reader DC 2017 (2017.011.30079及更早版本)
Acrobat DC (Classic 2015) (2015.006.30417及更早版本)
Acrobat Reader DC (Classic 2015) (2015.006.30417及更早版本)
Windows 7 for 32-bit Systems Service Pack 1
Windows 7 for x64-based Systems Service Pack 1
Windows Server 2008 for 32-bit Systems Service Pack 2
Windows Server 2008 for Itanium-Based Systems Service Pack 2
Windows Server 2008 for x64-based Systems Service Pack 2
Windows Server 2008 R2 for Itanium-Based Systems Service Pack 1
Windows Server 2008 R2 for x64-based Systems Service Pack 1
本文介绍了这款恶意样本以及所利用漏洞的技术细节。
PDF(Portable Document Format)是一种电子文档文件格式,与其他常见文档格式一样,攻击者可以利用该类型文件将恶意软件传播至受害者主机。为了执行恶意代码,攻击者需要寻找并利用PDF阅读器软件中的漏洞。现在有多款PDF阅读器,其中最常用的就是Adobe Reader。
Adobe Reader软件中有一个安全功能:沙箱(sandbox),也称为保护模式(Protected Mode)。Adobe在官方博客上分四部分(Part 1、Part 2、Part 3、Part 4)详细介绍了沙箱的具体实现。沙箱使漏洞利用过程更加困难:即使攻击者可以执行代码,还是必须绕过沙箱的保护机制才能突破运行Adobe Reader的计算机。通常情况下,攻击者需要借助操作系统本身的漏洞来绕过沙箱保护机制。
当然攻击者可以同时找到Adobe Reader软件以及目标操作系统中的漏洞并编写利用程序,不过这种情况非常罕见。
恶意PDF样本中嵌入了一段JavaScript代码,用来控制整个漏洞利用过程。一旦PDF文件被打开,JavaScript代码就会被执行。
在漏洞利用开头阶段,JavaScript代码开始操控Button1
对象,该对象包含一个精心构造的JPEG2000图像,该图像会触发Adobe Reader中的双重释放(double-free)漏洞。
图1. 操控Button1
对象的JavaScript代码
JavaScript代码中用到了堆喷射(heap-spray)技术以破坏内部数据结构。在这些操作都完成后,攻击者就实现了他们的主要目标:从JavaScript代码中实现内存的读取及写入。
图2. 用来读取及写入内存JavaScript代码
利用这两种方法,攻击者成功定位EScript.api
插件的内存地址,而该插件正是Adobe JavaScript的引擎。利用该模块的汇编指令(ROP gadgets),恶意JavaScript成功构造了一条ROP链,可以执行本地shellcode。
图3. 恶意JavaScript成功构造ROP链
最后一步,shellcode会初始化PDF中内嵌的一个PE文件,将执行权递交给该文件。
成功利用Adobe Reader漏洞后,攻击者必须打破沙箱保护机制,而这正是我们即将讨论的第二个利用代码的目的所在。
这个未知漏洞的源头在于win32k
Windows内核组件中的NtUserSetImeInfoEx
函数。更具体一些,就是NtUserSetImeInfoEx
的SetImeInfoEx
子例程没有验证数据指针的有效性,允许某个NULL指针被解除引用(dereference)。
图4. 反汇编后的SetImeInfoEx
例程代码
如图4所示,SetImeInfoEx
函数的第一个参数为指向经过初始化的WINDOWSTATION
对象的指针。如果攻击者创建了一个新的window station对象,并将其分配给用户模式下的当前进程,那么spklList
就会等于0。因此,映射NULL页面并将指针设置为偏移量0x2C
后,攻击者就可以利用这个漏洞写入内核空间中的任一地址。需要注意的是,从Windows 8开始,用户进程不能再映射NULL页面。
既然攻击者具备任意写入权限,他们就可以使用各种方法实施攻击,不过在我们分析的这个例子中,攻击者选择使用Ivanlef0u以及Mateusz “j00ru” Jurczyk和Gynvael Coldwin介绍的一种技术。攻击者重写了全局描述符表(GDT,Global Descriptor Table)来创建Ring 0的一个call gate)(调用门)。为了完成这个任务,攻击者使用SGDT汇编指令获取了原始的GDT信息,构造自己的表然后使用前面提到的漏洞重写了原始的表。
随后,漏洞利用程序使用CALL FAR
指令执行了跨权限级别的调用。
图5. 反汇编后的CALL FAR指令
一旦代码在内核模式执行,漏洞利用程序就会使用system token(令牌)替换掉当前进程的token。
当PDF样本提交到公共恶意样本库时,ESET研究人员就发现了这款样本。彼时样本并不包含最终的攻击载荷,这表明当时样本很有可能处于早期研发阶段。虽然当时样本并不包含真正的恶意载荷,仍有可能处于早期研发阶段,但这也告诉我们样本的作者在漏洞发现及漏洞利用方面具备较高的水平。
ESET检测标识:
JS/Exploit.Pdfka.QNV trojan
Win32/Exploit.CVE-2018-8120.A trojan
样本SHA-1哈希:
C82CFEAD292EECA601D3CF82C8C5340CB579D1C6
0D3F335CCCA4575593054446F5F219EBA6CD93FE
原文:https://www.welivesecurity.com/2018/05/15/tale-two-zero-days/