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

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

缺陷编号:wooyun-2014-064809

漏洞标题:PHPCMS 后台命令执行及多枚后台注入(安全处理不当)

相关厂商:phpcms

漏洞作者: phith0n

提交时间:2014-06-19 12:30

修复时间:2014-09-14 12:32

公开时间:2014-09-14 12:32

漏洞类型:命令执行

危害等级:高

自评Rank:15

漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-06-19: 细节已通知厂商并且等待厂商处理中
2014-06-24: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放
2014-08-18: 细节向核心白帽子及相关领域专家公开
2014-08-28: 细节向普通白帽子公开
2014-09-07: 细节向实习白帽子公开
2014-09-14: 细节向公众公开

简要描述:

一起交了吧,后台注入+后台getshell。注入的话低权限就行了。
'pc_version' => 'V9.5.6', //phpcms 版本号
'pc_release' => '20140522', //phpcms 更新日期

详细说明:

我曾交过一个后台getshell( WooYun: PHPCMS后台Getshell ),看看phpcms怎么修复的。
这是后台编辑自定义url规则的代码(/phpcms/modules/admin/urlrule.php:47),关键看其中怎么过滤后缀的:

function edit() {
if(isset($_POST['dosubmit'])) {
$urlruleid = intval($_POST['urlruleid']);
$_POST['info']['urlrule'] = rtrim(trim($_POST['info']['urlrule']),'.php');
$_POST['info']['urlrule'] = str_replace('.php','',$_POST['info']['urlrule']);
$this->db->update($_POST['info'],array('urlruleid'=>$urlruleid));
$this->public_cache_urlrule();
showmessage(L('update_success'),'','','edit');
} else {
$show_validator = $show_header = '';
$urlruleid = $_GET['urlruleid'];
$r = $this->db->get_one(array('urlruleid'=>$urlruleid));
extract($r);
$modules_arr = $this->module_db->select('','module,name');

$modules = array();
foreach ($modules_arr as $r) {
$modules[$r['module']] = $r['name'];
}
include $this->admin_tpl('urlrule_edit');
}
}


关键就是这两句话:
$_POST['info']['urlrule'] = rtrim(trim($_POST['info']['urlrule']),'.php');
$_POST['info']['urlrule'] = str_replace('.php','',$_POST['info']['urlrule']);
先去除了右边所有的“.php”中任意一个字符。然后再把.php清空。
其实就是比之前那个多了一个str_replace。
那么如果我的文件名是“xxxx.p.phphp .php”的话,首先去除右边的.php变成“xxxx.p.phphp ”,然后再替换.php为空,依旧变成“xxxx.php ”,拿shell方法和之前提交的一样。
然后注入,注入的话比较多,举个栗子,编辑文字处(/modules/content/content.php:151):

if($_POST['edit']) {
$this->page_db->update($_POST['info'],array('catid'=>$catid));
} else {
$catid = $this->page_db->insert($_POST['info'],1);
}


将$_POST['info']带入update函数,跟一下update函数:

final public function update($data, $where = '') {
if (is_array($where)) $where = $this->sqls($where);
return $this->db->update($data, $this->table_name, $where);
}


再跟进这里面的update方法:

public function update($data, $table, $where = '') {
...
default:
$fields[] = $this->add_special_char($k).'='.$this->escape_string($v);
...
$sql = 'UPDATE `'.$this->config['database'].'`.`'.$table.'` SET '.$field.$where;
return $this->execute($sql);
}


主要是$fields[] = $this->add_special_char($k).'='.$this->escape_string($v);这句,其实就是将key的值两边加反引号`,value的值两遍加单引号。
我们的POST数据是经过addslashes了的,但只有值经过了addslashes,键没有任何过滤。所以我们在POST数组的键中加入单引号就会报错:

05.jpg

漏洞证明:

拿shell步骤就不详细说了,看图吧:

01.jpg


注意此时要改“内容页”的url规则。
然后发表一篇内容,其中包含shell,在栏目的位置要把内容页url规则选成刚才改的那个。

02.jpg


然后生成一下内容页的静态,访问即可见shell:

03.jpg


注入的话低权限就可以了,只要编辑权限,能够有内容板块的管理权限:

04.jpg


如图,注入的时候记得要用/*!50000select*/替代select,因为内部会过滤一下select:

06.jpg


此类后台注入还有很多,基本都是类似这种直接将$_POST变量传入update或insert函数:update($_POST:

07.jpg

修复方案:

自己看咯~

版权声明:转载请注明来源 phith0n@乌云


漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2014-09-14 12:32

厂商回复:

最新状态:

暂无