日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql的count报错_Mysql报错注入原理分析(count()、rand()、group by)

發布時間:2023/12/2 数据库 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql的count报错_Mysql报错注入原理分析(count()、rand()、group by) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

前提:當行數大于等于3行時才會報錯。

原鏈接:https://www.cnblogs.com/xdans/p/5412468.html

幾個fool()原理解釋:

select

count(*),floor(rand(0)*2) from test group by floor(rand(0)*2)

首先看經典的floor注入語句:

and select 1 from (select

count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables

group by x)a)

第一眼看起來有些懵逼,我們來從最基本的入手,最后在分析這個語句

首先是floor()報錯產生的條件:

select count(*)

,floor(rand(0)*2)x from security.users group by x(自定義數據庫的一張表)

這里解釋一下x是什么意思,可能有些同學不太熟悉sql語句,floor(rand(0)*2)x的x是為floor(rand(0)*2)添加了一個別名,就是x就等于floor(rand(0)*2),這樣做的目的是

讓group by 和 floor(rand(0)*2)相遇(請原諒我這么解釋),

下一步我們在報錯位置處加上我們想要的子查詢,用concat()拼接:

select count(*)

,concat(database(),floor(rand(0)*2))x from security.users group by x

security就是我們想要的數據庫名,1是上一步拼接的。

但現在是不是就可以直接使用了呢?還有幾個步驟,先看直接拼接到and 后會怎樣:

select * from security.users

where id=1 and (select count(*) ,concat(database(),floor(rand(0)*2)x) from

security.users group by x)

報了一個錯,百度一番發現引發這個錯誤的原因很多,這里我是覺得我們構建的select語句的結果是一個結果表,而and 需要一個布爾值,也就是0或非零的值,那我們在嵌套一個查詢,前面說了select 的結果是一個結果表,那我們就可再從這個表執行查詢,只不過這次select的值是非零數字:

select 1 from (select

count(*) ,concat(database(),floor(rand(0)*2))x from security.users group by x)a

再啰嗦一句,最后這個a和之前解釋的x的作用是一樣的,是前面括號內容的別名,

sql語句要求在查詢結果的基礎上再執行查詢時,必須給定一個別名。

嵌套進and后執行

select * from security.users

where id=1 and(select 1 from (select count(*)

,concat(database(),floor(rand(0)*2))x from security.users group by x)a)

大功告成

我們完成了剛開始引入的floo()注入語句

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

隨機因子指的是rand(x)

x是否有。

當插入一條記錄時,不報錯。

增加一條記錄,有時候報錯。

再增加一條記錄也和2條記錄一樣進行隨機報錯。

三條及以上和2條記錄一樣進行隨機報錯。

分別對floor(rand()*2)和floor(rand(0)*2)在多記錄表中執行多次(記錄選擇10條以上),在有12條記錄表中執行結果如下圖:

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

可以看到floor(rand(0)*2)是有規律的,而且是固定的。

二 count與group by的虛擬表

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

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

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

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

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

1.查詢的時候如果使用rand()的話,該值會被計算多次,就是在使用group by的時候,floor(rand(0)*2)會被執行一次,如果虛表不存在記錄,插入虛表的時候會再被執行一次,以此類推。

注:使用group by,即虛表存儲是按照group by 計算的那一列來從上往下來計算,取一條記錄判斷虛表是否存在時會使函數執行一遍,當存入的時候(即表中key值無此值)會將原函數存入,但是存的內容是最終結果,即原函數會被再次執行結果存入虛表,當表中有此鍵值對,那么只需count+1,不用再存key,所以比較時會計算一次,存入時又會計算一次。

2.在使用count(*)時,如

select count(*) from test group by x;? x=floor(rand(0)*2)

mysql執行此句時會創建一個虛表,虛表一共兩個字段主鍵是x,另外一個字段是count(*)

3.首先知道floor(rand(0)*2)的值為011011...,

4.執行的過程(floor(rand(0)*2)報錯的原因):(插入之前是表面顯示數據,實際比較時和存儲時為表面數據計算之后的結果,這取決于數據庫的一種存儲機制,表面的sql語句會被審查,然后執行存入數據庫,再回顯數據庫中存的內容,即結果)

select count(*) from test group by floor(rand(0)*2) ;

select count(*),floor(rand(0)*2) from test group by floor(rand(0)*2) ;

(這個位置的floor(..))有沒有無所謂用不到

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

2).開始執行,查詢第一條記錄(即數據),在使用group by時 floor(rand(0)*2)執行一次,結果為0,即x=0(第一次執行),然后發現虛表中沒有key=0的鍵值對記錄,則floor(rand(0)*2)會被存入虛表,存入時會被計算為實際的值,即會被再執行一次(第二次執行),結果為1插入虛表,同時count由0變1。

3)取第二條記錄,floor(rand(0)*2)執行一次,結果為1(第三次執行),查詢虛表,發現虛表中有1,則直接count+1,不用再存key,所以floor(rand(0)*2)不會再被計算。

4).取第三條記錄,floor(rand(0)*2)執行一次,結果為0,發現虛表中沒有key=0,那么floor(rand(0)*2)會再次執行并存入虛表,此次計算結果為1(第五次執行),與已有的key沖突了,所以插入時報錯。

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

四 floor(rand()*2)報錯

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

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

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

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

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

總結

以上是生活随笔為你收集整理的mysql的count报错_Mysql报错注入原理分析(count()、rand()、group by)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。