
Mythic向けのクロスプラットフォームC2エージェント。動的関数ロード、SOCKS5プロキシ、ファイル操作、シェルコードインジェクション、macOS/Windowsのポストエクスプロイテーションモジュールを備えています。
Medusa は、Python 3.8 と Python 2.7 の両方に対応したクロスプラットフォームエージェントです。
Medusa をインストールするには、リモートコンピュータに Mythic v3 がインストールされている必要があります。Mythic のインストール手順は Mythic プロジェクトページ で確認できます。
Mythic のインストールルートから、次のコマンドを実行します:
./mythic-cli install github https://github.com/MythicAgents/Medusa.git
インストール後、Mythic を再起動して新しいエージェントをビルドしてください。
Payload_Type/medusa/rabbitmq_config.json ファイルはテンプレートであり、ご利用の Mythic 環境と一致している必要があります。
rabbitmq_password を Mythic の RABBITMQ_PASSWORD 値(通常は Mythic の .env から取得)に設定します。rabbitmq_host を RabbitMQ ホスト名/コンテナ名(docker-compose 構成では多くの場合 mythic_rabbitmq、ローカルバインドでは 127.0.0.1)に設定します。mythic_server_host を Mythic サーバーのホスト名/コンテナ名(docker-compose 構成では多くの場合 mythic_server、ローカルバインドでは 127.0.0.1)に設定します。ベースエージェントと同梱のコマンドはすべて Python 標準ライブラリを使用しているため、動作に追加パッケージは必要ありません。エージェントはコマンドをスレッドで実行するため、長時間かかるアップロードやダウンロードでもメインエージェントをブロックしません。
Medusa エージェントの両バージョンは、標準ライブラリで記述された AES256 HMAC 実装を使用しています(こちら から改変)。そのため、標準の Python インストール以外の追加依存関係は必要ありません。これにより、エージェントは Windows、Linux、macOS の各ホストで動作するはずです。なお、この暗号実装は大きなファイル(スクリーンショット、ダウンロードなど)の処理時に多少のオーバーヘッドが発生しますが、実用上問題ありません。
Payload_Type/Medusa/agent_code ディレクトリ内には、py2 と py3 の両方のサフィックスが付いた base_agent ファイルがあります。同様に、個々の関数ファイルにも同じようなファイル拡張子があります。
これらは builder.py スクリプトによって読み取られ、まず Medusa エージェントの正しいベース Python バージョンが選択されます。次に builder.py は、選択された Python バージョンに固有のコマンドを含めます。コマンドが .py 拡張子のみを持つ場合は、Py2 と Py3 の間で代替コードが必要ないという前提で、そのファイルがデフォルトで使用されます。
Medusa はジョブ実行に基本的なスレッド処理を使用します。ジョブが長時間実行される可能性がある場合、jobkill タスクからのシグナルに応答する「停止チェック」を実装できます。これは、以下のようなコードスニペットで実装できます:
if [task for task in self.taskings if task["task_id"] == task_id][0]["stopped"]:
# Some job-specific tidy up
return "Job stopped."
このハンドラは、download、upload、watch_dir、screenshot コマンド内で実装されています。
さらに、長時間実行するジョブが継続的な出力を提供する場合、ベースエージェントに含まれる sendTaskOutputUpdate 関数を使用して、タスク完了前に Mythic を更新できます。継続的な出力を提供し、jobkill で停止できるダミー関数を以下に示します。
def dummyFunction(self, task_id):
while(True):
# Check if we've got a stop signal.
if [task for task in self.taskings if task["task_id"] == task_id][0]["stopped"]: return "Job stopped."
# Send output back to Mythic
self.sendTaskOutputUpdate(task_id, "We're still running")
time.sleep(10)
Medusa は現在、http(AES256 HMAC 暗号化あり/なしの両方)と azure_blob の 2 つの C2 プロファイルをサポートしています。
HTTP プロファイルは、基本の非ダイナミックプロファイルを介して Mythic サーバーにコールバックします。タスクの取得には GET リクエスト、レスポンスの送信には POST リクエストを使用します。
| Command | Syntax | Description |
|---|
| cat | cat path/to/file | ファイルの内容を読み取り、出力します。 |
| cd | cd [.. dir] | 作業ディレクトリを変更します(.. で 1 つ上のディレクトリに移動)。 |
| cp | cp src_file_or_dir dst_file_or_dir | ファイルまたはフォルダを指定先にコピーします。 |
| cwd | cwd | 作業ディレクトリを出力します。 |
| download | download [path] | 対象システムからファイルをダウンロードします。 |
| download_bulk | download_bulk [path1] [path2] ... | 1 つのタスクで対象システムから複数のファイルをダウンロードします。 |
| exit | exit | コールバックを終了します。 |
| env | env | 環境変数を出力します。 |
| eval_code | eval_code [commands] | Python コードを実行し、出力を返します。 |
| jobkill | jobkill [task id] | 長時間実行中のタスクに停止シグナルを送信します。 |
| jobs | jobs | ダウンロードなどの長時間実行中のタスクを一覧表示します。 |
| list_modules | list_modules [module_name] | メモリ内のモジュール、または特定のモジュールの完全なファイル一覧を表示します。 |
| load | load command | 新しい機能をエージェントにロードします。 |
| load_module | load_module | ZIP 圧縮された Python モジュールをメモリにロードします(こちら と こちら から改変)。 |
| load_script | load_script | エージェント経由で Python スクリプトをロードして実行します。 |
| ls | ls [. path] | [path] 内のファイルとフォルダを一覧表示します。カレントディレクトリを指定するには . を使用します。 |
| mv | mv src_file_or_dir dst_file_or_dir | ファイルまたはフォルダを指定先に移動します。 |
| pip_freeze | pip_freeze | システムにインストールされているパッケージをプログラム的に一覧表示します。 |
| pty | pty [/bin/bash] / pty self / pty fork | 対話型 PTY セッションを開きます。モード: spawn はプログラムを PTY 付きで実行し、self はライブなエージェント状態を保持した同一プロセス内の Python REPL を開き、fork はスナップショットされた状態を持つ Python REPL にエージェントをフォークします(Linux/macOS のみ)。 |
| rm | rm file_or_dir | ファイルまたはフォルダを削除します。 |
| shell | shell [command] | subprocess.Popen() を使用してシェルコマンドを実行します。コマンドの完了を待つため、エージェントをブロックしないよう注意してください。 |
| socks | socks start/stop [port] | Medusa エージェント経由で SOCKS5 プロキシを開始/停止します。 |
| sleep | sleep [seconds] [jitter percentage] | エージェントのコールバック間隔を秒単位で設定します。 |
| unload | unload command | エージェントから既存の機能をアンロードします。 |
| unload_module | unload_module module_name | 以前メモリにロードした Python モジュールをアンロードします。 |
| upload | upload | マシン上のリモートパスにファイルをアップロードします。 |
| watch_dir | watch_dir path seconds | ターゲットディレクトリ内の変更を監視し、指定した間隔で変更をポーリングします。 |
| Command | Syntax | Description |
|---|
| clipboard | clipboard | クリップボードの内容を出力します(Cedric Owens が こちら で説明している Objective-C API を使用。macOS のみ、Python 2.7 のみ)。 |
| list_apps | list_apps | macOS アプリケーションを一覧表示します(Python 2.7 のみ、macOS のみ)。 |
| list_tcc | list_tcc [path] | macOS TCC データベースのエントリを一覧表示します(フルディスクアクセスが必要で、現時点では Big Sur のみ)。 |
| screenshot | screenshot | スクリーンショットを撮影します(Objective-C API を使用。macOS のみ、Python 2.7 のみ)。 |
| spawn_jxa | spawn_jxa | osascript プロセスを起動し、Javascript コンテンツをパイプで渡します。 |
| vscode_list_recent | vscode_list_recent [state_db] | VSCode で最近開いたファイルとフォルダを一覧表示します。 |
| vscode_open_edits | vscode_open_edits [backup_dir_path] | VSCode でファイルに加えた未保存の変更を一覧表示します。 |
| vscode_watch_edits | vscode_watch_edits [path to remote dir] [poll_interval] | 指定した間隔で VSCode のバックアップディレクトリをポーリングし、未保存の編集を確認します。 |
| Command | Syntax | Description |
|---|
| shinject | shinject | CreateRemoteThread を使用してターゲット PID にシェルコードを注入します(Windows のみ - こちら から改変)。 |
| load_dll | load_dll dll_path dll_export | ディスク上の DLL をロードし、エクスポートされた関数を実行します(注意: この DLL は完了時に int 値を返す必要があります。たとえば msfvenom で作成した DLL は、完了時にエージェントを強制終了させます)。 |
| list_dlls | list_dlls [pid] | ローカルまたはターゲットプロセスのプロセスメモリ(PEB)を読み取り、ロード済み DLL の一覧を取得します(Python 3 のみ) |
| ps | ps | PID、プロセス名、アーキテクチャ、バイナリパスなど、限定的なプロセス情報を取得します(Python 3 のみ) |
| ps_full | ps_full | PPID、整合性レベル、コマンドラインを含む完全なプロセス情報を取得します(Python 3 のみ) |
| kill | kill | プロセス ID でプロセスを終了します(Python 3 のみ) |