PIVOTPIPE: 新たな.NET製の非公式Beaconペイロード

2026年7月、IIJは公開ディレクトリ上でホストされた未知の.NET製マルウェアを観測・分析しました。

分析の結果、このマルウェアがCobalt Strike Beacon1に酷似する (あるいは重複する) 機能を持っていることが判明しました。このマルウェアはデフォルトC2プロファイルに近しい構成のCobalt Strike C2サーバとの通信に対応しており、さらにCobalt Strike Beaconに実装されている多くのC2コマンドの実行に対応しています。

しかしながら、検知回避用コード、独自ローダの実装、バイナリ内の文字列の難読化方式など、既存のCobalt Strike Beaconとは異なる実装を持つ機能も多く、単純なCobalt Strike Beaconの再実装版ではないことも確認しています。このことから、我々は本マルウェアを非公式のBeaconペイロードであると評価して、ファイル名やモジュール内の情報をもとに、PIVOTPIPEと命名しました。この記事ではPIVOTPIPEの解析結果や検知ルールなどを共有します。

ローダ

PIVOTPIPEはローダとRATの2つのコンポーネントで構成されています。まず、本項では公開ディレクトリに設置されていたローダの解析結果を紹介します。

ローダが実行されると、まずAMSIバイパス、Indirect Syscallの初期化処理、スリープマスクの有効化など、複数の検知回避およびEDR回避用のコードを実行します。これらの機能はPIVOTPIPEローダおよびRATの両方に実装されています。

次にローダは自身のファイル末尾から設定情報を agent.json に、公開鍵を pk.der に、スリープマスク用のCOFFファイルを sleepmask.o に (存在しない場合もある) 、XORエンコードおよびGZIP圧縮されたRATペイロードを core.pak というファイルにそれぞれ抽出して書き込みます。この際、一時フォルダ下に nb_ から始まる名前のフォルダが作成され、それが作業フォルダとして使用されます。

ファイルの書き込みが完了した後、ローダは core.pak をXORデコード、GZIP展開して、RATをメモリ上で実行します。XORデコードに必要な鍵もローダのファイル末尾に含まれており、今回観測した検体においては nbpivotpipenblabdbg などの文字列が使用されていました。

なお、ローダの実行時にコマンドライン引数 --foreign が渡されている場合、RATのペイロードをファイル末尾ではなくコマンドライン引数で指定されたURLから取得するよう実装されていました。この場合、PIVOTPIPEの設定情報やRATペイロードのXORデコード鍵は外部ファイル、環境変数、コマンドライン引数などからローダに渡されます。

RAT

ローダによってRATが実行されると、まずローダによって設置されたJSON形式の設定情報 (agent.json) を読み込みます。

なお、今回観測した検体には含まれていませんでしたが、他にも smb_mode, pipe_name, dns_mode といったパラメータが設定情報に含まれている可能性があります。これらのパラメータは本家Cobalt Strike Beaconにも存在するDNSを使用したC2通信やSMB Beacon2といった機能で使用されます。

その後、設定情報の内容をもとにC2サーバと通信します。SMB BeaconあるいはTCP Beacon3を使用するよう設定されている (設定情報内のパラメータ pivot_mode の値が true だった) 場合、PIVOTPIPEに感染した他のホストを経由してC2通信を実施します。
基本的にCobalt Strike Beaconのコマンド体系と同一ですが、PIVOTPIPEが対応しているC2コマンドの一覧は以下の通りです。

Type説明
3RATを終了する
4通信間隔 (Sleep時間) を変更する
5作業フォルダを変更する
6特定の通信データのアンパック用のコマンド
10ファイルをアップロードする
11ファイルをダウンロードする
14 – 17(リバース) ポートフォワーディングに関連するコマンド
19ファイルのダウンロードを停止する
22 – 24TCP BeaconおよびSMB Beaconに関連するコマンド
27ユーザ情報を取得する
28RevertToSelf関数を呼び出す
31他プロセスのトークンを取得・偽装する
32プロセス一覧を取得する
33プロセスをキルする
39作業フォルダを取得する
50リバースポートフォワーディングを開始する
53フォルダの内容を取得する
54フォルダを作成する
55ドライブ一覧を取得する
56ファイルを削除する
67ファイルの末尾にデータを書き込む
68SMB Beaconに接続する
73ファイルをコピーする
74ファイルを移動する
78コマンドを実行する
82TCP BeaconのListenを開始する

なお、今回観測した検体 pivot_hop2_kasp.exe はTCP Beacon機能を使用するよう設定情報が構成されていました。TCP Beacon機能が使用されている場合、PIVOTPIPEは他の感染ホストとP2P通信を行い、そのホストを経由してC2サーバと通信します。

開発途中のマルウェアという可能性について

PIVOTPIPEローダおよびRATが実行されると、マルウェア内の特定の処理 (C2通信やエラーハンドリングなど) のタイミングで、以下のファイルパスにデバッグ情報が書き込まれることを確認しています。

  • C:\WINDOWS\Temp\nb_drip_dbg.txt
  • C:\WINDOWS\Temp\nb_hook_dbg.txt
  • C:\WINDOWS\Temp\nb_fatal.txt
  • C:\WINDOWS\Temp\nb_hook_exports.txt
  • C:\WINDOWS\Temp\nb_hello_postex_ok.txt
  • C:\WINDOWS\Temp\nb_spawn_rewrite.txt
  • C:\WINDOWS\Temp\nb_postex_dbg.txt
  • C:\WINDOWS\Temp\nb_postex_fail.txt
  • C:\WINDOWS\Temp\nb_hb_dbg.txt
  • C:\WINDOWS\Temp\nb_post_last.txt
  • C:\WINDOWS\Temp\nb_export_dbg.txt
  • C:\WINDOWS\Temp\nb_sleep_dbg.txt

また、いくつかの機能の実装において、以下のようなマルウェアの開発環境のものと思われるファイルパスが使用されることを確認しています。

  • C:\Users\admin\Desktop\cscs\4.5\payloads\dotnet-4.x\sleeve\postex\hello_postex.dll
  • C:\Users\admin\Desktop\cscs\4.5\payloads\dotnet-4.x\sleeve\postex\hello.dll.enc

これらの痕跡から、PIVOTPIPEは観測時点では開発途中であり、今後さらに検知回避機能などがアップデートされる可能性があるといえます。

アンパッカー

我々は分析の効率化のためにローダのファイル末尾を静的に抽出、デコード、展開するPythonスクリプトを作成しました。ぜひインシデント対応や脅威リサーチ等でお役立てください。

unpack_pivotpipe_datablob.py
https://github.com/mopisec/research/blob/main/unpack_pivotpipe_datablob.py

さいごに

一部開発途中と思われる機能も確認されましたが、PIVOTPIPEは既に実際の攻撃活動で使用されている可能性があります。引き続き警戒が必要だといえるでしょう。

Appendix A: IoCs

ネットワーク

  • 45.32.253[.]166 (JP ; AS 20473 ; The Constant Company, LLC)
    • ポート8088 : Cobalt Strike C2サーバ
    • ポート8766 : 公開ディレクトリ

ファイル

SHA256ファイル名
AD9A03F3EA93C1A0A350F73B4ADA485CE444F2352EA11EEA05C87F075BE80CF7netbeacon_pivot.exe
FEEB5CAE714D0D35F68AD1D1B29DCCEC0BDCC58AC076869559DB53F6CB8137E8pivot_hop2_kasp.exe
715558E0AD32401C477D01412CC72FD07DC4EF6E122B6A730BA4B0A88A971677x64beacon.exe

Appendix B: YARAルール

rule PIVOTPIPE_LDR {
    meta:
      description = "Detects PIVOTPIPE Loader Payload"
      author = "Internet Initiative Japan Inc."
      hash1 = "AD9A03F3EA93C1A0A350F73B4ADA485CE444F2352EA11EEA05C87F075BE80CF7"
      hash2 = "FEEB5CAE714D0D35F68AD1D1B29DCCEC0BDCC58AC076869559DB53F6CB8137E8"
      hash3 = "715558E0AD32401C477D01412CC72FD07DC4EF6E122B6A730BA4B0A88A971677"

    strings:
        $magic = "NBPK1"
		
        $path0 = "C:\\WINDOWS\\Temp\\nb_fatal.txt" ascii wide
        $path1 = "C:\\WINDOWS\\Temp\\nb_sleep_dbg.txt" ascii wide
        $path2 = "C:\\WINDOWS\\Temp\\nb_drip_dbg.txt" ascii wide
        $path3 = "C:\\WINDOWS\\Temp\\nb_hook_exports.txt" ascii wide
        $path4 = "C:\\WINDOWS\\Temp\\nb_hello_postex_ok.txt" ascii wide
        $path5 = "C:\\WINDOWS\\Temp\\nb_spawn_rewrite.txt" ascii wide
		
        $devpath0 = "C:\\Users\\admin\\Desktop\\cscs\\4.5\\payloads\\dotnet-4.x\\sleeve\\postex\\hello_postex.dll" ascii wide
        $devpath1 = "C:\\Users\\admin\\Desktop\\cscs\\4.5\\payloads\\dotnet-4.x\\sleeve\\postex\\hello.dll.enc" ascii wide

        $str0 = "NB_AGENT_BASE" ascii wide
        $str1 = "NB_AGENT_SIZE" ascii wide
        $str2 = "NB_AGENT_MOD" ascii wide
        $str3 = "NB_AGENT_CLR_CORE" ascii wide
        $str4 = "HookGate init failed" ascii wide
        $str5 = "--- postex inject chain (Ghidra D2) ---" ascii wide
        $str6 = "foreign fetch needs pack key arg3 or NB_PACK_KEY" ascii wide
        $str7 = "hello shellcode requires x64" ascii wide

    condition:
        $magic and ((3 of ($path*)) or (1 of ($devpath*)) or (3 of ($str*)))
}Code language: plaintext (plaintext)
  1. 著名な脅威エミュレーションツールCobalt Strikeのエージェントプログラム。通常のマルウェアと同様に、C2サーバから命令を受信して、対応する処理を実行できる。 ↩︎
  2. SMB Beacon – Cobalt Strike User Guide
    https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/listener-infrastructure_beacon-smb.htm ↩︎
  3. TCP Beacon – Cobalt Strike User Guide
    https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/listener-infrastructure_beacon-tcp.htm ↩︎

シェアする