Back to Articles

ODAT: Penetration Testing Oracle Databases Beyond SQL Injection

[ View on GitHub ]

ODAT: Penetration Testing Oracle Databases Beyond SQL Injection

Hook

Your Oracle database can be perfectly patched against SQL injection and still vulnerable to 8+ different remote code execution methods using legitimate built-in features. ODAT automates all of them.

Context

Oracle databases power critical infrastructure across finance, healthcare, and enterprise systems, yet traditional database security scanning focuses primarily on SQL injection vulnerabilities and credential strength. This leaves a massive blind spot: Oracle’s extensive feature set—Java stored procedures, DBMS_SCHEDULER jobs, external table processing, DBMS_XSLPROCESSOR transformations—was designed for legitimate administrative tasks but can be weaponized by attackers with valid credentials. Before ODAT’s release, penetration testers relied on fragmented Metasploit modules or manual exploitation techniques documented across obscure security blogs. There was no comprehensive tool specifically engineered to test the full Oracle attack surface remotely.

ODAT emerged from this gap as an Oracle-specific offensive security tool that treats database features as potential attack vectors. Unlike general-purpose database scanners that check for known CVEs or configuration mistakes, ODAT operates like an adversary who already has network access and possibly compromised credentials. It chains reconnaissance (SID/Service Name enumeration), authentication attacks (credential brute-forcing with optimized account lists), privilege escalation techniques (exploiting system privileges to gain DBA/SYSDBA), and post-exploitation capabilities (reverse shells, file exfiltration, arbitrary command execution). The tool has evolved through Oracle Database 10g, 11g, 12c, 18c and 19c, continuously adapting as Oracle’s security model changed. Version 5.x introduced Service Name guessing alongside traditional SID enumeration, recognizing that modern Oracle deployments increasingly use Service Names for connection routing.

Technical Insight

Exploitation Modules

commands

host payload

HTTP download

OS command execution

cx_Oracle connection

TNS protocol

authenticated session

SQL + PL/SQL

CREATE JOB privileges

execute

Code Execution Methods

DBMS Scheduler + Jobs

Java Stored Procedures

External Tables

Reconnaissance Modules

SID/Service Guesser

Password Guesser

Attacker Machine

ODAT Core Engine

Privilege Escalation

Code Execution

File Upload/Download

TNS Listener Attack

Oracle Database

10g-19c

HTTP Server

Payload Delivery

System architecture — auto-generated

ODAT’s architecture revolves around modular attack vectors, each targeting specific Oracle subsystems. The tool leverages cx_Oracle for database connectivity but wraps it in exploitation logic that simulates realistic attack progression. The most revealing aspect is how it exploits administrative features that security teams often forget to restrict.

The DbmsScheduler module exemplifies this approach. DBMS_SCHEDULER, Oracle’s built-in job scheduling system, allows users with CREATE JOB privileges to execute PL/SQL code on a schedule. ODAT weaponizes this by creating jobs that execute OS commands through Java stored procedures. On Linux targets, it’s straightforward: create a Java stored procedure that invokes Runtime.getRuntime().exec(), wrap it in a scheduled job, and capture output. On Windows, version 5.0 introduced a more sophisticated technique—ODAT spins up a minimal HTTP server on the attacker’s machine, uses DBMS_SCHEDULER to make the Oracle server download a PowerShell payload via HTTP, then executes it to establish a reverse shell. The downloaded file is automatically cleaned up to reduce forensic traces. This matters because traditional database auditing focuses on SQL query patterns, not outbound HTTP connections initiated by the database server itself.

The Service Name Guesser (added in version 5.0) addresses a fundamental Oracle networking concept that many attackers overlooked. Oracle supports two connection identifiers: SIDs (System Identifiers, the traditional method) and Service Names (more flexible, modern approach). A database can have identical SID and Service Name values, or they can differ entirely. ODAT now tests both exhaustively:

# Conceptual flow of snguesser module
# Test candidate Service Names against target:port
for service_name in service_name_wordlist:
    try:
        connection_string = f"{username}/{password}@{ip}:{port}/{service_name}"
        connection = cx_Oracle.connect(connection_string)
        # Success - valid Service Name found
        log_valid_service(service_name)
        connection.close()
    except cx_Oracle.DatabaseError as e:
        error_code = e.args[0].code
        if error_code == 12514:  # ORA-12514: TNS:listener does not currently know of service
            continue  # Invalid Service Name, try next
        elif error_code == 1017:  # ORA-01017: invalid username/password
            # Service Name exists but credentials wrong
            log_valid_service(service_name)

This dual-enumeration strategy significantly improves reconnaissance success rates because cloud-managed Oracle instances and containerized deployments increasingly rely on Service Names rather than SIDs. The all module chains this automatically—it enumerates SIDs, then Service Names, then attempts credential attacks against discovered identifiers.

The privilege escalation module (privesc) deserves special attention for its surgical approach. Rather than exploiting buffer overflows or memory corruption bugs, it abuses Oracle’s privilege model. Oracle 10g-11g had numerous system privileges that, when granted, allowed users to execute code as SYSDBA. For example, CREATE ANY TRIGGER combined with ability to create triggers on SYS-owned objects meant you could inject code into administrative workflows. ODAT systematically checks whether the current user has these dangerous privilege combinations and provides exploitation guidance. Version 2.3.1 added CVE-2018-3004 exploitation—a privilege escalation via Oracle’s Java VM that allows authenticated users to write arbitrary files to the OS by bypassing built-in JVM security policies. This is critical because it works even when DBAs have locked down PL/SQL-based attacks.

The tnspoison module implements CVE-2012-1675, the TNS listener poisoning vulnerability. Oracle’s TNS listener accepts service registration from database instances, allowing remote databases to register themselves dynamically. The vulnerability allowed attackers to register fake database services, poisoning the listener’s routing table. When legitimate clients connected, they’d be redirected to attacker-controlled endpoints. While Oracle patched this in 2012, ODAT includes it because penetration testers routinely encounter unpatched Oracle 10g/early 11g systems in legacy environments, particularly in operational technology (OT) networks where patching is deferred for stability reasons.

ODAT’s connection management reveals production-testing experience. The --sleep parameter addresses ORA-12519 errors (“TNS: no appropriate service handler found”), which occur when the listener’s connection pool is exhausted—common during credential brute-forcing. By default, ODAT aggressively opens connections; --sleep 0.2 introduces 200ms delays between attempts, preventing listener overload. The tool also accepts custom sqlnet.ora files (since version 5.1) to tune TCP timeouts and connection parameters, crucial when testing databases behind high-latency networks or strict firewall rules. Version 4.1 added UTF-8 encoding by default for NVARCHAR2/NCLOB operations, fixing a longstanding issue where non-ASCII data in Oracle caused extraction failures.

Gotcha

ODAT’s effectiveness crumbles in several scenarios that penetration testers encounter frequently. Network-level restrictions are the primary obstacle—if the Oracle TNS listener (default port 1521) is firewalled to only accept connections from specific IP addresses or VLANs, ODAT cannot establish the initial connection. This is increasingly common in cloud deployments where Oracle databases run in private subnets behind bastion hosts. You’d need to pivot through a compromised web server or application tier first, and ODAT isn’t designed for tunneling through SOCKS proxies (unlike tools like Metasploit).

The dependency chain creates operational friction. ODAT requires cx_Oracle, which itself requires Oracle Instant Client libraries. Getting these components aligned—correct Python version, matching Oracle client version, proper library paths—can consume hours of troubleshooting, especially on non-standard Linux distributions or when testing from containers. The standalone Linux binaries at the releases page mitigate this somewhat, but they lag behind the development branch, meaning you miss recent features like Service Name guessing if you opt for convenience over capability. Module effectiveness varies dramatically based on database hardening. The DbmsScheduler reverse shell requires CREATE JOB privilege; external table attacks need CREATE ANY DIRECTORY and file system access; Java execution demands that Oracle’s Java VM is enabled (it’s disabled by default in 12c+). A well-hardened database with least-privilege account management will resist most of ODAT’s post-authentication attacks, leaving you with only credential brute-forcing. Finally, modern cloud-managed Oracle instances (Oracle Autonomous Database, AWS RDS for Oracle) restrict many administrative packages that ODAT exploits. Oracle Cloud blocks direct TNS listener access entirely in some configurations, requiring connections through SQL*Net proxies that ODAT doesn’t support.

Verdict

Use ODAT if you’re conducting authorized penetration tests against on-premises or IaaS-hosted Oracle databases where you need to demonstrate real-world attack chains beyond theoretical vulnerabilities—it excels at showing executives how valid but low-privileged credentials can escalate to OS-level compromise. It’s indispensable for red team exercises targeting Oracle environments or validating database hardening after deployment. Use it when you have network access to TNS listeners and want comprehensive coverage of Oracle-specific attack surfaces that general scanners miss. Skip ODAT if your targets are cloud-managed Oracle services with restricted administrative APIs, if you lack proper authorization (this tool will trigger every database intrusion detection system), or if you’re assessing non-Oracle databases—it’s completely specialized. Also skip if you need stealthy reconnaissance; ODAT’s brute-forcing and privilege checks generate obvious audit logs that any competent SOC will detect. For those scenarios, focus on application-layer vulnerabilities or social engineering instead.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/data-knowledge/quentinhardy-odat.svg)](https://starlog.is/api/badge-click/data-knowledge/quentinhardy-odat)