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

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

缺陷编号:wooyun-2014-055593

漏洞标题:Destoon Sql注入漏洞之3

相关厂商:DESTOON

漏洞作者: ′雨。

提交时间:2014-04-04 21:38

修复时间:2014-07-03 21:39

公开时间:2014-07-03 21:39

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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

简要描述:

过滤不严。

详细说明:

在api/js.php中

if($_SERVER['QUERY_STRING']) {
$exprise = isset($_GET['tag_expires']) ? intval($_GET['tag_expires']) : 0;
$moduleid = isset($_GET['moduleid']) ? intval($_GET['moduleid']) : 0;
$moduleid > 3 or exit('document.write("<h2>Bad Parameter</h2>");');
$tag = $_SERVER['QUERY_STRING'];

$_SERVER['QUERY_STRING'] = $_SERVER['REQUEST_URI'] = '';
foreach($_GET as $k=>$v) { unset($$k); }
$_GET = array();
require '../common.inc.php';
header("Content-type:text/javascript");

($DT['jstag'] && $DT['safe_domain'] && check_referer()) or exit('document.write("<h2>Invalid Referer</h2>");');

$tag = strip_sql(stripslashes(urldecode($tag)));

foreach(array('#', '$', '&amp;', 'table', 'fields', 'password', 'payword', 'debug') as $v) {
strpos($tag, $v) === false or exit('document.write("<h2>Bad Parameter</h2>");');
}
ob_start();

tag($tag, $exprise);


在这里。 ($DT['jstag'] && $DT['safe_domain'] && check_referer()) or exit('document.write("<h2>Invalid Referer</h2>");');
绕过这个的话 只要safe domain里面有植就行 无论为什么。
然后check_referer 自己修改一下referer 就可以绕过了。

function strip_sql($string) {
$search = array("/union/i","/0x([a-z0-9]{2,})/i","/select([[:space:]\*\/\-])/i","/update([[:space:]\*\/])/i","/replace([[:space:]\*\/])/i","/delete([[:space:]\*\/])/i","/drop([[:space:]\*\/])/i","/outfile([[:space:]\*\/])/i","/dumpfile([[:space:]\*\/])/i","/load_file\(/i","/substring\(/i","/substr\(/i","/concat\(/i","/concat_ws\(/i","/ascii\(/i","/hex\(/i","/ord\(/i","/char\(/i");
$replace = array('unio&#110;','0&#120;\\1','selec&#116;\\1','updat&#101;\\1','replac&#101;\\1','delet&#101;\\1','dro&#112;\\1','outfil&#101;\\1','dumpfil&#101;\\1','load_fil&#101;(','substrin&#103;(','subst&#114;(','conca&#116;(','concat_w&#115;(','asci&#105;(','he&#120;(','or&#100;(','cha&#114;(');
return is_array($string) ? array_map('strip_sql', $string) : preg_replace($search, $replace, $string);
}


然后绕过这个的话 利用这里的deocode来绕过。

function tag($parameter, $expires = 0) {
global $DT, $CFG, $MODULE, $DT_TIME, $db;
if($expires > 0) {
$tag_expires = $expires;
} else if($expires == -2) {
$tag_expires = $CFG['db_expires'];
} else if($expires == -1) {
$tag_expires = 0;
} else {
$tag_expires = $CFG['tag_expires'];
}
$tag_cache = false;
$db_cache = ($expires == -2 || defined('TOHTML')) ? 'CACHE' : '';
if($tag_expires && $db_cache != 'CACHE' && strpos($parameter, '&page=') === false) {
$tag_cache = true;
$TCF = DT_CACHE.'/tag/'.md5($parameter).'.htm';
if(is_file($TCF) && ($DT_TIME - filemtime($TCF) < $tag_expires)) {
echo substr(file_get($TCF), 17);
return;
}
}
$parameter = str_replace(array('&amp;', '%'), array('', '##'), $parameter);
parse_str($parameter, $par);
if(!is_array($par)) return '';
$par = dstripslashes($par);
extract($par, EXTR_SKIP);
isset($prefix) or $prefix = $db->pre;
isset($moduleid) or $moduleid = 1;
if(!isset($MODULE[$moduleid])) return '';
isset($fields) or $fields = '*';
isset($catid) or $catid = 0;
isset($child) or $child = 1;
isset($areaid) or $areaid = 0;
isset($areachild) or $areachild = 1;
isset($dir) or $dir = 'tag';
isset($template) or $template = 'list';
isset($condition) or $condition = '1';
isset($group) or $group = '';
isset($page) or $page = 1;
isset($offset) or $offset = 0;
isset($pagesize) or $pagesize = 10;
isset($order) or $order = '';
isset($showpage) or $showpage = 0;
isset($showcat) or $showcat = 0;
isset($datetype) or $datetype = 0;
isset($target) or $target = '';
isset($class) or $class = '';
isset($length) or $length = 0;
isset($introduce) or $introduce = 0;
isset($debug) or $debug = 0;
isset($lazy) or $lazy = 0;
(isset($cols) && $cols) or $cols = 1;
if($catid) {
if($moduleid > 4) {
if(is_numeric($catid)) {
$CAT = $db->get_one("SELECT child,arrchildid,moduleid FROM {$db->pre}category WHERE catid=$catid");
$condition .= ($child && $CAT['child'] && $CAT['moduleid'] == $moduleid) ? " AND catid IN (".$CAT['arrchildid'].")" : " AND catid=$catid";
} else {
if($child) {
$catids = '';
$sql="SELECT arrchildid FROM {$db->pre}category WHERE catid IN ($catid)";
echo $sql;exit;


在这里 把语句输出来。 测试一下语句。

漏洞证明:

d1.jpg


需要把referer修改成域名才能绕过check_referer
这里decode 那就用%2b来绕过空格。
过滤了substr 那就left 。 过滤了char 但是char (97)这样依旧可以执行。
基本就绕完了。

d2.jpg


相等即执行。

修复方案:

过滤。

版权声明:转载请注明来源 ′雨。@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:10

确认时间:2014-04-08 12:27

厂商回复:

感谢提醒,我们会尽快修复

最新状态:

暂无


漏洞评价:

评论