Skip to content

Commit 8c0e470

Browse files
author
jvazquez-r7
committed
final cleanup
1 parent c511e58 commit 8c0e470

File tree

1 file changed

+49
-38
lines changed

1 file changed

+49
-38
lines changed

modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,37 @@ class Metasploit4 < Msf::Auxiliary
2626

2727
def initialize
2828
super(
29-
'Name' => 'SAP RFC RFC_READ_TABLE',
29+
'Name' => 'SAP /sap/bc/soap/rfc SOAP Service RFC_READ_TABLE Function Dump Data',
3030
'Description' => %q{
31-
This module makes use of the RFC_READ_TABLE Remote Function Call (via SOAP) to read
32-
data from tables.
33-
},
34-
'References' => [[ 'URL', 'http://labs.mwrinfosecurity.com/tools/2012/04/27/sap-metasploit-modules/' ]],
35-
'Author' => [ 'Agnivesh Sathasivam', 'nmonkee' ],
36-
'License' => BSD_LICENSE
37-
)
31+
This module makes use of the RFC_READ_TABLE Function to read data from tables using
32+
the /sap/bc/soap/rfc SOAP service.
33+
},
34+
'References' =>
35+
[
36+
[ 'URL', 'http://labs.mwrinfosecurity.com/tools/2012/04/27/sap-metasploit-modules/' ]
37+
],
38+
'Author' =>
39+
[
40+
'Agnivesh Sathasivam',
41+
'nmonkee'
42+
],
43+
'License' => MSF_LICENSE
44+
)
3845

39-
register_options(
40-
[
41-
OptString.new('CLIENT', [true, 'Client', nil]),
42-
OptString.new('USERNAME', [true, 'Username', nil]),
43-
OptString.new('PASSWORD', [true, 'Password', nil]),
44-
OptString.new('TABLE', [true, 'Table to read', nil]),
45-
OptString.new('FIELDS', [true, 'Fields to read', '*'])
46-
], self.class)
46+
register_options(
47+
[
48+
Opt::RPORT(8000),
49+
OptString.new('CLIENT', [true, 'Client', nil]),
50+
OptString.new('USERNAME', [true, 'Username', nil]),
51+
OptString.new('PASSWORD', [true, 'Password', nil]),
52+
OptString.new('TABLE', [true, 'Table to read', nil]),
53+
OptString.new('FIELDS', [true, 'Fields to read', '*'])
54+
], self.class)
4755
end
4856

4957
def run_host(ip)
5058
columns = []
51-
columns << '*' if datastore['FIELDS'].nil?
59+
columns << '*' if datastore['FIELDS'].nil? or datastore['FIELDS'].empty?
5260
if datastore['FIELDS']
5361
columns.push (datastore['FIELDS']) if datastore['FIELDS'] =~ /^\w?/
5462
columns = datastore['FIELDS'].split(',') if datastore['FIELDS'] =~ /\w*,\w*/
@@ -77,8 +85,6 @@ def exec(ip,fields)
7785
user_pass = Rex::Text.encode_base64(datastore['USERNAME'] + ":" + datastore['PASSWORD'])
7886
print_status("[SAP] #{ip}:#{rport} - sending SOAP RFC_READ_TABLE request")
7987
begin
80-
error = ''
81-
success = ''
8288
res = send_request_raw({
8389
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
8490
'method' => 'POST',
@@ -91,7 +97,7 @@ def exec(ip,fields)
9197
'Content-Type' => 'text/xml; charset=UTF-8'
9298
}
9399
}, 45)
94-
if res and res.code ! 500 and res.code != 200
100+
if res and res.code != 500 and res.code != 200
95101
# to do - implement error handlers for each status code, 404, 301, etc.
96102
if res.body =~ /<h1>Logon failed<\/h1>/
97103
print_error("[SAP] #{ip}:#{rport} - login failed!")
@@ -102,36 +108,41 @@ def exec(ip,fields)
102108
elsif res and res.body =~ /Exception/
103109
response = res.body
104110
error = response.scan(%r{<faultstring>(.*?)</faultstring>})
105-
success = false
111+
0.upto(error.length-1) do |i|
112+
print_error("[SAP] #{ip}:#{rport} - error #{error[i]}")
113+
end
106114
return
107-
else
108-
response = res.body if res
109-
success = true
110-
end
111-
if success
115+
elsif res
116+
response = res.body
112117
output = response.scan(%r{<WA>([^<]+)</WA>}).flatten
113118
print_status("[SAP] #{ip}:#{rport} - got response")
114119
saptbl = Msf::Ui::Console::Table.new(
115120
Msf::Ui::Console::Table::Style::Default,
116-
'Header' => "[SAP] RFC_READ_TABLE",
117-
'Prefix' => "\n",
118-
'Postfix' => "\n",
119-
'Indent' => 1,
120-
'Columns' => ["Returned Data"]
121-
)
121+
'Header' => "[SAP] RFC_READ_TABLE",
122+
'Prefix' => "\n",
123+
'Postfix' => "\n",
124+
'Indent' => 1,
125+
'Columns' => ["Returned Data"]
126+
)
122127
0.upto(output.length-1) do |i|
123128
saptbl << [output[i]]
124129
end
125130
print(saptbl.to_s)
126-
end
127-
if !success
128-
0.upto(error.length-1) do |i|
129-
print_error("[SAP] #{ip}:#{rport} - error #{error[i]}")
130-
end
131+
this_service = report_service(
132+
:host => ip,
133+
:port => rport,
134+
:name => 'sap',
135+
:proto => 'tcp'
136+
)
137+
loot_path = store_loot("sap.tables.data", "text/plain", ip, saptbl.to_s, "#{ip}_sap_#{datastore['TABLE'].downcase}.txt", "SAP Data", this_service)
138+
print_good("[SAP] #{ip}:#{rport} - Data stored in #{loot_path}")
139+
return
140+
else
141+
print_eror("[SAP] #{ip}:#{rport} - Unknown error")
142+
return
131143
end
132144
rescue ::Rex::ConnectionError
133145
print_error("[SAP] #{ip}:#{rport} - Unable to connect")
134-
return false
135146
end
136147
end
137148
end

0 commit comments

Comments
 (0)