sql報錯注入原理分析

研究人員發現,使用group by子句結合rand()函數以及像count(*)這樣的聚合函數,在SQL查詢時會出現錯誤,且錯誤是隨機產生的,這就產生了雙重查詢注入。

到底爲什麼floor()、rand(0)、count()、group by相結合,會產生這種錯誤呢?轉載以前烏雲一位哥的文章:

種子值爲0的rand()函數的輸出幾乎固定爲01101
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述

Okay let get it straight:
在這裏插入圖片描述
關鍵點在於:在插入虛擬表的時候又要執行一次rand(0),而插入前後rand(0)的值可能出現改變。

rand(0):01101
執行rand(0)[ 第一次 ]:0 / 執行concat函數時,準備插入虛擬表時發現沒有等於0的key,於是再執行rand(0)[ 第二次 ]:1
發現沒有等於1的key。成功插入之。

執行rand(0)[ 第三次 ]:1 / 執行concat函數時,準備插入虛擬表時發現等於1的key,於是count直接+1

執行rand(0)[ 第四次 ]:0 / 執行concat函數時,準備插入虛擬表時發現沒有等於0的key,於是再執行rand(0)[ 第五次 ]:1,卻發現已經有了等於1的key。報錯。

深層次的原因:
通過floor報錯的方法來爆數據的本質是group by語句的報錯。group by語句報錯的原因是floor(random(0)*2)的不確定性,即可能爲0也可能爲1(group by key的原理是循環讀取數據的每一行,將結果保存於臨時表中。讀取每一行的key時,如果key存在於臨時表中,則不在臨時表中則更新臨時表中的數據;如果該key不存在於臨時表中,則在臨時表中插入key所在行的數據。group by floor(random(0)*2)出錯的原因是key是個隨機數,檢測臨時表中key是否存在時計算了一下floor(random(0)*2)可能爲0,如果此時臨時表只有key爲1的行不存在key爲0的行,那麼數據庫要將該條記錄插入臨時表,由於是隨機數,插時又要計算一下隨機值,此時floor(random(0)*2)結果可能爲1,就會導致插入時衝突而報錯。即檢測時和插入時兩次計算了隨機數的值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章