——通过实例看运行时防护技术如何破解数字世界的“阿喀琉斯之踵”高危漏洞
概述
今年8月初,有安全厂商发布消息称捕获国内某款文档处理软件的远程代码执行漏洞。赛博昆仑实验室研究员经过紧急分析,确定了该漏洞的成因并还原出PoC,在此基础上第一时间发布了针对该漏洞的微补丁程序,并通过昆仑洞见平台下发,从而实现了无需升级重启,即可对该漏洞进行精准防御。同一时间,该文档开发厂商也发布了升级版本(以下称为8月官方补丁),对该漏洞进行了修补。
近期,昆仑实验室监测到该文档软件发布了最新更新,有意思的是,我们发现这次版本更新似乎对8月官方补丁进行了进一步强化。结合8月份对官方补丁的分析,我们猜测当时的补丁可能存在绕过问题。通过研究,我们确实找到了一种绕过8月官方补丁的方法。我们确认近日官方最新发布的版本更新已经修复了这一绕过方法;同时,已使用赛博昆仑8月发布微补丁程序的客户无需改文档软件升级即可防御这个绕过。
由于该文档软件原始远程代码执行漏洞是实际被捕获的0day,我们将该0day漏洞绕过定性为需要尽快处理的高危漏洞,建议使用相关文档软件的客户尽快到官方下载更新,第一时间进行升级修复。已部署使用赛博昆仑洞见平台及代理提供PC端防护的用户无需升级即可免疫该漏洞。
技术原理分析
8月被捕获的远程代码执行漏洞分析(以下称为8月漏洞)
8月漏洞基本上是微软Office历史漏洞CVE-2017-8570的翻版。由于该软件对Office文档的兼容性,出现了同样的漏洞。
8月漏洞的PoC构造如下:在Office文档里嵌入OLE链接,链接的第一层对象是一个CompositeMoniker (00000309-0000-0000-C000-000000000046)。CompositeMoniker包含了一个FileMoniker(00000303-0000-0000-C000-000000000046)和一个NewMoniker(ECABAFC6-7F19-11D2-978E-0000F8757E2A)。NewMoniker的作用只是将FileMoniker实例化,因此关键在于FileMonker。FileMoniker指向ScriptletFile对象,对应的路径可以是一个本地或者远程的脚本文件 (后缀名为.scr)。该FileMoniker实例化时会加载对应的脚本文件,并使用脚本引擎控件(如jscript.dll)运行对应脚本,即可实现远程代码执行。整个过程如下:
通过对官方8月补丁的分析,我们发现官方补丁的逻辑如下:
检查所有CompositeMoniker中包含的子Moniker,如果发现FileMoniker,则提取FileMoniker文件的路径,在路径中取出文件的后缀名。将后缀名与内置黑名单比较,如果该后缀名在黑名单中,则阻止这个FileMoniker的实例化。这个黑名单包含了scr, com, exe等有风险的文件类型。
我们可以看到,官方补丁确实能够成功阻止原始样本。只要FileMoniker指向的文件后缀名是scr加载过程就会失败。如果简单将文件的后缀名scr替换或者直接去掉,我们发现PoC也无法正常工作。这是因为COM Library也需要通过FileMoniker文件的后缀名来判断要实例化的组件,对这块有兴趣的读者可以研究一下ole32!wCoGetClassExt的实现过程,该函数最终是通过注册表中的后缀名对应到clsid。而scr对应了scriptlet file,在原始样本中,一旦scr后缀名不复存在,scriptlet控件也就无法实例化,整个过程就被阻断了。
尽管当时官方补丁看起来解决了这个0day漏洞,但是我们还是对该补丁有一点不确定。这主要是因为参考借鉴微软官方补丁在修补CVE-2017-8570时,采取的是直接禁止了Office文档中FileMoniker=>scriptlet的加载。这一修补显得更为彻底。相比之下,这个8月补丁存在一些不确定性 – 是否阻止scr后缀名就够了呢?
赛博昆仑针对8月漏洞的微补丁比较直接,直接参考微软官方CVE-2017-8570补丁,在该文档进程中阻止了FileMoniker=>scriptlet这一调用链。洞见平台的二进制微补丁引擎让我们能够很方便地实现这一功能。
前面提到,近期该文档软件发布了更新,通过分析我们发现,这次更新似乎对相关控件进行了更进一步限制。这让我们联想到了当时对8月补丁残存的疑虑 – 这会不会是8月补丁的一个延续呢? 由于在本次更新中,官方没有发布和漏洞相关的信息,所以我们从其它方向进行侧面验证。
我们在深入研究过程发现,确实有一种方法能够不使用scr后缀名,仍然能够实例化scriptlet控件。在FileMoniker在实例化对象时,除了通过后缀名对应到相关的CLSID,其实还存在一种直接在Moniker流中指定要实例化对象的CLSID的方式。通过该方式,我们可以达到使用任意后缀名,但仍然实例化Scriptlet的效果,从而彻底绕过了8月官方的补丁。下图为该绕过在这款软件10月的某个版本上的效果:
接着我们将绕过PoC在最新版本上进行了测试,发现最新版本已经能够阻止这一绕过PoC,解决方式应该是阻止了FileMoniker=>Scriptlet这一链条。这也间接证实了我们的猜测:官方发现了8月补丁的不足之处并且在最新的补丁中进行了解决。
关于软件运行时防护技术
漏洞攻防一直是安全攻防中的重要课题。通常我们面对0day漏洞,优先选择的解决方案肯定是打上官方补丁。但是漏洞攻防(乃至整个安全攻防)是一个立体的体系,并不存在某个单点就能解决所有问题的情况。软件运行时防护技术能够不依赖于官方补丁,在软件运行时对已知和未知漏洞进行防御,是在官方补丁之外对高危0day漏洞进行检测和防御的一个较为有效的手段。
从文中所举的实际案例我们可以看到,一个好的运行时防护规则/微补丁,不仅能够在官方补丁还未发布的窗口期(如微软修复0day漏洞的周期在4个月左右),实时地帮助用户有效地防护高危0day漏洞,甚至可以在官方补丁存在缺陷或者漏洞存在变种的情况下,对未知0day漏洞进行防御。比如在本文所举的例子中,同一个微补丁同时起到了针对已知漏洞防御(8月0day)和针对未知漏洞防御(8月补丁绕过)两个作用。我们可以看到一个高质量的运行时防护规则在面对实际漏洞时能够起到较好的效果,这需要防护规则的开发人员对漏洞原理、利用方式等具有较深入的理解和积累,能够从多个漏洞中总结出共性和经验。这对漏洞解决方案提供方的漏洞研究能力,提出了较高的要求。
漏洞防护规则的落地需要依托于一套完整的产品框架。该框架最基本的要求是能够支持尽量多的平台和应用程序架构。从各种Web应用(Java/PHP/Python/…),到二进制程序和服务,再到系统内核、设备,都可能在某一时间出现需要立即防护高危0day漏洞。只有尽量多的适配不同的平台和程序架构,才能在有需要时第一时间在最精确的位置实现防御。
赛博昆仑一直致力于根本解决数字世界“阿喀琉斯之踵”高危漏洞问题,集结业界安全人才,沉淀漏洞挖掘经验,提炼实战攻击技巧,通过洞见系列产品持续输出高级攻防对抗能力,重构安全防护平衡点。
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...