| 网站首页 | Vip会员区 | 教程 | 下载 | 图片 | QQ家园 | 免费资源 | 在线服务 | 论坛 | 博客 | 程序开发 | It学堂 | 作品发布 | 
站点相关
代刻黑客光盘或订做光盘

精品软件程序定制

为您的网站或者服务器保驾护航
相关内容
最 新 热 门
相 关 文 章
没有相关文章
您现在的位置: 红色黑客联盟 >> 教程 >> 黑客技术 >> 脚本攻防 >> 正文
Dedecms V5可执行文件上传漏洞
文章录入:7747.Net    责任编辑:7747.Net  更新时间:2008-7-17 1:17:36

【字体:

发布时间:2008-06-11
SBEUGID:SEBUGV2008073605
影响版本:
Dedecms V5
描述:
这是一个比较有意思的东西,但是成功利用起来并不容易,呵呵。
首先看config_rglobals.php文件,摘的一段代码如下。这里作者本意是为了帮我们注册变量的,但是他却疏忽了我们不但能注册变量,还能覆盖一些变量。config_rglobals_magic.php也有同样的问题
…………………………………………………………………………

if(is_array($_GET)){

 


foreach($_GET AS $key => $value){ $$key = $value; }

 

}//可以覆盖任意变量

 

…………


…………………………………………………………………………


说这个是漏洞还太早了,要结合下面的代码看到底有没有好利用的地方,看config_base.php文件可以发现这样一段代码


…………………………………………………………………………

…………

 

//载入用户配置的系统变量

 

require_once(DEDEINC."/config_hand.php");

 

…………

 

if($phpold==1){ //低版本强制检查变量

 


$cfg_isMagic = false;

 


$cfg_registerGlobals = false;

 

}else{

 


$cfg_registerGlobals = @ini_get("register_globals");

 


$cfg_isMagic = @ini_get("magic_quotes_gpc");

 

}

 

 


//检测系统是否注册外部变量

 

if(!$cfg_isMagic) require_once(DEDEINC."/config_rglobals_magic.php");

 

else if(!$cfg_registerGlobals || $cfg_needFilter) require_once(DEDEINC."/config_rglobals.php");


…………………………………………………………………………

 

从这里可以看出,在register_globals=off 我们可以注册自己的变量并覆盖之前的值。而在register_globals=on时由于服务器配置的原因,ini_get()函数在很多时候是会失效的。简单的说,就是即使register_globals=On,也可能是ini_get('register_globals') =FALSE,所以依旧可以导致变量覆盖。但是能覆盖的只能是在这之前的内容,向前找看到config_hand.php文件里面定义的值似乎都能覆盖,但是真的能覆盖吗?再向前看到这样的代码,原来程序还是有考虑的

…………………………………………………………………………

 

//全局安全检测

 

foreach($ckvs as $ckv){

 


foreach($$ckv AS $_k => $_v){

 


if(eregi("^(globals|cfg_)",$_k)) unset(${$ckv}[$_k]);

 


}

 

}

 

………………………………………………………………………

 

上面代码的意思是cfg_开头的变量不让从外部提交,发现了就unset掉,这样看的话config_hand.php里面cfg_开头的全局变量都是不让我们覆盖的。看到这里也许有人觉得没戏了。厄,多数情况下是这样的,但是别忘记了我们还有Zend_Hash_Del_Key_Or_Index漏洞,在PHP < 4.4.3, 5 <= PHP < 5.1.4时这个unset并不能释放我们的变量,于是这里就带来了隐患。

 

 


下面说个有意思的利用方式,就是选择覆盖$cfg_mediatype来上传任意文件呢?但是这个地方是有限制的,在config_base.php中用require_once函数调用文件config_rglobals.php之前有一段这样的代码

 

………………………………………………………………

 

//检测上传的文件中是否有危险代码,有直接退出处理

 

if( !isset($cfg_NoUploadSafeCheck) ){

 

if (is_array($_FILES)) {

 


foreach($_FILES AS $_name => $_value){

 


${$_name} = $_value['tmp_name'];

 


$_fp = @fopen(${$_name},'r');

 


$_fstr = @fread($_fp,filesize(${$_name}));

 


@fclose($_fp);

 


if($_fstr!='' && ereg("<(\?|%)",$_fstr)){

 


echo "你上传的文件中含有危险内容,程序终止处理!";

 

 

exit();

 


}

 


}

 

}}

 

…………………………………………………………………

 

只有$cfg_NoUploadSafeCheck非空才可以绕过这段检查但是由于在这段代码后才用函数require_once来调用文件config_rglobals.php注册变量,所以只有在php设置register_globals=on时我们才可以提交$cfg_NoUploadSafeCheck绕过过滤上传php脚本

 

下面我们来看如何具体利用,看文件

 

…………………………………………………………

 

\include\dialoguser\medias_upload.php

 

…………

 

if(!CheckAddonType($uploadfile_name)){

 


ShowMsg("你所上传的文件类型被禁止,系统只允许上传<br>".$cfg_mb_mediatype." 类型附件!","-1");

 


exit();

 

}

 

 

 


$fs = explode(".",$uploadfile_name);

 

$sname = trim($fs[count($fs)-1]);

 

if($sname==''){

 


ShowMsg("你所上传的文件无法识别,系统禁止上传<br />","-1");

 


exit();

 

}

 


$nowtme = mytime();

 


$filename_name = dd2char($cfg_ml->M_ID."0".strftime("%y%m%d%H%M%S",$nowtme)."0".mt_rand(1000,9999));

 

$filename = $filename_name.".".$sname; //这里用不带目录的文件名作标题

 


$fileurl = $rootdir."/".$filename;

 

$fullfilename = $cfg_basedir.$fileurl;

 


//严格检查最终的文件名

 

if(!CheckAddonType($fullfilename) || eregi("\.(php|asp|pl|shtml|jsp|cgi|aspx)",$fullfilename)){

 


ShowMsg("你所上传的文件类型被禁止,系统只允许上传<br>".$cfg_mb_mediatype." 类型附件!","-1");

 


exit();

 

}

 


@move_uploaded_file($uploadfile,$fullfilename);

 

……

 

……………………………………………………………………….

 

 


对于检查最终的文件名部分的代码,asa并不在黑名单里面。剩下的就是CheckAddonType函数的过滤了,我们找到相关代码

 

 


……………………………………………………………………

 

\\include\inc_memberlogin.php

 

//检测用户的附件类型

 

function CheckAddonType($aname){

 


global $cfg_mb_mediatype;

 


if(empty($cfg_mb_mediatype)){

 


$cfg_mb_mediatype = "jpg|gif|png|bmp|swf|mpg|mp3|rm|rmvb|wmv|asf|wma|zip|rar|doc|xsl|ppt|wps";

 


}

 


$anames = explode('.',$aname);

 


$atype = $anames[count($anames)-1];

 


if(count($anames)==1) return false;

 


else{

 


$atype = strtolower($atype);

 


$cfg_mb_mediatypes = explode('|',trim($cfg_mb_mediatype));

 


if(in_array($atype,$cfg_mb_mediatypes)) return true;

 


else return false;

 

}

}

……………………………………………………………………………..
依然是依据$cfg_mb_mediatype来过滤的,综合上面的分析,可以将之覆盖为asa来达到我们的目的。实战中要利用起来真不容易,需要ini_get失效,register_globals 为on,php本身Zend_Hash_Del_Key_Or_Index的洞没有被修补,还有更不幸的是需要支持asa。
<* 参考
Flyh4t[W.S.T]

http://www.wolvez.org
*>
SEBUG安全建议:
暂无
// Sebug.net [ 2008-07-12 ]
本安全信息由SEBUG翻译整理,版权所有,未经许可,不得转载

本信息来源于SEBUG Security Database - 漏洞信息库
原文链接:http://www.sebug.net/vulndb/3605/

您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力
  • 上一篇文章:

  • 下一篇文章: 没有了
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
     | 设为首页 | 加入收藏 | 广告服务 | 我要投稿 | 关于我们 | 版权申明 | 免责声明 | 隐私声明 | 网站地图 |