Oracle 豐富的系統表、PL/SQL 特性與 Web 應用框架差異,形成獨特的 SQL 注入攻擊面。本文系統解析**系統表情報收集、注入點分類 (DML vs PL/SQL vs 匿名區塊)、Cursor/DBMS_SQL 繞過限制、PHP 轉義繞過**、以及防禦建議,供安全測試與程式碼審計參考。
Oracle 幾乎所有中繼資料存於系統表/視圖:
SYS.V_$OPTION:資料庫選項 (Java、Partitioning、OLAP 等)ALL_TABLES / ALL_TAB_COLUMNS:可存取表與欄位結構USER_OBJECTS、DBA_USERS、V$VERSION:物件、用戶、版本攻擊者先查系統表掌握結構,再精準提取業務資料。
| 注入點類型 | 特性 | 多語句支援 | DDL 執行 | 典型利用手法 |
|---|---|---|---|---|
| DML (SELECT/INSERT/UPDATE/DELETE) | 最常見,單語句 | 否 | 否 | UNION 查詢、盲注、Error-based |
| PL/SQL 存儲過程/函數參數 | 動態 SQL 組裝 (EXECUTE IMMEDIATE) | 否 (單塊) | 需建立自訂函數/過程 | 注入建立函數 → 執行 DDL |
| Cursor / DBMS_SQL | 動態游標 API | 是 (多 OPEN/PARSE/EXECUTE) | 是 | 繞過單語句限制,直接跑 DDL |
| 匿名 PL/SQL 區塊 (BEGIN ... END) | 極少見,但最危險 | **是** | **直接可跑** | 幾乎無限制,等同本地登入 |
-- 攻擊者輸入
' ;
DECLARE c NUMBER;
BEGIN
c := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(c, 'GRANT DBA TO PUBLIC', DBMS_SQL.NATIVE);
DBMS_SQL.EXECUTE(c);
END; --
利用 DBMS_SQL 套件在單一注入點執行多條 DDL,提權極快。
-- 若輸入直接置於 BEGIN ... END 之間
BEGIN
-- 原始邏輯
SELECT * FROM users WHERE id = '1'; -- 攻擊者控制 '1'
-- 注入 payload
EXECUTE IMMEDIATE 'CREATE USER hacker IDENTIFIED BY pwd';
GRANT DBA TO hacker;
END;
可直接執行任意 PL/SQL,**繞過所有單語句、權限檢查**,極難防禦。
| 框架 | 參數過濾 | 類型檢查 | 注入易發點 |
|---|---|---|---|
| ASP / 早期 PHP | 幾乎無 | 弱型別 | 所有參數 |
| .NET / JSP | 部分內建 | **強型別** (數字參數自動拒絕字串) | **字串參數** 為主 |
| PHP (magic_quotes_gpc=On) | ' → \' | 弱型別 | 單引號被破壞 |
magic_quotes 將 ' 轉為 \'。\'**,單引號轉義是 '' (兩個單引號)。' 經 PHP 變 \' 送入 Oracle,**語法錯誤而非注入成功**;但攻擊者可改用 CHR(39)、|| 連接、HEXTORAW 等無單引號 payload。PreparedStatement、EXECUTE IMMEDIATE ... USING、**絕不拼接字串**。REVOKE EXECUTE ON DBMS_SQL FROM PUBLIC、UTL_FILE、DBMS_JOB 等。EXECUTE IMMEDIATE、DBMS_SQL、動態 PL/SQL 組裝點。理解 Oracle 注入的**系統表情報鏈、PL/SQL 多語句繞過、框架轉義差異**,才能在程式碼審計與滲透測試中精準定位高危洞洞,並實施有效防禦。