
はじめに
WaterPlumは北朝鮮に関連する攻撃グループであるとされており、特にContagious Interviewという攻撃キャンペーンを行っています。WaterPlumは複数のクラスタ(チーム)に分類することができますが、その中でもチーム8(Moralis系、Modilus系とも呼ばれている)による活動が観測されています。
チーム8については、これまでContagious Interviewキャンペーンにおいて、主にOtterCookieを使用した攻撃を行ってきました。しかし、2025年12月頃から、新たなマルウェアを使用し始めています。私たちはこのマルウェアをStoatWaffleと呼んでいます。
本稿ではWaterPlumのチーム8の最新の攻撃フローと、新たに使用され始めたStoatWaffleの解析結果を紹介します。
攻撃フロー

チーム8はブロックチェーンに関連するプロジェクトをデコイとしています。悪性なリポジトリには .vscode ディレクトリがあり、そのディレクトリの中にはtasks.jsonが含まれています。ユーザがVSCodeを使って悪性リポジトリを開き、リポジトリを信頼設定した場合、tasks.jsonが読み込まれます。
tasks.jsonの runOptions に runOn という設定があります。悪性リポジトリのtasks.jsonでは、この値が folderOpen となっており、VSCodeでディレクトリを開いた際にタスクが実行されるようになっています。

タスクはOSごとに設定されており、いずれの場合もVercel上のWebアプリケーションからデータをダウンロードして実行するようになっています。以降ではWindowsでの動作について説明しますが、基本的な挙動はどのOSでも同じです。

Vercelからダウンロードされたデータはcmd.exeによって実行されます。1段目のデータは極めてシンプルなダウンローダとなっており、後続のBATファイルvscode-bootstrap.cmdをダウンロードして実行します。

vscode-bootstrap.cmdはまず、Node.jsがインストールされているかチェックします。インストールされていない場合、Node.jsの公式サイトからNode.jsをダウンロードします。

その後、env.nplとpackage.jsonをダウンロードし、Node.jsを使ってenv.nplを実行します。

StoatWaffle
Loader
vscode-bootstrap.cmdによって実行されるenv.nplは、StoatWaffleの1段目のダウンローダです。C2サーバの /api/errorMessage に対して5秒間隔で接続し、C2サーバの応答として、statusがerrorであれば、messageをNode.jsのコードとして実行します。

私たちの調査時点では、env.nplによってC2とポーリングが行われてから、約5分ほど経過すると以下のようなJSONデータがダウンロードされました。

env.nplによってダウンロード・実行されたNode.jsコードは、StoatWaffleの2段目のダウンローダです。1段目と同様にC2サーバと定期的に通信を行いつつ、C2サーバから得られたコードを実行します。
2段目のダウンローダは、1段目と同じC2サーバの /api/handleErrors というパスに対して5秒おきに接続します。C2サーバの応答として含まれているmessagesをNode.jsのコードとして実行します。

私たちの調査時点では、2段目のダウンローダが実行された直後に、StoatWaffleのStealerモジュールとRATモジュールのダウンロード・実行を観測しました。

Stealerモジュール
Stealerモジュールは、Webブラウザに保存されているクレデンシャルや、特定のブラウザ拡張のデータを窃取し、C2サーバへアップロードします。
Chromium系のWebブラウザの場合、保存されているクレデンシャルの他、ブラウザ拡張のデータ(Appendix)を窃取します。
Firefoxの場合、保存されているクレデンシャルに加えて、ブラウザ拡張のデータを窃取します。extensions.jsonに書かれているブラウザ拡張の名前を取得し、予め定義されたキーワードが含まれているかチェックします。

さらに、macOSの場合は、Keychainのデータベースの窃取も行います。

窃取対象のファイルはOSの一時ディレクトリ配下に作成されたランダムな名前のディレクトリへコピーされ、その後はC2サーバの /upload へ送信されます。
また、こうしたクレデンシャルの窃取とは別に、被害者端末にインストールされているソフトウェアを探索し、その情報を /uploadsecond に送信します。
大変興味深いことに、Stealerモジュールは被害者端末がWSL環境かどうかチェックを行います。WSLの場合、Windows側のユーザプロファイルを取得し、wslpathを使ってLinuxのパスへ変換します。これによって、WSL上のNode.jsからWindows側のデータにアクセスすることが可能です。

RATモジュール
RATモジュールは、C2サーバと定期的に通信を行い、`/api/hsocketNext` からコマンドを受信した場合はそれを実行し、結果を /api/hsocketResult に送信します。

実装されているコマンドは以下のとおりです。

おわりに
本稿では、WaterPlumのチーム8が新たに使い始めたマルウェアStoatWaffleについて紹介しました。StoatWaffleはNode.jsで実装されたモジュール式のマルウェアであり、StealerモジュールやRATモジュールが実装されています。WaterPlumは絶えず新たなマルウェアを生み出し続け、また改良し続けています。今後もその動向を注視していく必要があります。
IoC
- 185[.]163.125.196
- 147[.]124.202.208
- 163[.]245.194.216
- 66[.]235.168.136
- 87[.]236.177.9