zoukankan      html  css  js  c++  java
  • ThinkPHP3.2.3框架exp注入

    这个注入与bind注入差不多

    环境搭建

    直接在IndexController.class.php中创建一个demo

    public function index(){
            $map=array();
            $map['id']=$_GET['id'];
            $data=M('users')->where($map)->find();
            dump($data);
        }
    

    数据库配置:

    <?php
    return array(
        //'配置项'=>'配置值'
        'DB_TYPE'           =>  'mysql',
        'DB_HOST'           =>  'localhost',
        'DB_NAME'           =>  'thinkphp',
        'DB_USER'           =>  'root',
        'DB_PWD'            =>  'root',
        'DB_PORT'           =>  '3306',
        'DB_FIELDS_CACHE'   =>  true,
        'SHOW_PAGE_TRACE'   =>  true,
    );
    

    漏洞分析

    payload:

    http://127.0.0.1/thinkphp32/index.php?id[0]=exp&id[1]==1%20and%20updatexml(1,concat(0x7,user(),0x7e),1)
    

    indexController.class.php

    <?php
    namespace HomeController;
    use ThinkController;
    class IndexController extends Controller {
        public function index(){
            $map=array();
            $map['id']=$_GET['id'];
            $data=M('users')->where($map)->find();
            dump($data);
        }
    }
    

    可以看到这里并没有使用I函数使用I函数则不会产生exp注入),原因我们在之后分析,我们先来分析这个注入。直接跟入where函数:

    image-20201015115649820

    可以看到跟以前一样,由于传入的是数组,直接将id数组赋值给了$this->options['where'],然后返回。

    继续跟入find,还是跟以前一样,需要关注的两个位置是:

    $options            =   $this->_parseOptions($options);
    $resultSet          =   $this->db->select($options);
    

    先来跟入$this->_parseOptions($options);

    /**
     * 分析表达式
     * @access protected
     * @param array $options 表达式参数
     * @return array
     */
    protected function _parseOptions($options=array()) {
        if(is_array($options))
            $options =  array_merge($this->options,$options);
    
        if(!isset($options['table'])){
            // 自动获取表名
            $options['table']   =   $this->getTableName();
            $fields             =   $this->fields;
        }else{
            // 指定数据表 则重新获取字段列表 但不支持类型检测
            $fields             =   $this->getDbFields();
        }
    
        // 数据表别名
        if(!empty($options['alias'])) {
            $options['table']  .=   ' '.$options['alias'];
        }
        // 记录操作的模型名称
        $options['model']       =   $this->name;
    
        // 字段类型验证
        if(isset($options['where']) && is_array($options['where']) && !empty($fields) && !isset($options['join'])) {
            // 对数组查询条件进行字段类型检查
            foreach ($options['where'] as $key=>$val){
                $key            =   trim($key);
                if(in_array($key,$fields,true)){
                    if(is_scalar($val)) {
                        $this->_parseType($options['where'],$key);
                    }
                }elseif(!is_numeric($key) && '_' != substr($key,0,1) && false === strpos($key,'.') && false === strpos($key,'(') && false === strpos($key,'|') && false === strpos($key,'&')){
                    if(!empty($this->options['strict'])){
                        E(L('_ERROR_QUERY_EXPRESS_').':['.$key.'=>'.$val.']');
                    } 
                    unset($options['where'][$key]);
                }
            }
        }
        // 查询过后清空sql表达式组装 避免影响下次查询
        $this->options  =   array();
        // 表达式过滤
        $this->_options_filter($options);
        return $options;
    }
    

    可以看到由于传入数组所以在if(is_scalar($val))处并没有进入_parseType进行类型转换,最后返回,接下分析$this->db->select($options):

    image-20201015150208317

    继续进入$this->buildSelectSql($options);:

    image-20201015150319934

    然后是$this->parseSql($this->selectSql,$options);:

    image-20201015150358691

    之后重点在这个parseWhere中的parseWhereItem函数,和bind基本一样。

    image-20201015150849893

    可以看到在parseWhereItem直接进行了拼接,拼接结果为:

    `id` =1 and updatexml(1,concat(0x7,user(),0x7e),1)
    

    最后返回最终拼接结果为:

    image-20201015151103214

    造成了sql注入。

    最后回到一开始的I函数问题,在I函数内部的think_filter中,对exp进行了正则匹配,如果匹配到了会在其后面加空格,从而使得后面的将会对其进行处理无法正确拼接sql注入语句。

    image-20201015153932710

    image-20201015154337895

    修复

    在取出传入参数时使用I函数即可避免产生exp注入。

    参考

    1. ThinkPHP漏洞分析集合
    2. 代码审计之Thinkphp3.2.3
  • 相关阅读:
    python-深入学习
    python-第一天学习python
    JMeter-关联、添加压力机、linux下运行、抓包、手机抓包等学习
    python模块---常用模块2
    python模块---常用模块
    python函数--装饰器
    python函数--匿名函数,内置函数,闭包
    python函数--生成器,生成器表达式,列表推导式
    python函数--global,nonlocal ,新格式化输出,迭代器
    python函数--万能参数,形参,名称空间,嵌套,内置函数globals locals ,关键字nonlocal global
  • 原文地址:https://www.cnblogs.com/lktop/p/13824846.html
Copyright © 2011-2022 走看看