之前没时间记录,趁国庆放假补上。
环境搭建
系统需要至少满足以下要求:
- Apache 2.2+, IIS 7+ or NGINX 1.4+
- PHP 5.3.7
- MySQL 5.1.5
- mod_rewrite, URL Rewrite or equivalent.
- Additional PHP Modules: MySQLi, cURL, OpenSSL Support, iconv, mbstring, JSON Support, XML Support
如果你还是不太清楚自己的环境是否符合要求,可以下载官方的环境检测程序:http://files.vbulletin.com/vb_test.zip 。这里,我的环境是 Ubuntu16.04+Apache+PHP 5.6.40 ,下面是环境满足要求的结果图。
开启、配置 Apache 的 rewrite 模块,这里以 Ubuntu、debian 为例:
sudo a2enmod rewrite #开启rewrite模块
sudo vim /etc/apache2/apache2.conf
# 找到如下内容:
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
# 将AllowOverride None改成AllowOverride All
sudo systemctl restart apache2
找到网站根目录下的 config.php.bkp 文件,将其重命名成 config.php 。找到 webroot/core/includes/config.php.new 文件,将其重命名成 config.php ,并修改以下字段:
修改保存后,访问 http://website/core/install/install.php 即可开始安装网站程序。
漏洞分析
我们先来看下本次漏洞的 EXP ,可以发现其构造并不复杂。
POST /vBulletin/index.php HTTP/1.1
Host: 192.168.0.106
Cookie: XDEBUG_SESSION=PHPSTORM
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 64
routestring=ajax/render/widget_php&widgetConfig[code]=phpinfo();
接下来,我们直接从入口文件开始跟进。在下图 第38行 处下断点,当我们直接单步跳过时,会发现代码执行漏洞被触发了,说明漏洞代码应该在 vB5_Frontend_ApplicationLight 类的 execute 方法中。(下图对应文件位置:vBulletin514/index.php)
我们跟进 execute 方法,会发现其会去调用 vB5_Frontend_ApplicationLight 类的 callRender 方法,继续跟进。(下图对应文件位置:vBulletin514/includes/vb5/frontend/applicationlight.php)
在 callRender 方法中做了一件比较重要的事情,那就是将 $_POST、$_GET 数据注册到 vB5_Template 类的 registered 属性中,而这个属性等下会用来变量覆盖。(下图对应文件位置:vBulletin514/includes/vb5/template.php)
注册完 vB5_Template 类的 registered 属性,就进入了 render 方法。在下图 第201行 ,我们看到程序对 registered 属性进行了变量覆盖,而我们使用上面的 EXP 就会注册 $widgetConfig=array('code'=>'phpinfo();') 变量。接着,程序就会从数据库中取模板代码,即 SELECT * FROM template WHERE `templateid` IN (406); 执行结果的 template 字段对应的值。(下图对应文件位置:vBulletin514/includes/vb5/template.php)
从上图可以看出,程序会将模板代码放入 eval 函数中执行,而程序默认允许将模板中的变量再次 eval ,结合前面的变量覆盖,最终导致代码执行漏洞的发生。其剩余的代码如下图所示。
相关文章: