齐博 src="/do/js.php?id=775",齐博地方门户鸡肋文件包含造成的高危SQL注入 | CN-SEC 中文网...

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

首先,我和大家说一下齐博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 "

";

}

如果$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.="$rs[name]";

}

*/

if(!$fup){

foreach( $city_DB[name] AS $key=>$value){

$ckk=$ck==$key?" selected ":" ";

$show.="$value";

}

}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.="$value";

}

}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.="$rs[name]";

}

}

}

$title = $table=="{$pre}city"?'全国':'请选择';

return "$title$show";

}

我们关键看这两句:

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 区域

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 区域

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,造成注入。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值