【轉載】Mysql報錯注入原理分析(count()、rand()、group by)

Mysql報錯注入原理分析(count()、rand()、group by)

0x00 疑問


一直在用mysql數據庫報錯注入方法,但為何會報錯?

image

百度谷歌知乎了一番,發現大家都是把官網的結論發一下截圖,然后執行sql語句證明一下結論,但是沒有人去深入研究為什么rand不能和order by一起使用,也沒徹底說明三者同時使用報錯的原理。

image

0x01 位置問題?


select count(),(floor(rand(0)2))x from information_schema.tables group by x; 這是網上最常見的語句,目前位置看到的網上sql注入教程,floor 都是直接放count(*) 后面,為了排除干擾,我們直接對比了兩個報錯語句,如下圖

image

由上面的圖片,可以知道報錯跟位置無關。

0x02 絕對報錯還是相對報錯?


是不是報錯語句有了floor(rand(0)*2)以及其他幾個條件就一定報錯?其實并不是如此,我們先建建個表,新增一條記錄看看,如下圖:

image

確認表中只有一條記錄后,再執行報錯語句看看,如下圖:

image

多次執行均未發現報錯。

然后我們新增一條記錄。

image

然后再測試下報錯語句

image

多次執行并沒有報錯

OK 那我們再增加一條

image

執行報錯語句

image

ok 成功報錯

由此可證明floor(rand(0)*2)報錯是有條件的,記錄必須3條以上,而且在3條以上必定報錯,到底為何?請繼續往下看。

0x03 隨機因子具有決定權么(rand()和rand(0))


為了更徹底的說明報錯原因,直接把隨機因子去掉,再來一遍看看,先看一條記錄的時候,如下圖:

image

一條記錄的話 無論執行多少次也不報錯

然后增加一條記錄。

兩條記錄的話 結果就變成不確定性了

image
image
image

隨機出現報錯。

然后再插入一條

三條記錄之后,也和2條記錄一樣進行隨機報錯。

由此可見報錯和隨機因子是有關聯的,但有什么關聯呢,為什么直接使用rand(),有兩條記錄的情況下就會報錯,而且是有時候報錯,有時候不報錯,而rand(0)的時候在兩條的時候不報錯,在三條以上就絕對報錯?我們繼續往下看。

0x04 不確定性與確定性


前面說過,floor(rand(0)2)報錯的原理是恰恰是由于它的確定性,這到底是為什么呢?從0x03我們大致可以猜想到,因為floor(rand()2)不加隨機因子的時候是隨機出錯的,而在3條記錄以上用floor(rand(0)2)就一定報錯,由此可猜想floor(rand()2)是比較隨機的,不具備確定性因素,而floor(rand(0)*2)具備某方面的確定性。

為了證明我們猜想,分別對floor(rand()2)和floor(rand(0)2)在多記錄表中執行多次(記錄選擇10條以上),在有12條記錄表中執行結果如下圖:

image

連續3次查詢,毫無規則,接下來看看select floor(rand(0)*2) from T-Safe;,如下圖:

image

可以看到floor(rand(0)*2)是有規律的,而且是固定的,這個就是上面提到的由于是確定性才導致的報錯,那為何會報錯呢,我們接著往下看。

0x05 count與group by的虛擬表


使用select count(*) from T-Safe group by x;這種語句的時候我們經常可以看到下面類似的結果:

image

可以看出 test12的記錄有5條

與count()的結果相符合,那么mysql在遇到select count() from TSafe group by x;這語句的時候到底做了哪些操作呢,我們果斷猜測mysql遇到該語句時會建立一個虛擬表(實際上就是會建立虛擬表),那整個工作流程就會如下圖所示:

  1. 先建立虛擬表,如下圖(其中key是主鍵,不可重復):
image

2.開始查詢數據,取數據庫數據,然后查看虛擬表存在不,不存在則插入新記錄,存在則count(*)字段直接加1,如下圖:

image

由此看到 如果key存在的話就+1, 不存在的話就新建一個key。

那這個和報錯有啥內在聯系,我們直接往下來,其實到這里,結合前面的內容大家也能猜個一二了。

0x06 floor(rand(0)*2)報錯


其實mysql官方有給過提示,就是查詢的時候如果使用rand()的話,該值會被計算多次,那這個“被計算多次”到底是什么意思,就是在使用group by的時候,floor(rand(0)2)會被執行一次,如果虛表不存在記錄,插入虛表的時候會再被執行一次,我們來看下floor(rand(0)2)報錯的過程就知道了,從0x04可以看到在一次多記錄的查詢過程中floor(rand(0)2)的值是定性的,為011011…(記住這個順序很重要),報錯實際上就是floor(rand(0)2)被計算多次導致的,具體看看select count() from TSafe group by floor(rand(0)2);的查詢過程:

1.查詢前默認會建立空虛擬表如下圖:

image

2.取第一條記錄,執行floor(rand(0)2),發現結果為0(第一次計算),查詢虛擬表,發現0的鍵值不存在,則floor(rand(0)2)會被再計算一次,結果為1(第二次計算),插入虛表,這時第一條記錄查詢完畢,如下圖:

image

3.查詢第二條記錄,再次計算floor(rand(0)2),發現結果為1(第三次計算),查詢虛表,發現1的鍵值存在,所以floor(rand(0)2)不會被計算第二次,直接count(*)加1,第二條記錄查詢完畢,結果如下:

image

4.查詢第三條記錄,再次計算floor(rand(0)2),發現結果為0(第4次計算),查詢虛表,發現鍵值沒有0,則數據庫嘗試插入一條新的數據,在插入數據時floor(rand(0)2)被再次計算,作為虛表的主鍵,其值為1(第5次計算),然而1這個主鍵已經存在于虛擬表中,而新計算的值也為1(主鍵鍵值必須唯一),所以插入的時候就直接報錯了。

5.整個查詢過程floor(rand(0)*2)被計算了5次,查詢原數據表3次,所以這就是為什么數據表中需要3條數據,使用該語句才會報錯的原因。

0x07 floor(rand()*2)報錯


由0x05我們可以同樣推理出不加入隨機因子的情況,由于沒加入隨機因子,所以floor(rand()*2)是不可測的,因此在兩條數據的時候,只要出現下面情況,即可報錯,如下圖:

image

最重要的是前面幾條記錄查詢后不能讓虛表存在0,1鍵值,如果存在了,那無論多少條記錄,也都沒辦法報錯,因為floor(rand()*2)不會再被計算做為虛表的鍵值,這也就是為什么不加隨機因子有時候會報錯,有時候不會報錯的原因。如圖:

image

當前面記錄讓虛表長成這樣子后,由于不管查詢多少條記錄,floor(rand()2)的值在虛表中都能找到,所以不會被再次計算,只是簡單的增加count()字段的數量,所以不會報錯,比如floor(rand(1)*2),如圖:

image

在前兩條記錄查詢后,虛擬表已經存在0和1兩個鍵值了,所以后面再怎么弄還是不會報錯。

總之報錯需要count(*),rand()、group by,三者缺一不可。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373