世界を動かす技術を、日本語で。

脅威アクターが「Microsoft Visual Studio Code」の悪用を拡大

概要

  • Jamf Threat Labs がVisual Studio Codeの tasks.json 悪用の新手法を発見
  • Contagious Interview キャンペーンの進化した感染経路を解説
  • 辞書ファイル型の難読化JavaScript による攻撃手法の詳細
  • Node.js実行・C2通信・リモートコード実行 の実装内容
  • 開発者向けの防御策 と注意点を提案

Visual Studio Codeタスク設定ファイルの悪用進化

  • 北朝鮮(DPRK)関連グループ によるContagious Interviewキャンペーンの新たな攻撃手法
  • GitHubやGitLab 上の悪意あるリポジトリを利用した感染経路
  • Visual Studio Code でリポジトリを開くと、信頼確認後に tasks.json が自動実行
  • macOS ではnohup bash -cとcurlで外部JavaScriptペイロードを取得、 Node.js で実行
  • vercel.app など正規サービスを悪用したペイロードホスティング
  • Jamf Threat Labsが悪質リポジトリをGitHubに報告、削除対応

JavaScriptペイロードの分析

  • ペイロードは 冗長コードや未使用関数 を多く含み、難読化・解析妨害を意図
  • コア機能 はバックドア実装
    • リモートコード実行 :攻撃者が任意のJavaScriptを実行可能
    • システム指紋収集 :ホスト名、MACアドレス、OS情報を収集
    • C2通信 :5秒ごとにC2サーバーへビ―コン送信・指示待機
    • IPアドレス取得 :ipify.org経由で外部IP判定
  • 追加JavaScript取得・実行や 自己削除・痕跡消去 機能も搭載
  • AIアシスト生成を示唆するコメント も一部に確認

攻撃チェーンの流れ

  • 被害者が 採用試験や技術課題 を装ったリポジトリをクローン・開封
  • Visual Studio Codeで信頼設定後、 tasks.json 経由でコマンド実行
  • Node.js 経由でペイロード取得・実行、バックドア常駐
  • C2サーバーと通信し、追加命令やさらなるペイロードを受信・実行

開発者・組織向けの防御策

  • Jamf Threat Prevention および Advanced Threat Controls のブロックモード有効化推奨
  • サードパーティリポジトリ の信頼設定前に内容精査
  • npm install 実行時は package.json・インストールスクリプト・タスク設定 の確認必須
  • 不審なリポジトリやコード の利用回避

まとめと今後の展望

  • DPRK系攻撃者 の手法は 開発者の実運用フロー に巧妙に組み込まれる傾向
  • Visual Studio CodeやNode.js など開発ツールの設定ファイル悪用が拡大
  • Jamf Threat Labsは今後も 手口の進化 を継続監視
  • 開発者は セキュリティ意識向上リポジトリ精査 の徹底が必要

関連情報や詳細分析はJamf Threat Labsブログ にて公開

Hackerたちの意見

Eclipseファンの視点から見ると、なんで今VS Codeがデファクトスタンダードになってるんだろう?仕方なくVS Codeを使ってるけど、Eclipseの方が全然良かった気がするし、マルウェアが混ざったプロジェクトのセキュリティ問題も繰り返し出てるし。ここ1、2年で偽のリクルーターによる感染プロジェクトの投稿もいくつかあったしね。多分、Javaが原因でEclipseが人気なくなったんだろうな。

特定の開発ツールを強制するって、なんか変だよね。面接の時に一度だけ見たことがあるけど、みんな同じ環境にしておかないと、お互いのPCに簡単にアクセスできないからって言ってた…それは変だし、赤信号だと思ってその会社には進まなかった。

Eclipseが安全ってわけじゃなくて、単に穴を探してる人が少ないだけだよ。問題はソフトウェアじゃなくて、インターネットからのコードをどう信頼するかだよね。Eclipseを使ってても、偽のリクルーターに騙されて悪いスクリプトを実行させられることもあるし。テキストエディタを変えたところで、ソーシャルエンジニアリングは解決できないよ。

Eclipseファンの視点から見ると、なんで今VS Codeがデファクトスタンダードになってるんだろう?Eclipseは今良くなったの?15年前に使ってたけど、起動に時間がかかって、メモリも食うし、動作も遅かった。チーム全員がEclipseを使うためにRAMをアップグレードしたくらい、当時の会社支給のPC(それなりに良かったけど)じゃEclipseをちゃんと使えなかったから。なんで人気がなくなったのか全然想像できない…

VSCodeに切り替えたのは、無料のエディタでファイルにジャンプするホットキーがすごく使いやすいから。大きなVSがファイルにジャンプする機能を追加したときのことを覚えてるけど、実装がひどくて全然使えなかった。マイクロソフトで10年働いてたけど、大きなソースツリーをナビゲートする一番の方法は「dir /s 部分ファイル名.*」だったよ。あの頃、ほとんどのコードベースはVisual Studioで開けなかったしね。(チームによるけど、私は主に古いC/C++のコードベースにいた。)MSのいくつかのチームはSource Insightっていうエディタにお金を払っていて、コードをインデックス化してCの#defineや他のプリプロセッサマクロも解析できる、すごくユニークでパワフルなツールだった。強力なシンボル検索とファジーファイル名検索の機能があって、フォルダ構造の中でファイルを見つけるためにSource Insightを開いておくことがよくあった。最初にSSDを手に入れたとき、開発の生産性が一番上がったのはコンパイル時間じゃなくて、ディレクトリ構造の中でファイルを見つける速さだった。Vi/Emacsのユーザーはこれを全部やってくれる魔法のプラグインを持ってるかもしれないけど、2000年代と2010年代のWindowsユーザーとしては、MSのツールはこれに関してはひどかった。そこにVS Codeが登場して、素晴らしいファジーファイル名マッチングができるようになった。すごいよね。確かに本物のVisual Studioの90%の機能は欠けてるけど(フロントエンドのウェブコードからバックエンド、SQLのストアドプロシージャにデバッガーがステップインできるのは、マイクロソフトが20年前に実現してたことだし、今のツールでは不可能なダークマジックと見なされるだろうけど)、プロジェクトをすごく早くナビゲートできるのは素晴らしい!

私にとってVSCodeは超軽量で、同時に十分な機能があるんだ。Eclipseは何年も使ってなかったけど、記憶ではすごく重かった。Java以外のサポートはほとんどなかったしね。面白いことに、JavaだけはVSCodeのサポートが悪いから、Javaプロジェクト用にIdeaのライセンスを買い続けてる。私が使う他の言語(JS/TS、Go、Python、Shell、YAML、XML)にはVSCodeを使ってて、満足してるよ。最近はVSCodeがAI関連で膨れ上がってきてるけど、今のところAI機能を一つの設定で全部無効にできて、その後は問題なく動いてる。AI機能は別のプラグインにまとめて、インストールしない選択肢があればいいんだけど、今のマネージャーはみんなにAIを押し付けたがるみたいだね。VSCodeのもう一つの良いところは、JavaScriptで書かれていてブラウザで起動できること。将来的には開発環境をブラウザに移したいけど、まだ実現できてない。

数年前に切り替えた理由は、ssh経由のリモートセッションサポートが素晴らしかったから。しばらくその選択を再評価してないけど、今ではそれに加えてLSPサポート(あとはMLのオートコンプリートも少し)も必須になってる。

速さがあって、サクッと使えるデフォルトが整ってるから。MSが初期プラグインを提供して、エコシステムが発展したんだ。説明されている脅威モデルはVS Code特有のものじゃないよ。

Eclipseはあんまり好きじゃなかったけど、JetBrainsのIDEが好きなのに、VSCodeを使わざるを得なかった。だって、ちゃんとしたクライアントサーバーモードを持ってる現代的なエディタはそれだけだから。つまり、UIをローカルで表示しながら、コードのインデックス作成やインテリジェンスをサーバーでやってるってこと。企業の世界では、セキュリティアップグレードでスクリプト言語の間違ったバージョンがインストールされて、ノートパソコンがめちゃくちゃになるのを助けるより、使い捨てのリモートVMを維持する方が楽なんだよね。

昔はEclipseも使ってたけど、最近はほとんどVSCodeしか使ってない。素晴らしいテキストエディタだよ。マルチライン選択や編集ツールがすごくて、ファイル検索も瞬時にできるし、ファイル名を完全に正確に入力する必要もない。最近はサイドバーを使ってファイルを探すことはほとんどなくて、ctrl+eショートカットを打ってファイル名の数文字を入れるだけで、すぐに結果が出る。小さなことだけど、影響は大きい。比較のために言うと、VSはファイル検索に数秒かかるし、ワークスペースにインポートされていないファイルを見逃すこともある。その違いがあるから、VSは私には役に立たない。

私もVS Codeはあんまり好きじゃないけど、半ダースの半分くらいのマイナーな言語を使うことが多いから、VS Codeを使ってる。これが唯一の[0]エディタだから。[0]: VimやEmacsもほぼ同じくらい、もしくは少しだけ良い言語サポートがあるけど、私はTUIよりGUIが好きなんだよね。

フォルダを開くだけで隠れたコードが実行されるって、怖いよね。便利さと引き換えに安全を失って、今そのツケを払ってる感じ。ユーザーはファイルを信頼するボタンをクリックしちゃうよね、作業が早くなると思ったら。ソフトウェアの設計がミスをしやすくしてるから、彼らを責めることはできないよ。

フォルダを開くときに、そのフォルダを信頼するかどうか聞いてこない?

まぁ、Vimもこれまでに実行脆弱性があったことは確かだよね。https://github.com/numirias/security/blob/master/doc/2019-06...

安全を便利さと引き換えにしたんだよね。これが初めてじゃないけど。LLMも同じだね。

またマクロ有効なOfficeファイルの話か。

次は、JavaScriptの仮想オペレーティングシステムだね。

tasks.jsonは自動で実行されるの?追加のユーザー操作が必要だと思ってたんだけど?

記事は「そのまま実行される」とは言ってないけど(「結果として実行される可能性がある」)、ちょっとあいまいだよね。 > プロジェクトが開かれると、Visual Studio Codeはユーザーにリポジトリの作者を信頼するよう促す。その信頼が与えられると、アプリケーションはリポジトリのtasks.json設定ファイルを自動的に処理することになり、システム上で任意のコマンドが実行される可能性がある。スクリーンショットでは、そのタスクは「node」と名付けられているから、悪意のあるMakefileターゲットをバックドアとして埋め込むようなものだね。ただ、.vscode/somethingsomethingのjsonファイルにあるから、見つけにくいのが難点。 (たぶん、GH Copilotを簡単に騙して実行させることもできるし)

依存関係が長くて、LLMやこれらの脅威モデルがある中で、コンテナ内での開発がデフォルトのワークフローになるべきだと思う。

より良いアプリケーションのサンドボックス化が必要だと感じるけど、オープンソースソフトウェアの多くはUnixの抽象化に基づいているから、コンテナ内で動かさなきゃいけない。でも、macOSにはコンテナがないみたいだし、コンテナ自体もあまり良い抽象化とは言えない。ただ、Unixがコアにある中ではこれがベストかも。Robloxスタジオに近いものがあれば面白いと思う。環境を開くと、バックグラウンドで色々立ち上がって、良いデバッガーやログ、開発IDE、良いレンダリング(例えば3Dグラフィックス)があって、別のプロジェクトは独立していて、ゲーム(アプリやプロジェクト)をスピンダウンするときは全部がスピンダウンする感じ。

開発マシンを乗っ取られないためにはいいアイデアだけど、十分じゃないよね。結局、作業中のコードがめちゃくちゃになって、バックドア付きのアプリがデプロイされたり、感染した開発スクリプトがチームメイトや下流のオープンソースプロジェクトのユーザーに影響を与えたり、APIキーやクラウドの認証情報が危険にさらされることになるから。

Appleは実際にTahoeで独自のコンテナフレームワークを導入したけど、まだ初期段階だね。 https://github.com/apple/container

Appleのコンテナは実際に結構いいよ。なんでそれが悪い抽象だって言うの?

XPCや権限のためにそういうものがあるんだよね。UNIX文化の背景を持つプログラムは、そういうのを使うことにあまり気を使わないけど。

UTMは無料で、ネイティブのmacOS VMを立ち上げられるよ。どうしてもJavaScriptを書かなきゃいけないときは、ここでやるかな。Sha1 Huludのためにね。

VS Codeの設定で「tasks」を検索すると、「Task: Allow Automatic Tasks」が見つかるから、それをオフにしてね。他に何か制限すべきことある?

そう、全部アンインストールしちゃえ。結局、JavaScriptがたくさん乗っかったChromiumに過ぎないから。

今すべてをロックしても、今後新しい便利な「機能」で自動更新されたらどうするの?悪い開発文化はパッチで直せないよ。

USBドライブの自動実行の話を思い出すね。全然学ばないな。

macOSシステムでは、nohup bash -cを使ってcurl -sと組み合わせたバックグラウンドシェルコマンドが実行されて、リモートからJavaScriptペイロードを取得することになる。制限のないアウトバウンド接続、特にcurl/wget/bashから。

これはただの偽りの安心感を与えるだけかもしれないね。私の知る限り、ワークスペースの設定がユーザー設定より優先されるのを無効にする方法はないから、悪意のあるリポジトリが簡単にそれを上書きして、自動タスクを再有効化できちゃうよ。

VSCodeでフォルダを開くときは、そのフォルダを信頼済みとしてマークしない方がいいよ。他にどんなフックが存在するか追跡するのが難しくなるからね(特に各アドオンがそれぞれ独自のものを追加するかもしれないし)。

最初に思ったのは、ノードモジュールをインストールしてインポートして実行するとき、モジュールの作者がスクリプトに書いたコードにローカル実行権限を与えてるってことだよね?ほとんどのプログラミング言語が同じ問題を抱えてるし。RubyのgemやPythonのパッケージの中のコードを誰が審査してるの?好きな言語を追加してみて。で、tasks.jsonについては知らなかったんだけど(VSC使ってないから)、ググったらhttps://code.visualstudio.com/api/extension-guides/task-prov...の例が出てきて、Rubyのrakeを実行することについてだった。だから、悪意のあるパッケージをインストールするよりちょっと悪いかもね。トリガーはエディタから悪意のあるリポジトリを開くことだし。これって一般的なやり方なの?もしそうなら、二つのことを意味するね。1) 開発者がコードをインストールして実行する明示的な選択をしてないから、攻撃の可能性が予期しないもので、2) それはどんな言語のユーザーにも影響する、リモートからのパッケージインストールが安全なものや、そもそもパッケージをインストールしない言語のユーザーにも。

VsCodeで新しいフォルダを開くたびに、そのフォルダを信頼するかどうか聞かれるよね。みんなたぶん「はい」って言っちゃうけど、信頼できないフォルダを開くのが危険だってことはちゃんと教えてくれてるよ。

JSエコシステムが悪化してる理由は、機能的なものを作るために必要なパッケージの数が普通の言語よりもずっと多いからだね。

VSCodeユーザーじゃないから、本当に疑問なんだけど、フォルダを開くだけでVSCodeが自動的にタスクを実行する実用的なケースって何?便利のためにnpm inpm startを自動でやってくれるだけなの?それ以外にも正当な目的があるの?

私が使ってたときは、Jekyllサーバーを自動で立ち上げるために使ってたな。サイトの作業をしてると、変更をブラウザで確認したくなるからね。今は切り替えたから、ただ一つコマンドを追加で実行するだけで済むし、大きな手間ではなかったけど、ちょっと便利だったよ。

この機能とは別に、一般的に人々はIDEに言語サーバーを実行させたり、ビルドシステムを設定したり、その他のいろんなことをやってほしいと思ってる。これらはフォルダ内でコードを実行するための設定が必要になることが多いんだ。VSCodeにはこれを防ぐための制限モードがあって、無効にするにはダイアログに同意しなきゃいけないけど、それを無効にするとほとんどの機能も使えなくなっちゃうよ。

この「タスク」機能って本当に役立つの?IDEやテキストエディタは、そもそも自動的に任意のコードを実行すべきじゃないと思う。evalはブロックすべきだし、拡張機能やプラグインは外部ロジック(LSPのプロセスとか)を実行する力を非常に制限するべきだと思う。すべてのプロセスを手動でホワイトリストに入れる必要があるくらいにね。