


概要
GithubでVSCodeの自動化機能を悪用したマルウェアを確認し、分析した。
流布されたマルウェアは、Contagious Interviewキャンペーンに使用されるBeavertail、InvisibleFerret、OtterCookieであることが確認された。
一部のコードでLLMを活用して作成されたと推定される状況が確認された。
攻撃者は採用担当者、開発者、仮想企業に偽装したアカウントを使用して信頼性を確保し、マルウェアを流布したことが確認された。
C&Cサーバーの特徴を通じて、追加のC&Cサーバーを確保および分析した。
1. 概要
最近、GithubにおいてVSCode(Visual Studio Code)の自動化機能を悪用したマルウェアが多数確認された。分析の結果、Contagious Interviewキャンペーンに使用されるマルウェアであり、少なくとも2025年8月からキャンペーンが開始されていたことが確認された。
Contagious Interviewキャンペーンは、主に開発者を対象にマルウェアを流布する北朝鮮を背景とした攻撃グループのキャンペーンである。Contagious Interviewキャンペーンにおいて、攻撃者は主に採用担当者を装って開発者に接近し、コーディングテストやビデオ面接などを口実にBeavertail、InvisibleFerret、OtterCookieなどのマルウェアをダウンロードするよう誘導する。
今回確認されたGithubアカウントは、実在する企業の採用担当者、Web3開発者、架空の企業を装っていたことが確認された。これにより、攻撃者は正常な採用活動および開発活動を装って信頼度を確保し、マルウェアの流布を試みたものと判断される。
また、流布に使用されたマルウェアを分析した結果、人間が直接作成したコードではなく、生成型AI(LLM)を活用して作成されたと推定される状況が確認された。これは、攻撃者が悪質なツール製作プロセスの効率性を高め、コード分析を困難にするために、AI技術を積極的に活用していることを示唆している。
本稿では、今回の攻撃に使用されたマルウェアの動作方式と機能を分析し、攻撃者が活用したGithubアカウントの活動履歴について取り上げる。
2. 攻撃者のGitHub活動履歴
2.1. 実在する企業の採用担当者へのなりすまし
Web3企業である Koinosの採用担当者になりすました事例で、コーディングテストに関連するリポジトリからマルウェアが確認された。現在、アカウント情報は確認できないが、andrewというアカウントを使用しており、コーディングテストのためにフォークされたリポジトリが多数残っていることが確認できる。

caption - コーディングテスト関連リポジトリ
すべてのリポジトリの .vscode/task.json ファイルに、マルウェアをダウンロードして実行するコマンドが挿入されている。挿入されたコマンドはVSCodeの自動化機能を悪用し、リポジトリをVSCodeで開いたときに自動的に実行される。

caption - .vscode/task.jsonに挿入されたスクリプト
現在まで残っている andrew アカウントがコミットしたリポジトリは計11個で、コミット履歴を確認した結果、 andrew は andrew_watson という名前でも活動しており、メールアドレスは andrew@koinos[.]us を使用している。

caption - コミット履歴の例
メールに使用された koinos[.]us ドメインは、なりすました企業Koinosのドメイン(koinos.io)と酷似しており、実際にリポジトリ名に koinos、assessment(評価)、dev-test(開発テスト)といった単語が多く使用されていることから、実際のマルウェア配布プロセスは特定できなかったものの、採用プロセスを餌に企業の採用担当者になりすましてマルウェアを配布したものと判断される。
2.2. 開発者へのなりすまし
開発者になりすまし、共同作業中のリポジトリにコマンドを挿入した事例である。計5つのアカウントが確認され、すべてWeb3関連のプロジェクト作業経験があるフルスタック開発者として活動している。アカウントのリストは以下の通りである。
ameeetgaikwad
dannythedawger
yosket
nikkhielseath
jmjles

caption - jmjles アカウントのプロフィール
コマンドが挿入されたリポジトリは計10個で、リポジトリのリストは以下の通りである。
Token-Presale-dApp
Promoting-DApp
dapp-integration
Web3-RE-Prototype
TrustLedger_Fixes
linkfi
testtoken
messageforge
Token-Presale
Decentralized-Social
現在、 yosket、 nikkhielseath の2つのアカウントは削除されているが、残りの3つのアカウントは依然としてアクティブである。コマンドは .vscode/task.json ファイルに挿入されており、共同作業中のリポジトリであるため、別途の感染誘導なしにマルウェアに感染させることができる。

caption - .vscode/task.jsonに挿入されたスクリプト
最も活発に活動したアカウントは yosket で、現在はアカウントが削除されているが、2026年1月16日まで活動した記録が存在する。

caption - yosketの2026年1月16日のコミット履歴
また、 yosket のコミット履歴から、当該アカウントがコマンドを挿入したリポジトリが現在まで10個残っていることが確認された。リポジトリのリストは以下の通りである。
hxxps://github[.]com/TrustLedgerLabs/Token-Presale-dApp
hxxps://github[.]com/ryon-business/Promoting-DApp
hxxps://github[.]com/angel-group888/dapp-integration
hxxps://github[.]com/AretaSchmidt/Web3-RE-Prototype
hxxps://github[.]com/QalbeAli/TrustLedger_Fixes
hxxps://github[.]com/trustllabs/Token-Presale-dApp
hxxps://github[.]com/DavidMoura07/linkfi
hxxps://github[.]com/VictorKulagin/testtoken
hxxps://github[.]com/rajaXcodes/Token-Presale-dApp
hxxps://github[.]com/Rochelle128/TokenPresaleDApp
yosket 以外の4つのアカウントすべてが yosket と同じプロジェクトを進行していたことが確認され、
messageforge リポジトリでは、2つのアカウントが協力してマルウェアを配布しようとする様子も確認された。

caption - messageforge リポジトリ、nikkhielseath アカウントのコミット履歴
.vscode/tasks.json ファイルには、マルウェアをダウンロードして実行する以外にも、 .vscode/spellright.dict ファイルを nodejs で実行するコマンドも追加されている。 .vscode/spellright.dict ファイルは obfuscator.io で難読化されたJavaScriptファイルであり、 ameeetgaikwad アカウントによって追加されたことが確認されている。

caption - ameeetgaikwad アカウントが追加した .vscode/spellright.dict ファイル
2.3. 架空の企業活動
特定の企業のリポジトリにコマンドが挿入されていることが確認されたが、確認の結果、ホームページの構築やLinkedInアカウントの作成などにより、架空の企業を実在する企業のように見せかけてなりすました事例である。確認された3つのリポジトリすべてにコマンドが挿入されている。

caption - 架空の企業 veneliteus-dev アカウント
3つのリポジトリすべてにおいて、同一のコマンドが .vscode/tasks.json ファイルに挿入されている。コマンドは長い空白を利用して隠されており、すべて2026年1月14日にアップロードされた。

caption - .vscode/tasks.jsonに挿入された悪意のあるスクリプト
veneliteus-dev アカウントのプロフィールにリンクされているウェブサイトには、現在何の機能も存在せず、SNSのリンクが4つあるものの、LinkedInを除く残り3つ(Facebook、Instagram、X)はアカウントのプロフィールではなく、該当するSNSのメインページにリンクされている。
![hxxps://veneliteus[.]com](https://framerusercontent.com/images/n9MzG0x1GE8i7BFTbwqSAJ69Y.png)
caption - hxxps://veneliteus[.]com

caption - Venelitus LinkedIn
また、ホームページのメール入力欄にメールアドレスを入力しても、 Message sent! というメッセージが表示されるだけで、メールは届かない。実際のマルウェア配布プロセスは特定できなかったが、「2.1. 実在する企業の採用担当者へのなりすまし」と同様の手法でマルウェアを配布したものと判断される。
3. 攻撃分析

caption - 攻撃概要図
今回のContagious Interviewキャンペーンの攻撃フローは2つに分かれている。対象の環境や攻撃段階に応じて、BeavertailとInvisibleFerretを配布するか、または別途OtterCookieを配布していた。
3.1. Beavertail、InvisibleFerret
3.1.1. task.json - Downloader
該当のダウンローダーはVSCodeによってのみ実行される。runOptionsのrunOnオプションがfolderOpenに設定されているため、リポジトリのフォルダーがVSCodeで開かれた場合に、自動的に挿入されたコマンドが実行される仕組みである。

caption - .vscode/task.jsonの長い空白によって隠されたコマンド
挿入されたコマンドは計3つで、ユーザーのオペレーティングシステム(linux、macOS、windows)に適合するコマンドが実行される。コマンドの動作は、C&Cサーバーからスクリプトをダウンロードして実行することである。

caption - 挿入されたコマンド
オペレーティングシステム別でダウンロードするURLは異なるが、linuxとmacOSのダウンロードスクリプトは同一である。また、すべてのスクリプトに共通して、新しいスクリプトをダウンロードして実行する。
OSがlinux、macOSである場合、$HOME/Documents/tokenlinux.nplファイルとしてシェルスクリプトをダウンロードする。その後、ファイル名をtokenlinux.shに変更して実行する。

caption - linux、macOSのダウンロードスクリプト
OSがwindowsである場合には、%USERPROFILE%/parseにcmdスクリプトをダウンロードする。その後、ファイル名をtoken.cmdに変更して実行する。

caption - windowsのダウンロードスクリプト
しかし、分析当時において、windowsでダウンロードされるcmdスクリプトはAccess permanently suspended.というエラーメッセージを出力したため、確保できなかった。
3.1.2. tokenlinux.sh - Downloader
linux、macOSで実行されるtokenlinux.shファイルはダウンローダーであり、LLMによって作成されたものと判断される。
これまでにContagious Interviewで使用されたスクリプトとは異なり、コメントが詳細に作成されており、コメント内で絵文字を使用するパターンが確認されたため、LLMを活用して作成されたものとみられる。

caption - 詳細で絵文字が含まれているコメント
tokenlinux.shは、現在のパスにnodejsディレクトリが存在するかどうかを確認し、該当のディレクトリが存在しない場合は、nodejsをダウンロードした後に解凍する。解凍後にnodejsをシステムPATHに追加し、C&Cサーバーからparser.jsおよびpackage.jsonファイルをダウンロードして$HOME/Documentsのパスに保存する。
その後、ダウンロードされたnodejsを利用してparser.jsファイルを実行する。このとき、一緒にダウンロードされたpackage.jsonには、parser.jsの実行に必要なパッケージ情報が含まれている。
3.1.3. - parser.js - Downloader
parser.jsはobfuscator.ioによって難読化が施されたダウンローダーである。JavaScriptで作成されており、適用された主な難読化方式は以下の通りである。
文字列の抽出および配列化:コード内で使用される主要な文字列を、別の配列にまとめて保存する。
実行時の配列シャッフル:文字列の配列は、コード実行の初期に特定のロジックによって順序が再配置される。
オフセットベースの文字列アクセス:文字列の位置を直接参照することなく、オフセット値を引数として受け取る別の関数を経由して、配列内の文字列を呼び出す。
識別子の変造:意味のある変数名や関数名を、a1、alのような無意味で短い名前に変更する。

caption - 難読化が適用された様子
難読化のほかにも、コードが修正またはフォーマット(整列)されている場合に、ダミーコードが実行されてエラーが発生するようにする保護手法が適用されている。

caption - 保護手法に関連する関数
2つのC&Cサーバーと通信するが、それぞれの目的は以下の通りである。
情報受信用C&Cサーバー:Beavertailをダウンロードするための情報(2番目のC&CサーバーのアドレスおよびキャンペーンID)の受信
マルウェアダウンロード用C&Cサーバー:Beavertailのダウンロード
情報受信用C&Cサーバーのアドレスはbase64でエンコードされており、2つのアドレスが存在する。もし1番目の情報受信用C&Cサーバーとの通信に失敗した場合は、2番目の情報受信用C&Cサーバーと通信する。

caption - 情報受信用C&Cサーバーのアドレスデコードルーチン
hxxp://[中間サーバー]:1244/s/6df937fe9011へのアクセス結果がZT3で始まる場合、それ以降の値をbase64でデコードする。デコードされた値は、,を基準として前部分がマルウェアダウンロード用C&Cサーバーのアドレス、後ろ部分がキャンペーンIDの値である。2026年1月26日基準で、C&Cサーバーのアドレスは66.235.175[.]117、キャンペーンIDはknHbMe8である。

caption - マルウェアダウンロード用C&Cサーバーのアドレスデコードルーチン
文字列はxorで復号して使用し、このときのキーは0x70a07948である。

caption - 文字列復号ルーチン
マルウェアのダウンロードおよび実行プロセスは以下の通りである。
ホームディレクトリに.vscodeフォルダーを作成する
hxxp://[マルウェアダウンロード用C&Cサーバー]:1244/keyにホスト名、ユーザー名、現在時刻を送信するhxxp://[マルウェアダウンロード用C&Cサーバー]:1244/j/[キャンペーンID]からBeavertailをダウンロードする保存パス:
.vscode/test.js
hxxp://[マルウェアダウンロード用C&Cサーバー]:1244/pからtest.jsを動作させるためのパッケージファイルをダウンロードする保存パス:
.vscode/package.json
.vscode/test.jsを実行する
マルウェアのダウンロードルーチンは約10分ごとに繰り返され、計3回実行される。
3.1.4. Beavertail
Beavertailマルウェアは計3つのJavaScriptファイルで構成されており、最初に実行されるtest.jsから残りの2つのファイルをダウンロードして実行する。また、すべてのBeavertailマルウェアには、parser.jsと同様の方式の難読化と保護手法が適用されている。
test.js
ブラウザ情報を収集し、n.jsとp.jsをダウンロードして実行する。情報を収集するブラウザの一覧は以下の通りである。
Chrome
Chromium
Brave
Opera
ブラウザに保存されたアカウント情報とブラウザ拡張情報を収集し、hxxp://66.235.175[.]117:1244/uploadsへとアップロードする。このとき、情報収集の対象となるブラウザ拡張の一覧は以下の表の通りである。
caption - 情報収集対象のブラウザ拡張リスト
アップロードが完了すると、hxxp://66.235.175[.]117:1244/client/knHbMe8からファイルをダウンロードして.nplとして保存する。ダウンロードした.nplファイルはInvisibleFerretであり、Pythonを通じて実行される。このとき、OSがwindowsである場合は、hxxp://66.235.11[.]117:1244/pdoからPythonをダウンロードして.nplファイルを実行する。

caption - .nplファイルのダウンロードルーチン
InvisibleFerretの実行後、残りのBeavertailマルウェアをhxxp://66.235.11[.]117:1244/n/knHbMe8およびhxxp://66.235.11[.]117:1244/z/knHbMe8からダウンロードし、それぞれ.vscode/n.js、.vscode/p.jsとして保存して実行する。

caption - 追加のBeavertailダウンロードルーチン
n.js
バックドアマルウェアであり、まずシステム情報を収集した後にhxxp://66.235.175[.]117:1244/keysへとアップロードする。収集するシステム情報は以下の通りである。
IPを通じて確認した位置情報
ISP情報
ユーザー名をHMACでダイジェストしたuuid
ホスト名
ユーザー名
オペレーティングシステムの種類
OSのリリース情報
OSのバージョン
アップロード後、C&Cサーバーとソケット接続を確立して通信する。このとき、C&Cサーバーのアドレスは216.250.251[.]87であり、ポート番号は1247である。

caption - ソケット接続ルーチン
接続が確立すると、ソケットを通じてC&Cサーバーからcode値を受信し、受信したcode値に応じて実施する行為は以下の表の通りである。
caption - バックドア行為
ファイルをアップロードするときはFTPを利用し、使用されるFTPサーバーのドメイン、ユーザー名、パスワードはC&Cサーバーから送信される。アップロードのパスは/DAknHbMe8/[ホスト名]+[ユーザー名]/[ファイル名]である。

caption - FTPアップロードルーチン
ssh_envコマンドは、パスに以下の表に含まれる文字列が含まれているファイルを探索してアップロードする。
caption - 探索文字列リスト
このとき、tsconfig.jsonのように特定の名前や拡張子を持つファイルはアップロードせず、node_modulesのような特定フォルダは探索しない。詳細なリストは「付録 C. 探索条件」を参照のこと。
p.js
ファイルを収集およびアップロードするマルウェアである。以下の表に含まれるパターンを満たすパスのファイルを探索してアップロードする。
caption - 探索パターンリスト
n.jsと同様に特定のパスは探索せず、特定の拡張子を持つファイルはアップロードしない。詳細なリストは「付録 C. 探索条件」を参照のこと。

caption - アップロードファイル探索ルーチン
ファイルのアップロードは、hxxp://66.235.175[.]117:1244/uploadsに対して以下のような構造のPOSTリクエストを送信して行う。
上記の構造において、ファイルインデックスは、探索パターンでマッチングして生成したファイルリスト内での該当ファイルの順序を意味する。ファイルのアップロードが完了すると、ファイルパス、ホスト名を以下のような構造でhxxp://66.235.175[.]117:1244/keysへとアップロードする。
3.1.5. InvisibleFerret
InvisibleFerretはPythonで記述されたマルウェアであり、5つのPythonスクリプトで構成されている。すべてのInvisibleFerretスクリプトは、以下のような方法で難読化されている。
難読化された文字列の最初の8文字を除いた以降の文字列をbase85でデコードする。
デコードされた結果を、使用しなかった最初の8文字とxorした後にexecで実行する。
execで実行された文字列は、再び新しい文字列を反転させてbase64でデコードし、zlibで圧縮した後にexecで実行する。
3番目のプロセスを64回ほど繰り返すと、実際のマルウェアスクリプトが実行される。
.npl
Beavertailから実行されたInvisibleFerretスクリプトであり、2つの追加スクリプトをダウンロードして実行する。

caption - スクリプトのダウンロードおよび実行ルーチン
hxxp://66.235[.]175.117:1244/payl/knHbMe8からファイルをダウンロードして.vscode/payに保存した後に実行し、hxxp://66.235[.]175.117:1244/bro/knHbMe8からファイルをダウンロードして.vscode/bowに保存した後に実行する。このとき、OSがDarwinである場合、bowファイルはダウンロードしない。
pay
C&Cサーバーのソケット接続を通じて受信したcode値に応じて、不正な行為を実行するバックドアマルウェアである。C&Cサーバーのアドレスは216.250.251[.]87であり、ポート番号は1245である。

caption - ソケット接続ルーチン
受信したcode値に応じて実施する行為は以下の表の通りである。
caption - バックドア行為
ssh_envコマンドは、パスに以下の表に含まれる文字列が含まれているファイルを探索してアップロードする。
詳細なリストは「付録 C. 探索条件」を参照のこと。
bow
TsunamiInjectorスクリプトを難読化した後にstartupフォルダーに保存し、スクリプトが持続的に実行されるように設定する。

caption - スクリプト保存ルーチン
TsunamiInjectorスクリプトは、約1000個の暗号化されたurlを復号してアクセスし、中身が存在するurlを探索する。復号プロセスは以下の通りである。
16進数でエンコードされた文字列をデコードする。
デコードされた文字列を
!!!HappyPenguin1950!!!でxorする。復号された文字列をbase64でデコードした後に順番を反転させる。

caption - URL復号ルーチン
復号されたurlはすべてテキスト共有サイトであるpastebinのurlであり、内容が残っているpastebinのurlを発見した場合、該当ページのコンテンツを上記と同様の方法で復号する。復号された結果は別のurlであり、該当のurlからファイルをダウンロードして`%APPDATA%\Microsoft\Windows\Applications\Runtime Broker.exe`に解凍する。

caption - ファイルダウンロードルーチン
ファイルのダウンロードが完了すると、該当のファイルパスをWindows Defenderの検知除外パスに追加し、ユーザーがログインするたびに実行されるようにタスクを作成する。

caption - タスク作成ルーチン
adc
hxxp://66.235.175[.]117:1244/andから、リモートデスクトップ制御プログラムであるAnyDeskをダウンロードする。その後、ダウンロードしたAnyDeskの設定を更新し、攻撃者のアカウントでいつでもリモート接続ができるように変更する。

caption - AnyDesk設定更新ルーチン
mc
ブラウザ環境を操作し、最終的に暗号資産ウォレットのブラウザ拡張機能をインストールする。実行時には、まず自己削除を行う。

caption - 自己削除ルーチン
その後、ChromeおよびBraveブラウザの拡張機能ディレクトリを探索し、特定の拡張機能のファイルをすべて削除する。削除対象となる拡張機能のID一覧は以下の通りである。
nkbihfbeogaeaoehlefnkodbefgpgknn
acmacodkjbdgmoleebolmdjonilkdbch
拡張機能ファイルの削除が完了すると、hxxp://45.59.163[.]55:1244/mmz/[ブラウザ拡張ID]_knHbMe8からファイルをダウンロードして、削除した既存の拡張機能ディレクトリに解凍する。このプロセスにおいて変更されるブラウザ拡張機能はRabby WalletおよびMetaMaskで、いずれも暗号資産ウォレットに関連する拡張機能である。

caption - ブラウザ拡張ファイルの変更ルーチン
その後、マルウェアはChromeブラウザのプロファイル設定ファイルを収集してhxxp://45.59.163[.]55:1244/hへ送信する。サーバーから正常なレスポンスを受信した場合、そのレスポンス値を利用してChromeのSecure Preferences設定を操作する。
追加で、macOS環境においてChromeのメジャーバージョンが140以上である場合、hxxp://45.59.163[.]55:1244/ddoからファイルをダウンロードして/Applications/Google Chrome.appのパスに上書きする方法で、Chromeのダウングレードを試みる。

caption - Chromeダウングレードルーチン
設定変更が完了すると、変更内容を即座に反映させるために、ブラウザに保存されたクッキー、キャッシュ、セッションデータなどをすべて削除し、成功したかどうかのステータスをhxxp://66.235.175[.]117:1244/tへと送信する。
3.2. OtterCookie
3.2.1. task.json - Downloader
該当のダウンローダーはVSCodeによってのみ実行される。runOptionsのrunOnオプションがfolderOpenに設定されているため、リポジトリのフォルダーがVSCodeで開かれた場合に、自動的に挿入されたコマンドが実行される仕組みである。BeavertailやInvisibleFerretの配布に使用されたtask.jsonファイルとは異なり、コマンドが隠されていない。

caption - .vscode/tasks.jsonに挿入されたコマンド
オペレーティングシステム別でダウンロードするURLは異なるが、linuxとmacOSのダウンロードスクリプトは同一である。また、すべてのスクリプトに共通して、新しいスクリプトをダウンロードして実行する。
OSがlinux、macOSである場合、$HOME/.vscode/vscode-bootstrap.shファイルとしてシェルスクリプトをダウンロードして実行する。

caption - linux、macOSで実行されるシェルスクリプト
OSがwindowsである場合、%USERPROFILE%\.vscode\vscode-bootstrap.cmdファイルとしてcmdスクリプトをダウンロードして実行する。

caption - windowsで実行されるcmdスクリプト
しかし、分析当時において、windowsでダウンロードされるcmdスクリプトはAccess permanently suspended.というエラーメッセージを出力したため、確保できなかった。
3.2.2. vscode-bootstrap.sh - Downloader
linux、macOSで実行されるvscode-bootstrap.shファイルはダウンローダーであり、tokenlinux.shと同様にLLMによって作成されたものと判断される。異なっている点として、絵文字が使用されていない。

caption - 詳細なコメントが記述されたシェルスクリプト
vscode-bootstrap.shは現在のパスにnodejsディレクトリが存在するかどうかを確認し、該当のディレクトリが存在しない場合は、nodejsをダウンロードした後に解凍する。解凍後、C&Cサーバーからenv-setup.jsおよびpackage.jsonファイルをダウンロードして$HOME/.vscodeのパスに保存する。その後、ダウンロードされたnodejsを利用してenv-setup.jsを実行する。
3.2.3. env-setup.js - Downloader
env-setup.jsは、hxxps://y-lilac-sigma.vercel[.]app/api/ipcheck-encrypted/608にアクセスしてレスポンスをevalで実行するダウンローダーである。特異な点は、正常なレスポンスが取得されたときではなく、エラーが発生したときに実行されることである。

caption - env-setup.jsのコード
3.2.4. OtterCookie
env-setup.jsを通じてダウンロードおよび実行され、Beavertailと同様の方式の難読化と保護手法が適用されている。
OtterCookieは、文字列として保存された3つのスクリプトを、それぞれ個別のプロセスで実行する。このとき、lockファイルに{ pid: [プロセス PID], startedAt: [プロセス起動時刻] }のコンテンツを記述し、スクリプトが重複して実行されないようにする。lockファイルの名前とスクリプトの情報は以下の表の通りである。
caption - lockおよびスクリプト情報
ldbScript
ブラウザに保存されたアカウント情報とブラウザ拡張機能を収集するスクリプトである。情報収集の対象となるブラウザの一覧は以下の表の通りである。
caption - 情報収集対象のブラウザリスト
情報収集の対象となるブラウザ拡張機能の一覧は以下の表の通りである。
caption - 情報収集対象のブラウザ拡張リスト
autoUploadScript
すべてのドライブを対象に、特定の文字列が含まれるファイルを探索したうえで、hxxp://172.86.73[.]198:8086/uploadへアップロードする。探索に使用される文字列については「付録 C. 探索条件」を参照のこと。

caption - ファイルアップロードルーチン
このとき、ldbScriptのファイルアップロード方式とは異なり、ファイルのメタデータは存在せず、HMACトークンの作成にファイルパスを使用する。
autoUploadScriptもコメントが詳細に施されていることや、ユーザーには表示されないコンソール出力が頻繁に行われることなどの特徴があり、LLMを介して作成されたものと推測される。
socketScript
システム情報を収集し、hxxp://172.86.73[.]198:8087/api/notifyへと送信する。収集するシステム情報と送信する形式は以下の通りである。
その後、C&Cサーバーに対してソケット接続を確立する。C&Cサーバーのアドレスは172.86.73[.]198で、ポート番号は8087である。ソケットを通じてC&Cサーバーから受信したメッセージに応じて実施する行為は以下の表の通りである。
caption - メッセージに応じて実行される行為
processControl機能は、ldbScript、autoUploadScript、socketScriptを停止または再開できるように設計されているが、現時点では停止機能のみが実装されている。

caption - 未完成のprocessControl機能
socketScriptもコメントが詳細に施されていることや、ユーザーには表示されないコンソール出力が頻繁に行われることなどの特徴があり、LLMを介して作成されたものと推測される。
4. 追加のC&Cサーバーの確保
Beavertail、InvisibleFerretのC&Cサーバーには、共通して以下のような特徴がある。
1244番ポートにHTTPサーバーが存在する。
21(FTP)、3389(RDP)ポートが有効になっている。
主にVPSホスティング業者を利用してサーバーを運営している。
hxxp://[C&Cサーバー]:1244/pにアクセスすると、package.jsonファイルを返す。
特徴1、2、3を利用して、まずはCensysから関連するIPを18個発見することができた。

caption - Censysの検索結果
次に、確保したIPに対してhxxp://[IP]:1224/pのアクセス結果を確認し、最終的に10個のC&Cサーバーアドレスを特定した。C&Cサーバーアドレスの一覧は以下の表の通りである。
caption - 追加で特定されたC&Cサーバー一覧
C&CサーバーはすべてVPSホスティングを利用しており、ホスティング業者が異なる場合でも、IPの位置情報はアメリカであることが確認された。また、130.65.230[.]100、66.235.175[.]117、66.235.175[.]109を除いた7つのIPでは、445番ポート(SMB)が有効になっている。
これ以外のほとんどのC&Cサーバーは、誤ったキャンペーンIDを使用してリクエストを送信すると応答がなかったが、66.235.175[.]109、38.92.47[.]152、45.59.163[.]23の3つのC&Cサーバーからは応答があった。
38.92.47[.]152はエラーメッセージを応答として返し、66.235.175[.]109と45.59.163[.]23はリクエストとして送信された誤ったキャンペーンIDを応答として返した。
OtterCookieのC&Cサーバーは防弾ホスティング(Bulletproof Hosting)によって保護されているため、追加のC&Cサーバーを確保することはできなかった。
5. おわりに
本稿では、GitHubにおいてVSCodeの自動化機能を悪用して配布された「Contagious Interview」キャンペーンを分析した。最終段階で実行されるマルウェアはBeavertail、InvisibleFerret、OtterCookieであることが確認されており、感染したシステムからブラウザの資格情報や暗号資産(仮想通貨)ウォレット関連ファイルなどの機密情報を窃取し、C&Cサーバーからのコマンドを受信して遠隔操作や追加のマルウェアダウンロードなどの悪意ある行為を行うことが確認された。
VSCodeの機能を悪用した攻撃は、プロジェクトを開くだけで一部の開発ツールが設定に従ってコードを自動実行する可能性があるため、継続的な注意が必要である。特にVSCodeの使用時、Workspace Trust機能が有効になっているかを確認し(security.workspace.trust.enabled、デフォルト値はtrue)、信頼を付与する前にエディタの設定とワークスペースの構成を事前に検証することが推奨される。この際、.vscodeディレクトリ、使用中のツールチェーン、拡張機能(Extension)の設定を優先的に監査することで、自動実行の経路や予期せぬ動作の可能性を最小限に抑える必要がある。
特に今回のキャンペーンは、生成AI(LLM)を活用して悪意あるスクリプトを作成することで、攻撃ツールの開発効率を向上させており、実際の企業の採用担当者へのなりすましや、一般の開発者を装ったオープンソースプロジェクトへの寄与(コントリビューション)など、ソーシャルエンジニアリングの手法が確認された。さらに、分析の過程で攻撃者が運用する多数の追加C&Cサーバーを特定しており、これにより攻撃インフラが継続的に拡張および運用されている状況が確認された。
現在もContagious Interviewキャンペーンが観測されており、攻撃者はGitHubを中心としたオープンソースのエコシステムや開発者をターゲットにしている。特に、採用課題やインタビュー用プロジェクト、テストコードなどに偽装したリポジトリにおいて、開発ツールの自動化機能を悪用する攻撃手法は、キャンペーンの攻撃手法が継続的に進化している事実を裏付けている。
6. 付録
u4ed5u69d8u66f8 A. MITRE ATT&CK
caption - MITRE ATT&CK
u4ed5u69d8u66f8 B. IOCs
sha256
caption - sha256
ip
216.250.251[.]211
216.250.251[.]87
45.59.163[.]23
45.59.163[.]55
38.92.47[.]152
103.65.230[.]100
147.124.213[.]19
66.235.175[.]117
66.235.175[.]109
147.124.202[.]225
67.203.7[.]205
147.124.213[.]232
172.86.73[.]198
URL
hxxps://vscode-load-config.vercel[.]app/settings/mac?flag=4
hxxps://vscode-settings-config.vercel[.]app/settings/windows?flag=8
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/linux?flag=306
hxxps://vscode-helper171-ruby.vercel[.]app/settings/windows?flag=4
hxxps://www.vscodeconfig[.]com/settings/mac?flag=1
hxxps://www.vscodeconfig[.]com/settings/mac?flag=3
hxxps://vscodesettings03kui.vercel[.]app/api/settings/mac
hxxps://www.vscodeconfig[.]com/settings/windows?flag=3
hxxps://vscode-helper171.vercel[.]app/settings/linux?flag=4
hxxps://vscode-load-config.vercel[.]app/settings/linux?flag=4
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/linux?flag=301
hxxps://www.vscodeconfig[.]com/settings/mac?flag=4
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/mac?flag=302
hxxps://www.vscodeconfig[.]com/settings/linux?flag=1
hxxps://vscode-helper171-ruby.vercel[.]app/settings/linux?flag=6
hxxps://vscode-toolkit-bootstrap.vercel[.]app/settings/windows?flag=306
hxxps://vscode-settings-config.vercel[.]app/settings/linux?flag=606
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/windows?flag=306
hxxps://vscode-load.onrender[.]com/settings/linux?flag=5
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/windows?flag=302
hxxps://vscode-toolkit-bootstrap.vercel[.]app/settings/mac?flag=306
hxxps://vscode-settings-config.vercel[.]app/settings/mac?flag=8
hxxps://vscode-helper171-ruby.vercel[.]app/settings/mac?flag=3
hxxps://vscode-load-config.vercel[.]app/settings/linux?flag=1
hxxps://www.vscodeconfig[.]com/settings/windows?flag=4
hxxps://vscode-helper-132.vercel[.]app/settings/windows?flag=4
hxxps://vscode-helper-132.vercel[.]app/settings/linux?flag=4
hxxps://vscodesettingstask.vercel[.]app/api/settings/windows
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/mac?flag=306
hxxps://vscode-load-config.vercel[.]app/settings/windows?flag=1
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/linux?flag=302
hxxps://vscode-load.onrender[.]com/settings/windows?flag=5
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/mac?flag=308
hxxps://vscode-helper171-ruby.vercel[.]app/settings/windows?flag=6
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/windows?flag=301
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/windows?flag=305
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/mac?flag=305
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/linux?flag=308
hxxps://codeviewer-three.vercel[.]app/task/windows?token=6df937fe9011
hxxps://vscode-helper171-ruby.vercel[.]app/settings/linux?flag=4
hxxps://vscode-helper171-ruby.vercel[.]app/settings/windows?flag=3
hxxps://vscodesettingstask.vercel[.]app/api/settings/linux
hxxps://vscode-helper171.vercel[.]app/settings/windows?flag=4
hxxps://vscode-helper171-ruby.vercel[.]app/settings/linux?flag=3
hxxps://codeviewer-three.vercel[.]app/task/windows?token=f93a80304111
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/mac?flag=301
hxxps://codeviewer-three.vercel[.]app/task/mac?token=2a643f1b401f
hxxps://vscode-load.onrender[.]com/settings/mac?flag=5
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/windows?flag=308
hxxps://codeviewer-three.vercel[.]app/task/linux?token=f93a80304111
hxxps://vscode-load-config.vercel[.]app/settings/windows?flag=4
hxxps://vscode-helper-132.vercel[.]app/settings/mac?flag=4
hxxps://codeviewer-three.vercel[.]app/task/mac?token=6df937fe9011
hxxps://codeviewer-three.vercel[.]app/task/linux?token=6df937fe9011
hxxps://vscodesettingstask.vercel[.]app/api/settings/bootstraplinux
hxxps://vscode-settings-config.vercel[.]app/settings/mac?flag=9
hxxps://vscode-settings-config.vercel[.]app/settings/linux?flag=9
hxxps://vscode-helper171.vercel[.]app/settings/mac?flag=4
hxxps://vscode-helper171-ruby.vercel[.]app/settings/mac?flag=6
hxxps://vscodesettings03kui.vercel[.]app/api/settings/windows
hxxps://vscode-load-config.vercel[.]app/settings/mac?flag=1
hxxps://codeviewer-three.vercel[.]app/task/windows?token=2a643f1b401f
hxxps://codeviewer-three.vercel[.]app/task/mac?token=f93a80304111
hxxps://vscode-settings-config.vercel[.]app/settings/windows?flag=9
hxxps://www.vscodeconfig[.]com/settings/windows?flag=1
hxxps://vscode-settings-config.vercel[.]app/settings/mac?flag=606
hxxps://vscode-toolkit-bootstrap.vercel[.]app/settings/linux?flag=306
hxxps://vscodesettings03kui.vercel[.]app/api/settings/linux
hxxps://www.vscodeconfig[.]com/settings/linux?flag=4
hxxps://vscode-settings-config.vercel[.]app/settings/windows?flag=606
hxxps://vscode-settings-bootstrap.vercel[.]app/settings/linux?flag=305
hxxps://www.vscodeconfig[.]com/settings/linux?flag=3
hxxps://vscode-helper171-ruby.vercel[.]app/settings/mac?flag=4
hxxps://vscodesettingstask.vercel[.]app/api/settings/mac
hxxps://codeviewer-three.vercel[.]app/task/linux?token=2a643f1b401f
hxxps://vscode-settings-config.vercel[.]app/settings/linux?flag=8
Github repository
hxxps://github[.]com/veneliteus-dev/casino-game/
hxxps://github[.]com/brahmabit/be_challenge_blockchain/
hxxps://github[.]com/vnvstore/funtico-labs-assessment-15/
hxxps://github[.]com/samuelmeadowbiankah/felina/
hxxps://github[.]com/nhonlvsoict/skill-test-main/
hxxps://github[.]com/goldendragon68/Bullana/
hxxps://github[.]com/ivanwassaf/skill-test/
hxxps://github[.]com/SettleMint-Tech-Hub5/SettleMint_Platform/
hxxps://github[.]com/veneliteus-dev/exchange-backend/
hxxps://github[.]com/0x9x-sketch/Oasis361/
hxxps://github[.]com/eastmade/web3project-momo-token/
u4ed5u69d8u66f8 C. u691cu7d22u6761u4ef6
u691cu7d22u3057u306au3044u30d5u30a9u30ebu30c0
caption - u691cu7d22u3057u306au3044u30d5u30a9u30ebu30c0u30eau30b9u30c8
u30a2u30c3u30d7u30edu30fcu30c9u3057u306au3044u62e1u5f35u5b50
caption - u30a2u30c3u30d7u30edu30fcu30c9u3057u306au3044u62e1u5f35u5b50u30eau30b9u30c8
autoUploadScript u691cu7d22u6587u5b57u5217
caption - autoUploadScript u691cu7d22u6587u5b57u5217u30eau30b9u30c8

人気の記事





