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

Oracle Java Stored Procedure 實戰:檔案操作、Shell 執行與網路 Socket 整合

     編輯:Oracle 資料庫基礎

Java Stored Procedure 概述

Oracle 支援在資料庫內載入並執行 Java 類別,透過 PL/SQL Call Specs 公開靜態方法為 SQL 可呼叫函數。適用於檔案系統存取、外部程式呼叫、網路通訊等 PL/SQL 難以處理的場景。

注意:本文示範代碼包含反向 Shell、檔案讀寫、命令執行等高風險功能,僅供教學理解 Java Stored Procedure 機制,生產環境嚴禁部署此類程式碼,極易造成資安漏洞。

Java 原始碼載入

CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "ISTO" AS
import java.io.*;
import java.net.*;
public class ISTO {
  // 列舉目錄
  public static String listFolder(String path) { ... }
  // 儲存檔案
  public static String saveFile(String filepath, String value) { ... }
  // 讀取檔案
  public static String readFile(String pathfile, String code) { ... }
  // 執行外部程式
  public static String execFile(String filepath, String code) { ... }
  // 綁定 Shell (Bind Shell)
  public static String bindShell(int port) { ... }
  // 反向 Shell (Reverse Shell)
  public static String reverseShell(String host, int port) { ... }
  // 內部類別處理 Shell 互動
  public static class optShell extends Thread { ... }
};

PL/SQL 函數包裝器

建立對應的 PL/SQL 函數對應 Java 靜態方法:

CREATE OR REPLACE FUNCTION isto_listfolder(p_path VARCHAR2) RETURN VARCHAR2
AS LANGUAGE JAVA NAME 'ISTO.listFolder(java.lang.String) return java.lang.String';

CREATE OR REPLACE FUNCTION isto_savefile(p_path VARCHAR2, p_value VARCHAR2) RETURN VARCHAR2
AS LANGUAGE JAVA NAME 'ISTO.saveFile(java.lang.String, java.lang.String) return java.lang.String';

CREATE OR REPLACE FUNCTION isto_readfile(p_path VARCHAR2, p_code VARCHAR2) RETURN VARCHAR2
AS LANGUAGE JAVA NAME 'ISTO.readFile(java.lang.String, java.lang.String) return java.lang.String';

CREATE OR REPLACE FUNCTION isto_execfile(p_path VARCHAR2, p_code VARCHAR2) RETURN VARCHAR2
AS LANGUAGE JAVA NAME 'ISTO.execFile(java.lang.String, java.lang.String) return java.lang.String';

CREATE OR REPLACE FUNCTION isto_bindshell(p_port NUMBER) RETURN VARCHAR2
AS LANGUAGE JAVA NAME 'ISTO.bindShell(int) return java.lang.String';

CREATE OR REPLACE FUNCTION isto_reverseshell(p_host VARCHAR2, p_port NUMBER) RETURN VARCHAR2
AS LANGUAGE JAVA NAME 'ISTO.reverseShell(java.lang.String, int) return java.lang.String';

Java 權限授予(關鍵步驟)

預設 Java 在資料庫中運行於沙箱,需明確授予檔案、網路、執行權限:

BEGIN
  DBMS_JAVA.GRANT_PERMISSION('用戶名', 'java.io.FilePermission', '<>', 'read,write,execute,delete');
  DBMS_JAVA.GRANT_PERMISSION('用戶名', 'java.lang.RuntimePermission', '*', 'writeFileDescriptor');
  DBMS_JAVA.GRANT_PERMISSION('用戶名', 'java.net.SocketPermission', '*:*', 'accept,connect,listen,resolve');
END;
/

測試呼叫

SELECT isto_listfolder('/usr') FROM dual;
SELECT isto_execfile('C:\Windows\system32\cmd.exe /c dir c:\', 'GBK') FROM dual;
SELECT isto_readfile('/tmp/1.txt', 'GBK') FROM dual;
SELECT isto_savefile('/tmp/1.txt', '測試內容') FROM dual;
SELECT isto_bindshell(20000) FROM dual;  -- 監聽埠,極高風險

安全性警示與替代方案

  • 極高風險:此類程式碼等同給資料庫用戶 OS 級存取權,繞過所有資料庫安全控制
  • 生產環境應採用 External Tables、UTL_FILE、DBMS_SCHEDULER 外部作業、Oracle REST Data Services (ORDS) 等安全機制
  • 若必須使用 Java Stored Procedure,嚴格限制權限:最小化 FilePermission 路徑、禁止 RuntimePermission、限制 SocketPermission 目標主機/埠
  • 啟用資料庫稽核追蹤所有 Java 類別載入與權限變更
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved