何為order by 注入
它是指可控制的位置在order by子句后,如下order參數可控:select * from goods order by $_GET['order']
order by是mysql中對查詢數據進行排序的方法, 使用示例
select * from 表名 order by 列名(或者數字) asc;升序(默認升序)
select * from 表名 order by 列名(或者數字) desc;降序
判斷注入類型
數字型order by注入時,語句order by=2 and 1=2
,和order by=2 and 1=1
顯示的結果一樣,所以無法用來判斷注入點類型
而rand()在數字型中,每次刷新會顯示不同的排序結果
當在字符型中用?sort=rand()
,則不會有效果,排序不會改變
因此用rand()可判斷注入點類型
注入方式
1.和union查詢一塊使用來判斷字段有幾個
(不是本主題討論的重點)
在sql注入時經常利用order by
子句進行快速猜解表中的列數
通過修改order by
參數值,比如調整為較大的整型數如order by 5
,再依據回顯情況來判斷具體表中包含的列數。
判斷出列數后,接着使用union select
語句進行回顯。
2.基於if語句盲注(數字型)
下面的語句只有order=$id
,數字型注入時才能生效,
order ='$id'
導致if語句變成字符串,功能失效
如下圖為演示
-
字符串型時if()失效,排列順序不改變
-
數字型時排列順序改變
知道列名情況下
if語句返回的是字符類型,不是整型, 因此如果使用數字代替列名是不行的,如下圖
這是在知道列名的前提下使用
?order=if(表達式,id,username)
- 表達式為true時,根據id排序
- 表達式為false時,根據username排序
不知道列名
id總知道吧
?order=if(表達式,1,(select id from information_schema.tables))
-
如果表達式為true時,則會返回正常的頁面。
-
如果表達式為false時,sql語句會報ERROR 1242 (21000): Subquery returns more than 1 row的錯誤,導致查詢內容為空
3.基於時間的盲注
order by if(表達式,1,sleep(1))
-
表達式為true時,正常時間顯示
-
表達式false時,會延遲一段時間顯示
延遲的時間並不是sleep(1)中的1秒,而是大於1秒。 它與所查詢的數據的條數是成倍數關系的。
計算公式:延遲時間=sleep(1)的秒數*所查詢數據條數
如果查詢的數據很多時,延遲的時間就會特別長
在寫腳本時,可以添加timeout這一參數來避免延遲時間過長這一情況。
4.基於rand()的盲注(數字型)
rand() 函數可以產生隨機數介於0和1之間的一個數
當給rand() 一個參數的時候,會將該參數作為一個隨機種子,生成一個介於0-1之間的一個數,
種子固定,則生成的數固定
order by rand
:這個不是分組,只是排序,rand()只是生成一個隨機數,每次檢索的結果排序會不同
order by rand(表達式)
當表達式為true和false時,排序結果是不同的,所以就可以使用rand()函數進行盲注了。
5.報錯注入
order by updatexml(1,if(1=2,1,(表達式)),1)
order by extractvalue(1,if(1=2,1,(表達式)));
因為1=2
,所以執行表達式內容
例如order by updatexml(1,if(1=2,1,concat(0x7e,database(),0x7e)),1)
獲取數據庫名
若改成1=1
,則頁面正常顯示