Oracle SQL Execution and File Access
Authenticated Oracle database access provides structured data extraction, file system access via UTL_FILE, and privilege enumeration that maps the path to OS command execution. Start by understanding what the current account can access before attempting escalation. Confirm working credentials through weak credential testing before proceeding here. Oracle enforces a layered privilege model. Regular users only access their own schemas. The DBA role unlocks system views like dba_users and sys.user$. If your account lacks DBA privileges, many queries here return ORA-00942 or empty results. Check your current privileges with SELECT * FROM session_privs before running anything else. Accounts granted DBA through application roles may not show it in session_privs: also check SELECT * FROM session_roles.
- Database and Version Information
- Enumerate All Database Users
- Extract Password Hashes
- File Read with UTL_FILE
- File Read with ODAT
Database and Version Information
The banner line identifies the exact Oracle release. Enterprise Edition exposes more built-in packages than Standard Edition. The version number determines which hash format is in use and which exploitation paths apply. A READ WRITE open_mode confirms the database is fully active. A MOUNTED or READ ONLY mode limits what you can query. Note the host_name value: it often matches the OS hostname and helps correlate this access with SSH, RDP, or other services on the same host.
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 ORCL ORCL READ WRITE ORCL db-server-01 11.2.0.2.0
Explain command
| -L | Attempt login only once, do not reprompt on failed credentials. |
| $USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL))) | Credentials and full TNS connect descriptor targeting Oracle SID ORCL on port 1521. |
| $TARGET_IP | Placeholder for the target Oracle database server IP address. |
Enumerate All Database Users
Rows with ACCOUNT_STATUS of OPEN are active accounts and the primary targets for cracking or reuse. EXPIRED & LOCKED accounts cannot authenticate without administrator intervention, but their password hashes are still present in sys.user$ and worth cracking for reuse elsewhere. Look for default Oracle accounts like SCOTT, HR, OUTLN, DBSNMP, and MGMT_VIEW in OPEN status. These frequently retain vendor-default passwords. Application accounts in the USERS tablespace are typically created by the deploying team and often share passwords with other services. System accounts in SYSTEM or SYSAUX are high-value targets: cracking SYS or SYSTEM gives full DBA access if you do not already have it.
USERNAME ACCOUNT_STATUS DEFAULT_TABLESPACE SYS OPEN SYSTEM SYSTEM OPEN SYSTEM SCOTT OPEN USERS HR EXPIRED & LOCKED USERS
Explain command
| -L | Attempt login only once; do not prompt for credentials on failure. |
| $USER/$PASSWORD@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$TARGET_IP)(PORT=1521))(CONNECT_DATA=(SID=ORCL))) | Oracle connection string with credentials, TCP host, port 1521, and SID ORCL. |
| $TARGET_IP | Placeholder for the target Oracle database server IP address. |
Extract Password Hashes
Oracle password hashes are stored in the data dictionary and readable with DBA privileges. Querying dba_users alone does not expose raw hashes in 11g and later. You need direct access to sys.user$ to get usable hash values. Without DBA role, this query fails with insufficient privileges. If you are running as a non-DBA user, check for SELECT on sys.user$ granted explicitly: SELECT * FROM session_privs WHERE privilege LIKE '%USER%'.
NAME PASSWORD SPARE4 SYSTEM D4DF7931AB130E37 S:... SCOTT F894844C34402B67 S:...
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. |
| $TARGET_IP | Placeholder for the target Oracle DB server IP address. |
| SELECT username, password FROM dba_users WHERE account_status='OPEN' | SQL query retrieving credentials of all open/active Oracle accounts. |
Oracle 10g and earlier use DES-based hashes (hashcat mode 3100). Oracle 11g uses SHA1-based hashes (mode 112). Oracle 12c+ uses SHA-512 based hashes (mode 12300). Crack with hashcat using the appropriate mode. The PASSWORD column holds the legacy DES hash, always uppercase hex. The SPARE4 column holds the 11g SHA1 hash. If SPARE4 starts with S:, extract everything after that prefix for mode 112. On 12c+ systems, SPARE4 also contains a T: prefixed SHA-512 verifier. The DES hash in PASSWORD is username-salted: the salt is the username in uppercase, which hashcat mode 3100 expects as username:hash. Cracked Oracle credentials frequently reuse the same password on OS accounts. Always try cracked passwords against SSH and other local services on the same host before moving on.
File Read with UTL_FILE
UTL_FILE reads and writes files accessible to the Oracle process user. It requires DIRECTORY objects pointing to accessible paths. On Linux, the Oracle process runs as the oracle OS user. Any file readable by that user is reachable through UTL_FILE. You need CREATE ANY DIRECTORY privilege to define new DIRECTORY objects pointing to arbitrary paths like /etc. Without it, you are limited to paths already exposed in all_directories. The DATA_PUMP_DIR and ORACLE_HOME directories are almost always present. Check /tmp for staged files or credentials left by other processes. If CREATE ANY DIRECTORY is denied, look for writable directories in all_directories and read files within those paths instead.
DIRECTORY_NAME DIRECTORY_PATH DATA_PUMP_DIR /u01/app/oracle/admin/orcl/dpdump/ ORACLE_HOME /u01/app/oracle/product/11.2.0/dbhome_1/ TMP /tmp
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))) | Full Oracle EZConnect string with credentials, target IP, port 1521, and SID. |
| $TARGET_IP | Placeholder for the target Oracle database server IP address. |
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 Easy Connect string specifying credentials, TCP host, port 1521, and SID ORCL. |
| $TARGET_IP | Placeholder for the target Oracle DB server IP address. |
| <<EOF | Heredoc delimiter piping the SQL/PL-SQL block as stdin to sqlplus. |
File Read with ODAT
ODAT's ctxsys module provides file read more cleanly when the required privileges are present. The ctxsys approach exploits Oracle Text indexing to read arbitrary files without needing an explicit DIRECTORY object or CREATE ANY DIRECTORY privilege. This works when the CTXSYS schema is installed, which is the default on most Oracle installations. ODAT writes the retrieved file content locally, avoiding the need to parse PL/SQL output manually. If ctxsys fails with insufficient privileges, fall back to the UTL_FILE method. Target high-value files: /etc/passwd, /etc/shadow, Oracle wallet files at $ORACLE_BASE/admin/ORCL/xdb_wallet/ewallet.p12, and TNS configuration at $ORACLE_HOME/network/admin/tnsnames.ora. The tnsnames.ora file often reveals other internal Oracle instances reachable from the current server.
Explain command
| ctxsys | Uses the CTXSYS Oracle module to exploit text index privileges. |
| -s $TARGET_IP | Specifies the target Oracle database server IP address. |
| -p 1521 | Specifies the target port (default Oracle listener port 1521). |
| -d ORCL | Specifies the Oracle database SID to connect to. |
| -U $USER | Specifies the username for Oracle database authentication. |
| -P $PASSWORD | Specifies the password for Oracle database authentication. |
| --getFile | Reads a file from the remote server filesystem via Oracle. |
| /etc/passwd | Remote file path to be read from the target system. |
| /tmp/passwd_output | Local path where the retrieved file content will be saved. |
From file read, pivot to OS command execution if Java is enabled in the database. The DBMS_JAVA package allows direct OS command execution when Java stored procedures are available and the account has JAVA_ADMIN or DBA role. Check Java availability with SELECT * FROM all_objects WHERE object_name = 'DBMS_JAVA' AND object_type = 'PACKAGE'. External table abuse is another path to command execution that does not require Java. Both techniques require DBA or equivalent privileges.
References
-
Oracle: UTL_FILEDOCS: Oracle: UTL_FILE, docs.oracle.com/en/database/oracle/oracle-database/19/arpls/UTL_FILE.html (opens in new tab)
UTL_FILE package reference for filesystem read and write operations
-
ctxsys and other post-authentication exploitation modules