thinkphp5.0.9预处理导致的sql注入复现与详细分析
復現
先搭建thinkphp5.0.9環境
配置下測試環境
然后訪問
http://tptest.cc/index.php/index/index/getage?names[0,updatexml(0,concat(0xa,user()),0)]=1
復現成功
【點擊獲取學習資料】
-
滲透工具
-
技術文檔、書籍
最新大廠面試題目及答案 -
視頻教程
-
應急響應筆記
-
學習思路構圖等等
漏洞分析
先看看傳進來了什么
是一個關聯數組
跟進where
跟進parseWhereExp,看了一番,就是普通的對where參數解析
繼續跟進select
Query的select函數從這里開始,構造的sql語句就出問題了
繼續跟進builder->select -> parseWhere -> buildWhere -> parseWhereItem
在這里將關聯數組的key拼接了上去
正常查詢,傳參names[]=li,構造出來的應該是這樣
生成的預處理sql應該是這樣,where_name_in_0會被替換為li
而惡意payload,生成的是
看一下最終生成的sql語句
調試發現,預處理發生了錯誤,但是報錯注入成功,語句被執行了?預處理時執行了sql語句?
想調試下,但是這條語句,進不去,不能調試,,不知道什么原因,
$this->PDOStatement = $this->linkID->prepare($sql);
在網上看到了p神的文章
https://www.leavesongs.com/PENETRATION/thinkphp5-in-sqlinjection.html
就是說在PDO::ATTR_EMULATE_PREPARES => false模式下,預處理是假的,邊替換邊執行,這就可以解
釋得通了
找一下不能子查詢的原因
構造payload:
?names[0,updatexml(0,concat(0xa,(select group_concat(SCHEMA_NAME) from information_schema.SCHEMATA
)),0)]=1
預處理沒有報錯
但在$result = $this->PDOStatement->bindValue($param, $val[0], $val[1]);時報錯
應該是PDO的預處理,不能解析這一長串
那就從param入手看一下,
param來自$bind
$bind來自上面遇到過的
想繞過就要讓$bindKey變為where_name_in_0,,但是構造的sql語句不變,做不到,立刻放棄
令我疑惑的兩個點
user()查詢是在預處理時報錯退出的,子查詢是在綁定key-value時退出的
而且使用子查詢,PDO是解析成功了的,在mysql日志看到如下
使用user()查詢日志:
直接用sql語句查日志
為什么PDO調用user(),在mysql日志看不到記錄
搞不懂
總結
thinkphp沒有對輸入過濾,直接做拼接
眾所周知預處理不能處理in,order by這些動態的變量,所以審計的時候可以重點看一下
這個漏洞沒什么用,不過可以當個練習了
造成這個漏洞的原因一是thinkphp沒有對輸入進行過濾,直接將輸入拼接。二是由于PDO的特性,在預處理時把代碼執行了
如何修復
看5.0.22,已經修復
select生成的語句沒有我們構造的內容了
繼續調試,bindkey后面不使用key拼接了,而是使用遞增的i
這是5.0.9的
總結
以上是生活随笔為你收集整理的thinkphp5.0.9预处理导致的sql注入复现与详细分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学了这些技术就能轻松找到一份待遇不错的岗
- 下一篇: 使用FUSE挖掘文件上传漏洞