cmseasy某处sql注入,无视防御
从/celive/live/index.php开始:include('include/config.inc.php'); include_once(CE_ROOT . '/include/celive.class.php'); $ac = addslashes($_GET['action']); if ($ac == '1') { $live = new celive(); $live->template(); $live->xajax_live(); ... ... ... ... ... ...
先包含了两个文件,而这两个文件并没有对传入参数进行过滤。 当\$_GET['action']为1时,调用$live->xajax_live() \celive\include\celive.class.php:480
function xajax_live() { if (!$this->xajax_live_flag) { $this->xajax_live_flag=true; include_once(dirname(__FILE__).'/xajax.inc.php'); include_once(dirname(__FILE__).'/xajax.class.php'); global $xajax_live; $xajax_live=new xajax(); $xajax_live->setCharEncoding('utf-8'); $xajax_live->decodeUTF8InputOn(); $xajax_live->registerFunction('Request'); $xajax_live->registerFunction('Postdata'); $xajax_live->registerFunction('ChatHistory'); $xajax_live->registerFunction('LiveMessage'); $xajax_live->registerFunction('EndChat'); $xajax_live->registerFunction('GetAdminEndChat'); $xajax_live->processRequests(); } }首先注册了一些函数,然后调用$xarax->processRequests()处理用户请求,processRequests()比较大,我们只分析有 漏洞 的部分。 \celive\include\xajax.class.php:266:
function processRequests() { $requestMode = -1; $sFunctionName = ""; $bFoundFunction = true; $bFunctionIsCatchAll = false; $sFunctionNameForSpecial = ""; $aArgs = array(); $sPreResponse = ""; $bEndRequest = false; $requestMode = $this->getRequestMode(); // 如果没有参数就退出 if ($requestMode == -1) return; if ($requestMode == XAJAX_POST) { $sFunctionName = $_POST["xajax"]; if (!empty($_POST["xajaxargs"])) $aArgs = $_POST["xajaxargs"]; } else { header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); $sFunctionName = $_GET["xajax"]; if (!empty($_GET["xajaxargs"])) $aArgs = $_GET["xajaxargs"]; }在初始化一堆变量后,开始获取用户传入的xajax和xajaxargs,这两参数一个是调用的函数名一个是函数参数。之后函数名放在\$sFunctionName里,参数被放在\$aArgs里。 如果函数不在已注册函数里就退出,函数列表里包括前面已注册的那些函数:
if ($bFoundFunction) { $sFunctionNameForSpecial = $sFunctionName; if (!array_key_exists($sFunctionName, $this->aFunctions)) { if ($this->sCatchAllFunction) { $sFunctionName = $this->sCatchAllFunction; $bFunctionIsCatchAll = true; } else { $bFoundFunction = false; $oResponse = new xajaxResponse(); $oResponse->addAlert("Unknown Function $sFunctionName."); } } }经过一系列判断与检查后,调用用户传入的函数:
if (!$bEndRequest) { if (!$this->_isFunctionCallable($sFunctionName)) { $oResponse = new xajaxResponse(); $oResponse->addAlert("The Registered Function $sFunctionName Could Not Be Found."); } else { if ($bFunctionIsCatchAll) { $aArgs = array($sFunctionNameForSpecial, $aArgs); } $oResponse = $this->_callFunction($sFunctionName, $aArgs); // 调用函数 }由于只能调用已注册函数,所以我检查了一遍已注册的那几个函数,在检查到LiveMessage函数时发现了漏洞: \celive\include\xajax.inc.php:182
function LiveMessage($a) { global $db; $sessionid = $_SESSION['sessionid']; $name = html specialchars($a['name']); $email = htmlspecialchars($a['email']); $country = htmlspecialchars($a['country']); $phone = htmlspecialchars($a['phone']); $departmentid = htmlspecialchars($a['departmentid']); $message = htmlspecialchars($a['message']); $timestamp = time(); $ip = $_SERVER['REMOTE_ADDR']; $sql = "INSERT INTO `chat` (`sessionid`,`name`,`email`,`phone`,`departmentid`,`message`,`timestamp`,`ip`,`status`) VALUES('" . $sessionid . "','" . $name . "','" . $email . "','" . $phone . "','" . $departmentid . "','" . $message . "','" . $timestamp . "','" . $ip . "','2')"; $db->query($sql); $sql = "DELETE FROM `sessions` WHERE `id`='" . $sessionid . "'"; $db->query($sql); $text = "<?php echo $lang[shout_success]?>\n"; $objResponse = new xajaxResponse('utf-8'); $objResponse->addAssign('content', 'innerHTML', $text); $objResponse->redirect('', 5); return $objResponse; }程序将用户传入的参数拼接到\$sql变量里,传入到$db->query($sql)函数中,我们跟进去查看是否有过滤。 \celive\include\database.class.php:135:
function query($sql, $table = '', $cache = '', $arg = '') { $line = explode("\n", $sql); if (count($line) == 1) { $line[0] = $this->prefix($line[0]); if ($table == '') { $table = $this->table; } return $this->raw_query($line[0], $table, $cache, $arg); } }继续跟进到$this->raw_query($line[0], $table, $cache, $arg)中发现全程没有过滤SQL语句被直接执行,因此存在SQL注入漏洞。
修复方案:对LiveMessage中的输入进行过滤
查看更多关于cmseasy sql注入漏洞(无视防御) - 网站安全 - 自学的详细内容...