「StegaBin」がPastebinのゼロ幅文字でC2を隠蔽し悪意あるnpmパッケージを配布
SocketとKmsec.ukのKieran Miyamotoが、北朝鮮系脅威クラスタ(攻撃グループ)Famous Chollima による新しいnpmサプライチェーン攻撃「StegaBin」を報告した。2月25〜26日の2日間で26個の悪意あるnpmパッケージが公開され、Pastebinに投稿した無害なエッセイにゼロ幅Unicode文字でC2 URLを埋め込むというステガノグラフィー手法が使われている。Socketは最初のパッケージ公開から2分以内に検出し、全26パッケージを各6分以内に危険判定した。
Famous ChollimaとContagious Interview
Famous ChollimaはCrowdStrikeが追跡する北朝鮮系のサイバー脅威クラスタで、Lazarus Groupと密接に関連する。このグループは「Contagious Interview」と呼ばれるキャンペーン(セキュリティ分野では一連の攻撃活動を指す)を2023年後半から継続しており、LinkedIn等で偽のリクルーターを装い、技術面接を口実にNode.jsプロジェクトを実行させてBeaverTailダウンローダー→InvisibleFerretバックドアの感染チェーンを展開してきた。
今回のStegaBinキャンペーンは、Contagious Interviewの手口をnpmサプライチェーン攻撃に拡張したものだ。面接の場を設けるまでもなく、npm install だけで感染させられる。2月に報告されたSANDWORM_MODEと同様にタイポスクワッティング(名前を似せた偽パッケージで誤インストールを狙う手口)を使うが、Famous Chollimaは国家支援の攻撃グループであり、攻撃インフラの規模と持続性が異なる。
26個のパッケージとタイポスクワッティング
2月25〜26日に個別の使い捨てアカウントで以下が公開された。
argonist bcryptance bee-quarl bubble-core
corstoken daytonjs ether-lint expressjs-lint
fastify-lint formmiderable hapi-lint iosysredis
jslint-config jsnwebapptoken kafkajs-lint loadash-lint
mqttoken prism-lint promanage sequelization
typoriem undicy-lint uuindex vitetest-lint
windowston zoddle
bcrypt → bcryptance、lodash → loadash-lint、express → expressjs-lint、winston → windowston、zod → zoddle のように、実在する人気パッケージの名前に似せた命名で開発者を誤誘導する。-lint、token、js などのサフィックスを付加して開発ツールや認証ライブラリに偽装している。各パッケージは正規の依存パッケージをdependenciesに宣言し、見た目の信頼性を高めている。
Pastebinステガノグラフィーの仕組み
このキャンペーン最大の特徴が、C2 URLの隠蔽にPastebinとゼロ幅Unicode文字を組み合わせたステガノグラフィーを使う点だ。
ゼロ幅Unicode文字とは
「ゼロ幅」は表示幅がゼロの不可視文字のこと。テキストエディタやブラウザでは見えないが、文字列としてはしっかり存在する。主な文字種は以下の通り。
| 文字 | コードポイント | 本来の用途 |
|---|---|---|
| Zero Width Space (ZWSP) | U+200B | 改行可能位置のヒント。タイ語やクメール語など分かち書きしない言語で使われる |
| Zero Width Non-Joiner (ZWNJ) | U+200C | 合字の抑制。ペルシア語やアラビア語で文字の結合を防ぐ |
| Zero Width Joiner (ZWJ) | U+200D | 文字の結合を強制。絵文字の合成(👨👩👧 = 👨+ZWJ+👩+ZWJ+👧)で馴染みがある |
| Zero Width No-Break Space | U+FEFF | BOM(Byte Order Mark)。UTF-8/16ファイルの先頭に置くエンコーディング識別子 |
| Word Joiner | U+2060 | 改行禁止位置のヒント。U+FEFFの本来の役割を引き継いだ文字 |
これらはどれも正当なUnicode文字で、テキスト処理で日常的に使われている。ZWJは絵文字の合成に不可欠だし、ZWNJがないとアラビア文字の表示が壊れる。だからこそ、セキュリティツールが「ゼロ幅文字がある=悪意がある」と単純に判定できない。
悪用の歴史も長い。コピペ防止のためにWebページのテキストにゼロ幅文字を仕込んで、コピーした文章から出典を追跡する「ウォーターマーキング」は2010年代から使われていた。StegaBinはこの手法をC2の隠蔽に転用した形だ。
デコードの流れ
攻撃者は3つのPastebin pasteに一見無害なコンピュータサイエンスのエッセイを投稿し、テキスト内の等間隔な位置の文字をC2アドレスの文字に置換している。パッケージ内のvendor/scrypt-js/version.jsに含まれるデコーダーは以下のように動作する。
- テキストからゼロ幅Unicode文字を除去
- 先頭5文字を数値として読み取り、ペイロード長を取得
- テキスト全体を等間隔に区切った位置の文字を抽出
- 抽出文字列を
|||で分割し、===END===を終端マーカーとしてC2ドメインの配列を復元
全体の攻撃チェーンを図にすると以下の通り。
flowchart TD
A["npm install"] --> B["install script自動実行"]
B --> C["Pastebinからエッセイ取得"]
C --> D["ゼロ幅文字をデコード"]
D --> E["C2ドメインを復元"]
E --> F["Vercel 31台からDL"]
F --> G["OS別ペイロード実行"]
G --> H["9モジュールRAT展開"]
style A fill:#dc2626,color:#fff
style B fill:#dc2626,color:#fff
style C fill:#2563eb,color:#fff
style D fill:#7c3aed,color:#fff
style E fill:#7c3aed,color:#fff
style F fill:#2563eb,color:#fff
style G fill:#2563eb,color:#fff
style H fill:#dc2626,color:#fff
コード上にC2 URLは直接存在せず、Pastebinへの通信も「エッセイを取得しているだけ」にしか見えない。C2 URLを変更する場合もPastebin側を更新するだけで、配布済みパッケージの再公開が不要という運用上の利点がある。静的解析ツールやサンドボックスでの検出を困難にする設計だ。
Vercel 31デプロイメントによる配信インフラ
C2ドメインを復元した後、マルウェアはVercel上にホストされた31のデプロイメントから、プラットフォーム別のシェルスクリプトとRATコンポーネントをダウンロードする。分析時点でアクティブだったのは1つのみで、ドメイン例としてext-checkdin.vercel[.]appが確認されている。
Vercelの無料枠を悪用することで、攻撃インフラのコストをゼロに抑えつつ、テイクダウン(強制削除)されても別のデプロイメントに切り替えられる冗長性を確保している。
9モジュール構成のRAT
npm install時にインストールスクリプトが自動実行され、vendorディレクトリ内のペイロード(悪意あるコード本体)が起動する。最終的に以下の9モジュールが展開される。
| モジュール | 実装 | 機能 |
|---|---|---|
vs | Node.js | VS Code永続化。tasks.jsonにrunOn: "folderOpen"トリガーのタスクを追加し、プロジェクトを開くたびにVercelドメインへ接続 |
clip | Node.js | キーロガー・マウストラッカー・クリップボード窃取。10分間隔でデータを外部送信 |
bro | Python | ブラウザ認証情報収集。Chrome・Firefox・Edge・Brave等のパスワードストアを対象 |
j | Node.js | 暗号資産ウォレット窃取。MetaMask・Phantom・Coinbase Wallet・Exodus等 |
z | Node.js | ファイルシステム列挙と対象ファイルの抽出 |
n | Node.js | WebSocket RAT。103.106.67[.]63:1247へ永続接続し、リアルタイムでコマンド実行 |
truffle | Node.js | 正規のTruffleHogをデプロイし、.env・秘密鍵・APIキーなどのシークレットをスキャン |
git | Node.js | .sshディレクトリとGitリポジトリの認証情報を収集 |
sched | Node.js | 初期ローダーの再デプロイによる永続化メカニズム |
C2サーバーは103.106.67[.]63で、コマンド実行用にポート1244、WebSocket RAT用にポート1247を使い分ける。このIPはFamous Chollimaの過去のインフラと重複しており、帰属の根拠の一つになっている。
truffleモジュールが正規のセキュリティツールTruffleHogを「攻撃側のツール」として流用しているのが面白い。防御側が使うシークレットスキャナーをそのままインフォスティーラー(情報窃取マルウェア)に転用している。
OPSEC失敗による帰属確定
Threat Intelligence Reportの調査で、Famous Chollimaの運用上のセキュリティミスが明らかになった。攻撃者はnpmパッケージの公開にgenerator.email、emailfake.com、tempm.comなどの使い捨てメールサービスを使用していたが、これらのサービスは受信箱が公開されていた。
npm公開通知メールからIPアドレスが露出した。
216.227.145.218— Astrill VPN出口ノード(高信頼度)193.118.55.19、193.118.55.77— hide.me VPN67.43.59.10— Astrill VPN203.160.80.72— China Unicom ISP空間62.33.223.164— TransTeleCom ISP空間
さらに同じ使い捨てメールアドレスに、bayt.comやHireLatamなどの求人プラットフォームからの登録確認メールも届いていた。これにより、npmサプライチェーン攻撃とContagious Interviewの偽求人活動が同一インフラで運用されていることが裏付けられた。2025年9月から2026年1月末にかけて一貫したIPの使い回しが確認されている。
Google Drive経由の関連ステージャー
StegaBinとは別に、express-core-validatorという単独パッケージによる関連ステージャー(本体をダウンロードする中間ローダー)も確認されている。こちらはGoogle Driveを経由して次段ペイロードを配信する。Pastebinステガノグラフィーではなくクラウドストレージを使う変種で、Famous Chollimaが複数の配信経路を並行して試していることがわかる。
SANDWORM_MODEとの比較
2月に報告されたSANDWORM_MODEと並べると、同時期のnpmサプライチェーン攻撃でもアプローチが大きく異なる。
| SANDWORM_MODE | StegaBin | |
|---|---|---|
| アクター | 不明 | Famous Chollima(北朝鮮) |
| パッケージ数 | 19 | 26 |
| 公開アカウント | 2アカウント | 26個の使い捨てアカウント |
| C2隠蔽 | base64+XOR難読化 | Pastebinステガノグラフィー |
| 配信インフラ | Cloudflare Worker | Vercel 31デプロイメント |
| 自動伝播 | 3経路ワーム(npm/GitHub/SSH) | なし |
| AI環境標的 | MCPインジェクション | なし |
| 永続化 | gitフック+MCP設定改ざん | VS Code tasks.json |
| 特徴 | ポリモーフィックエンジン(コードを自動変形して検出を回避) | ゼロ幅Unicode文字ステガノグラフィー |
SANDWORM_MODEはワーム伝播とAIツール標的に特化し、StegaBinはC2の隠蔽と検出回避に注力している。開発者環境を狙うという大きな方向性は共通しているが、攻撃の設計思想が異なる。開発ツール自体が攻撃面になる傾向は加速している。
IOCと対策
| 種別 | 値 |
|---|---|
| C2サーバー | 103.106.67[.]63(ポート1244、1247) |
| Vercelドメイン例 | ext-checkdin.vercel[.]app |
| VPN出口ノード | 216.227.145.218、67.43.59.10(Astrill)、193.118.55.19、193.118.55.77(hide.me) |
26パッケージはnpmから削除済みだが、Famous Chollimaは過去にも削除後すぐ後継パッケージを再公開している。npm auditはレジストリに登録された既知の脆弱性を検索するだけで、パッケージ内の悪意あるコード自体は検出対象外。
実効性のある対策としては以下が挙げられる。
- Socket CLIでインストール前のパッケージ分析(
socket scan npm install <package>) - CIパイプラインへのパッケージスキャナー組み込み
- lockfileへの未知パッケージ追加を検知するgit hook
- 上記IOCのIPアドレスをファイアウォールでブロック
- VS Codeの
tasks.jsonに見覚えのないタスクがないか確認
これまでnpmサプライチェーン攻撃はSANDWORM_MODEのようなワーム型や、ClinejectionのようなCI経由の攻撃が目立っていたが、StegaBinはC2の隠蔽にここまで手間をかけた点が新しい。Pastebinのエッセイにゼロ幅文字でURLを仕込むのは、静的解析やネットワーク監視を前提とした防御側の盲点を突いている。Famous Chollimaが使い捨てメールの公開受信箱からIPを漏らしたのは間抜けだが、手法自体の洗練度は上がっている。それでもSocketが2分で検出しているあたり、隠蔽を凝っても公開リポジトリに出した瞬間に捕まる時代ではある。攻撃の巧妙さと運用のザルさが同居しているのがこのグループらしい。
- 元記事: The Hacker News - North Korean Hackers Publish 26 npm Packages Hiding Pastebin C2 for Cross-Platform RAT
- 調査レポート: Socket - StegaBin: 26 Malicious npm Packages Use Pastebin Steganography
- OPSEC分析: Threat Intelligence Report - DPRK FAMOUS CHOLLIMA OPSEC failure
- 脅威プロファイル: CrowdStrike - Famous Chollima Adversary Profile