专栏首页安恒信息vBulletin vB_Api_Hook->decodeArguments RCE 分析

vBulletin vB_Api_Hook->decodeArguments RCE 分析

介绍:

vBulletin是一个国外著名的商业论坛程序。前几天因官网被黑,而被爆出一个命令执行漏洞。

我们最早获得的一篇分析是在Pastie上的http://pastie.org/pastes/10527766/text?key=wq1hgkcj4afb9ipqzllsq,但是经过测试,我们可以确认漏洞存在,但是里面的POC我们在5.1.5版本中却未能测试成功。

分析:

测试版本:vBulletin 5.1.5

1.漏洞出现原因:

文件`/core/vb/api/hook.php`:

在类vB_Api_Hook的类函数decodeArguments中:

直接对`$arguments`参数直接进行反序列化操作,导致漏洞产生。

对于`unserialize`函数何种情况下会产生危害,可以查看:https://www.owasp.org/index.php/PHP_Object_Injection

2.POC:

vBulletin中没有可以直接利用的magic函数,所以我们需要结合多个类使用。

2.1.Pastie中的POC

Pastie中_cutz给出的是利用重写`vB_Database`类中的`$functions['free_result']`,然后通过`vB_dB_Result`类来调用。

2.1.1.类vB_Database

类`vB_Database`的声明在文件`/core/vb/database.php`中,里面有这么一个类函数:

`$queryresult`变量可控,只要我们能重写`$this->functions['free_result']`,就能执行任意函数。

比如`$this→functions['free_result']='system'`,`$queryresult='ifconfig'`,这样`return @$this→functions['free_result']($queryresult)`就变成了`return @system('ifconfig')`。

然后通过`unserialize`函数,我们可以直接重写`$this->functions['free_result']`,也就是_cutz给出的:

然后我们需要找个调用`vB_Database->free_result($queryresult)`的类。

2.1.2.类vB_dB_Result

类`vB_dB_Result`在文件`/core/vb/db/result.php`中。

里面有两个magic函数,__construct()和__destruct()。

调用到`vB_Database->free_result($queryresult)`的有两个类函数,`rewind()`和`free()`。

我们可以看到连个magic函数都间接调用到了`vB_Database->free_result($queryresult)`。

我们测试`unserialize`为类时,`__construct`并不会被执行,而`__desctruct`会执行。

那我们利用`__destruct`可以吗?

但 是`__destruct->free`里面有`if (isset($this->db) AND !empty($this->recordset) AND is_resource($this->recordset))`,`is_resource($this->recordset)`这个不 好绕过,即使绕过了,当我们调用 `vB_Database->free_result($queryresult)->$this->functions['free_result']($queryresult)`时,`$queryresult`参数也不好操作。

但是vB_dB_Result类实现了(implements)Iterator类,Iterator在foreach中会自动调用rewind函数(http://php.net/manual/zh/class.iterator.php)。在vB_Api_Hook类的decodeArguments函数里就有对$args的foreach操作($args = @unserialize($arguments))。

2.1.3.利用

*首先从vB_Database类开始:

$this->functions['free_result']:重写为我们想要的函数,如phpinfo, system等

但是vB_Database为抽象类,所以我们要找个继承vB_Database的类来使用,如vB_Database_MySQL类和vB_Database_MySQLi类。

*到vB_dB_Result类:

$this->db:覆盖为上面被修改过的vB_Database_MySQL。

$this→recordset:我们要传入函数的参数。

*结合上述两个类,序列化输出:

2.2.其它利用分析

这利用方法不是我们自己发现。当我们陷入死胡同后,Check Point Research Team的一篇分析给了我们光明,在此和大家分享。

http://blog.checkpoint.com/2015/11/05/check-point-discovers-critical-vbulletin-0-day/

2.2.1.vB_vURL类

我们通过搜索magic函数,在类`vB_vURL`中的`__destruct`中找到:

这时`$this->tmpfile`可被我们重写,但是这也只是个任意文件删除漏洞。难道就没有更好的利用方式了吗?这时我们想到了`__toString`。

当`$this->tmpfile`为一个对象时,`file_exists($this->tmpfile)`执行时,`$this->tmpfile->__toString`也会执行。

但是我们通过搜索了含有__toString的类,并没有找到什么有用的东西。

这时,我们开始寻找继承类,那些继承了含有__destruct或__toString的类。

找了好久,有几个类引起了我们的注意,其中一个就是vB_View_AJAXHTML。

2.2.2.vB_View_AJAXHTML类

vB_View_AJAXHTML类在文件/core/vb/view/ajaxhtml.php中。

vB_View类在文件/core/vb/view.php中。

类vB_View_AJAXHTML继承了vB_View类。

在vB_View类中有__toString:

vB_View类中的类函数render对我们来说没什么利用价值,但是在继承类vB_View_AJAXHTML中重新声明了类函数render。

vB_View_AJAXHTML类中的render():

这里,我们只要覆盖$this->content就能调用任何$obj->render()。

2.2.3. vB5_Template类

我们搜索`function render`看是否有可利用的render函数。之后在类`vB5_Template`中找到这个:

这里,我们只要覆盖$this->content就能调用任何$obj->render()。

2.2.3. vB5_Template类

我们搜索`function render`看是否有可利用的render函数。之后在类`vB5_Template`中找到这个:

我们直接按那篇报告的流程来,获取title为widget_php的代码内容。

这里$evaledPHP =vB_Template_Runtime::parseAction('bbcode', 'evalCode', $widgetConfig['code'])可当作eval($widgetConfig['code'])。

现在我们只需覆盖$widgetConfig['code']这个变量,在vB5_Template的render里有

我们可以覆盖self::$globalRegistered或者$this->registered,然后extract以后再覆盖$widgetConfig['code']。

这时就能从一个unserialize到命令执行了。

2.2.4.利用思路

*从vB5_Template开始,我们需要覆盖:

$this->registered:用在extract($this->registered, EXTR_OVERWRITE | EXTR_REFS),覆盖变量$widgetConfig['code']。

$this->template:覆盖为widget_php,使$templateCode = $templateCache->getTemplate($this->template)获取到的是template widget_php。

相关链接:

https://theadminzone.com/threads/vbulletin-com-forums-hacked.136961/

http://blog.checkpoint.com/2015/11/05/check-point-discovers-critical-vbulletin-0-day/

http://pastie.org/pastes/10527766/text?key=wq1hgkcj4afb9ipqzllsq

http://www.vbulletin.org/forum/showthread.php?p=2558144

http://archive.hack.lu/2015/They%20Hate%20Us%20Cause%20They%20Ain't%20Us.pdf

本文分享自微信公众号 - 安恒信息(DBAPP2013)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-11-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 传NSA能够录下全球最近30天的所有通话记录

    据美国《华盛顿邮报》获得的一份机密文件显示,美国国家安全署(NSA)能够完整地记录和播放1个月前在美国之外发生的任何一条通话记录。据前 NSA承...

    安恒信息
  • 全国人大代表提“建议加快制定网络安全法”

    3月4日上午,十二届全国人大三次会议预备会议将在人民大会堂举行。4日下午,大会秘书处安排代表按法律规定讨论和提出议案。 据统计,广东代表团代表拟提出15件议案,...

    安恒信息
  • 网络安全专家对APT及AVT的本质与特征分析

    “APT是一种连续性针对被攻击者系统存储的攻击行为,而且这种攻击通常没有明显的攻击特征。而AVT则会在获取敏感资料并准备离开被攻击系统前清除曾进行过相关操作的痕...

    安恒信息
  • RocketMQ 底层通信机制 源码分析

    RocketMQ 底层通讯是使用Netty来实现的。 下面我们通过源码分析下RocketMQ是怎么利用Netty进行通讯的。

    java404
  • java之StopWatch源码分析

    计时这个词语在生活中被应用的很普遍,体育竞赛时频繁出现的秒表,发令信号一经发出,秒表就在滴答滴答流转开始计时了,秒表此时的作用就是计时的代名词,在我们编写代码的...

    用户3625239
  • 线上应用故障排查之一:高CPU占用

    线上应用故障排查之一:高CPU占用 一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环。 以我们最近出现的一个实际故障为例,介绍怎么...

    小小科
  • ReactNative应用之汇率换算器开发全解析

        本篇博客将介绍如何开发一款简易的ReactNative小应用汇率换算器。本应用仅作为学习使用,其支持在人民币与美元间进行汇率计算。汇率计算器应用主要分为...

    珲少
  • React组件方法中为什么要绑定this

    上例仅仅是一个组件类的定义,当在其他组件中调用或是使用ReactDOM.render( )方法将其渲染到界面上时会生成一个组件的实例,因为组件是可以复用的,面向...

    大史不说话
  • as3: this,stage,root的测试

    在不使用文档类(document class)的情况下,直接在时间轴上写以下代码: trace("this->" + this,",root->" + root...

    菩提树下的杨过
  • WinForms 新窗体后台打开完美的解决

    最近在做浏览器开发时,想要实现 IE 6那种多窗体,又允许后台打开而不抢占视野的方式。

    跟着阿笨一起玩NET

扫码关注云+社区

领取腾讯云代金券