MySQL報錯注入通過構造payload讓信息通過錯誤提示回顯出來,主要應用與查詢不回現內容,會打印錯誤信息。這里主要講一下十大報錯中的floor報錯。
floor()
payload構造:
select * from test where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);
關鍵函數說明:
rand函數可以產生一個0--1之間的隨機數;
而當rand()有了參數之后,他會對所查詢的每條數據產生一個隨機數,但是從時間角度看每次給的隨機數值是一樣的,所以這個隨機數是可以預測的,也叫偽隨機數。
floor函數,其功能是“向下取整”,或者說“向下舍入”、“向零取舍”,即取不大於x的最大整數。
這里配合rand使用-->floor(rand(1)*2)
rand()返回的是0到1之間的隨機數,乘2是為了讓他返回0到2之間的隨機數,組合floor()的取整,這里返回的值只能是0和1;
groud by 對數據進行分組;可以看到原表中pid有0、1和2三種值,通過order by分組可以更清晰看到。
count(*) 簡單說就是個計數的函數;這里和group by合用用來計算每個分組出現的次數
該語句在運行時mysql會建立一個虛擬表,在查詢數據的時候,首先查看該虛擬表中是否存在該分組,如果存在那么計數值加1,不存在則新建該分組。
報錯分析
rand()的特殊性
select count(*) from test group by floor(rand(0)*2);
因為 rand 函數的特殊性(如果使用rand()的話,該值會被計算多次)。
在這里的意思就是,group by 進行分組時,floor(rand(0)*2)執行一次(查看分組是否存在),如果虛擬表中不在在該分組,那么在插入新分組的時候 floor(rand(0)*2)
就又計算了一次。
當我們使用floor(rand(0)*2)產生0和1兩個隨機數后,當在group by 對其進行分組的時候,首先遇到第一個值 0 ,發現 0 不存在,於是需要插入分組,就在這時,floor(rand(0)*2)
再次被觸發,生成第二個值 1 ,因此最終插入虛擬表的也就是第二個值 1 ;然后遇到第三個值 1 ,因為已經存在分組 1 了,就直接計數加1(這時1的計數變為2);遇到第四個值 0 的時候,發現 0 不存在,於是又需要插入新分組,然后floor(rand(0)*2)
又被觸發,生成第五個值 1 ,因此這時還是往虛擬表里插入分組 1 ,但是,分組 1 已經存在了!所以報錯!