Destoon Sql注入漏洞之3

2014-04-04T00:00:00
ID SSV:94498
Type seebug
Reporter Root
Modified 2014-04-04T00:00:00

Description

简要描述:

过滤不严。

详细说明:

在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=&gt;$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("&lt;h2&gt;Invalid Referer&lt;/h2&gt;");');

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

foreach(array('#', '$', '&amp;', 'table', 'fields', 'password', 'payword', 'debug') as $v) {
    strpos($tag, $v) === false or exit('document.write("&lt;h2&gt;Bad Parameter&lt;/h2&gt;");');
}
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 &gt; 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) &lt; $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-&gt;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 &gt; 4) { if(is_numeric($catid)) { $CAT = $db-&gt;get_one("SELECT child,arrchildid,moduleid FROM {$db-&gt;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-&gt;pre}category WHERE catid IN ($catid)"; echo $sql;exit;

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

漏洞证明:

<img src="https://images.seebug.org/upload/201404/0420513556a0426261f431e976228b6e05609c12.jpg" alt="d1.jpg" width="600" onerror="javascript:errimg(this);">

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

<img src="https://images.seebug.org/upload/201404/04205326138f76190f16233c710ef56f05d6b86a.jpg" alt="d2.jpg" width="600" onerror="javascript:errimg(this);">

相等即执行。