スティーラーは代用値を持ち去った
10 月 15 日、Symantec は今年初めて確認されたインフォスティーラー Aoki が、コーディングエージェントの認証情報を狙うようになったと報告した。.claude.json、Codex の config.toml と .env ファイル、GitHub Copilot、Cursor、Gemini、JetBrains AI Assistant、Kiro のトークン、そして AWS のキーだ。Bromure Agentic Coding では、これらのファイルにはどれも代用値が入っており、サインイン情報とキーは Mac 上で暗号化されたまま保管される。スティーラーのサーバーへ送られた代用値は、マシンを一時停止させる。
スティーラーのリストの先頭には、いまやコーディングエージェントがある。狙いは .claude.json、Codex の設定、そしてその隣にある .env ファイルだ。
インフォスティーラーが狙うのは、かつてはブラウザの Cookie、保存されたパスワード、暗号資産ウォレット、Discord のトークンだった。Aoki はいまもそれらをすべて盗む。最近のビルドはそれに加えて、コーディングエージェントがホームフォルダに置くファイルも探す。
Symantec の Threat Hunter Team は 10 月 15 日水曜日、Aoki: Infostealer Targets AI Coding Assistant Credentials でこの変化を解説した。同じ日に Infosecurity Magazine も報じている。Aoki は、復号ルーチン内の文字列から Aokigahara とも呼ばれ、今年の初めに登場した。Symantec によれば「以前のバージョンのマルウェアは AI 関連のファイルを狙っていなかった」。最新のサンプルは狙っている。
Aoki が盗むもの
Symantec は最新サンプルが狙うエージェント関連のファイルを列挙している。
.claude.jsonと Claude デスクトップアプリの Cookie。- ChatGPT の Cookie。
- Codex の
config.tomlと.envファイル。 - Cursor のローカル状態データベース。これは「チャットのコンテキストやコード片をキャッシュすることがある」。
- GitHub Copilot、Cursor、Google Gemini、JetBrains AI Assistant、Kiro のトークン。
- AWS 認証情報。
リストの残りは、インフォスティーラーのいつもの獲物だ。40 を超えるブラウザ、約 90 のウォレット拡張機能、デスクトップウォレット、パスワードマネージャー、Telegram、Discord、FTP クライアント、VPN クライアント。Aoki はさらに、名前に secret、privatekey、keystore、mnemonic、passphrase、backup を含むファイルをすべて探す。Symantec は「このマルウェアにはバックドアのコマンドリストがない」と指摘する。見つけたものを集め、C&C サーバーの /gate エンドポイントに POST するだけだ。
エージェントのファイルが手間をかける価値のある理由を、Symantec はこう説明する。「カード情報と同じく、盗んだ AI キーはそのまま現金化できる」。買い手はあなたのアカウントで利用量を使い込む。LLMjacking と呼ばれる手口だ。同じトークンは「攻撃者が正規ユーザーになりすまして活動することを可能にしうる」し、そのアカウントがつながっているリポジトリ、クラウドアカウント、CI/CD パイプラインにまで届く。
Aoki がどうやってマシンに入り込むのか、Symantec は書いていない。コーディングエージェントを使う開発者のノート PC なら、入り口として真っ先に考えられるのはパッケージだ。エージェントは毎日、自分の判断で何十ものパッケージをインストールする。postinstall スクリプトを持つ悪意ある依存パッケージは、npm install が終わった瞬間にエージェントの権限で動き出す。
Bromure マシンで同じリストをたどる
Bromure Agentic Coding では、エージェントは Mac 上の Linux VM で動く。本物の認証情報がその VM に入ることはない。Mac は本物を暗号化された保管庫にしまい、VM には本物と同じ形の代用値を書き込むので、どのツールもそれを受け付ける。Mac 上のプロキシが通信路の上で代用値を本物の値に差し替えるが、それはその認証情報が属するホストへのリクエストに限られる。
Aoki のリストを持ったスティーラーをこの VM に放り込み、チェックリストを一緒にたどってみよう。
.claude.json と Claude のキー
VM 内の Claude Code は代用キー sk-ant-api03-brm-… で動く。Claude のサブスクリプションでサインインした場合、OAuth トークンはサインイン時に Mac 側で取り込まれ、暗号化されて claude-subscription.enc に保存される。ホストは有効期限の 5 分ほど前にアクセストークンを更新し、Anthropic 宛てのリクエストに注入する。VM がリフレッシュトークンを持つことはないので、.claude.json にもホームフォルダのほかのどこにも、スティーラーが盗める有効な Claude 認証情報はない。
Codex の config.toml、auth.json、.env
Codex には、有効期限がはるか先に設定された偽の JWT を収めた ~/.codex/auth.json があらかじめ用意される。クライアントが更新しようとしないようにするためだ。本物の ChatGPT のサインイン情報は Mac 上の codex-subscription.enc にある。OpenAI の API キーは VM 内では sk-brm-… として現れる。
マシンの Credentials ペインで Import env file… を使って取り込んだプロジェクトの .env は、同じ変数名のまま戻ってくる。各値は、あなたが選んだホストに限定された brm_… の代用値だ。あなたのコードはこれまでどおり STRIPE_KEY を読み、スティーラーが読むのは brm_… だ。
GitHub、AWS、SSH
~/.git-credentials と GH_TOKEN には、本物と同じ 40 文字の ghp_ の代用値が入っている。~/.aws/credentials は存在しない。~/.aws/config は credential_process ヘルパーを指しており、このヘルパーは AWS SDK に本物のアクセスキー ID と 40 文字の偽のシークレットキーを渡す。Mac は AWS へ向かうすべてのリクエストに署名し直す。ヘルパーの出力をコピーしたスティーラーが手にするのは、InvalidSignatureException しか生まないシークレットキーだ。
privatekey や id_ed25519 のキーワード検索では何も見つからない。VM 内の SSH_AUTH_SOCK は Mac 上の署名エージェントへのブリッジで、秘密鍵のバイト列がそこを渡ることはない。
Cookie
Aoki は Claude デスクトップアプリと ChatGPT の Cookie を欲しがる。マシンの VM にはデスクトップアプリも、読み取れるブラウザプロファイルもない。Bromure のために Claude や ChatGPT にサインインすると、サインインページは Mac のブラウザで開き、トークンは保管庫に収まる。エージェントは、マシンの VM とは別の使い捨てのサイドカー VM で動く Chromium でブラウズするので、エージェントの VM にいるスティーラーはブラウザのプロファイルに手が届かない。
/gate へのアップロード
Aoki は最後に、獲物を /gate へ POST する。Symantec は dobeqnesmot[.]cc、hjazfioe[.]surf、neihite[.]cc を挙げている。Bromure マシンでは、このリクエストは Mac のプロキシを通らなければ外に出られない。プロキシが VM からネットワークへの唯一の経路だからだ。
プロキシは送信されるすべてのリクエストのヘッダーと本文を調べ、発行先以外のホストへ向かう代用値を探す。sk-ant-api03-brm-… の正当な宛先は Anthropic の系統だけだ。ghp_ の代用値は GitHub のものだ。それらが .cc ドメインへの POST に入っているなら、持ち出し以外の意味はない。プロキシは HTTP 451 を返し、何も転送しない。VM はその場で一時停止し、Mac には This environment may have been compromised が表示される。漏れた代用値ごとに 1 行ずつ、トークンのプレビュー、認証情報の名前、その属するホスト、スティーラーが送ろうとしたホストが並ぶ。
次に何をするかはあなたが決める。Save for Investigation は VM のディスク、ホームフォルダ、共有フォルダを指定したフォルダに書き出してから、マシンをシャットダウンする。Shut down はマシンを止めて侵害済みとしてマークする。侵害済みのマシンは Wipe and Launch を実行するまで起動しない。これはディスクとホームフォルダを入れ替え、トークン、SSH 鍵、設定は残す。Claude のサインイン情報も GitHub トークンも AWS キーも VM に入ったことはないので、スティーラーがコピーしたもののうち、ローテーションが必要なものは何もない。
スキャンより前の段階でアップロードを止めることもできる。マシンの Guardrails ペインで、Outbound connections の Unmatched traffic を Deny にし、マシンに必要なホストを列挙する。そうすれば未知の .cc ドメインへの接続は拒否され、Security Timeline にはその接続の赤い Firewall 行が表示される。
スティーラーがスキャンで代用値を読めないように獲物を梱包したとしても、向こう側のサーバーが受け取るのは、どこでも認証に通らない値だ。代用値が機能するのは、発行先のホストへ向かう途中で Mac のプロキシを通ったときだけだ。
##スティーラーが動き出す前に
エージェントの VM への入り口としていちばんありそうなのは、エージェントがインストールしたパッケージだ。マシンの Supply Chain ペインは、すべての取得を VM に届く前に Mac 上でチェックする。
- 公開日数ゲートはデフォルトで有効で、最低 2 日に設定されている。この基準より新しいパッケージのバージョンは見えなくなる。乗っ取られて数時間で取り下げられたリリースは、
npm installまで届かない。 - インストールスクリプトの除去を有効にすると、転送中のすべての npm tarball から
preinstall、install、postinstall、prepareフックが取り除かれる。npm マルウェアがインストール時に動く、いつもの経路だ。 - OSV、socket.dev、Depi は、既知のアドバイザリがあるバージョンや、マルウェアやタイポスクワットとしてフラグが立ったパッケージをブロックする。返すのは 451 で、その理由はパッケージマネージャーがそのまま表示する。
すべての取得は Security Timeline に記録されるので、インシデントの後でスティーラーを持ち込んだパッケージを突き止められる。
##スティーラーが Mac 上で動いた場合
Aoki のファイルリストは、スティーラーが Mac そのものの上で何を見つけるかも示している。Bromure をインストールしても、そこに加わるものはない。Bromure は Mac の Claude CLI や Codex CLI のサインイン情報を取り込まないし、必要ともしない。エージェントは VM で動き、そのサインイン情報は保管庫にある。~/Library/Application Support/BromureAC/ 以下で秘密を含むものはすべて AES-GCM の暗号文だ。マスターキーは Data Protection Keychain にあり、Bromure の署名 ID に紐づけられ、同期されることはない。フォルダをコピーしたスティーラーが手にするのは暗号化された blob だ。
Symantec が Cursor のローカルデータベースを名指しするのは、チャットのコンテキストとコードをキャッシュするからだ。エージェントの行動を記録する Bromure のセッショントレースは、同じ保管庫のキーで保存時に暗号化され、トークンの差し替えは最初と最後の文字だけのプレビューとして記録される。暗号化されていてもいなくても、本物の秘密がトレースに現れることはない。
リストのファイルはすべて代用値
.claude.json、Codex の auth.json と config.toml、取り込んだ .env の値、git の認証情報、AWS の設定には、どれも代用値が入っている。リフレッシュトークンと SSH 秘密鍵が VM に入ることはない。
アップロードでマシンが止まる
プロキシは発行先ではないホストへ向かう代用値を見つけると、451 を返して VM を一時停止し、漏れた認証情報を一つずつ名指しする。
ローテーション不要
Wipe and Launch はディスクとホームを入れ替え、キーは残す。スティーラーが持ち去ったのは、Mac のプロキシを通らなければ機能しない値だ。
入り口は見張られている
公開日数ゲート、インストールスクリプトの除去、レピュテーションチェックが、パッケージが VM に届く前に Mac 上で働き、すべての取得が記録される。
リストは伸びていく
Symantec によれば、Aoki の機能は「いまも活発に開発が続いているように見える」。ほかのスティーラーもこのリストを真似るだろう。Aoki がエージェントのファイルを加えたのは、盗んだエージェントのキーとサインイン情報が売れるからだ。エージェントを Bromure マシンで動かせば、買い手が手にするのは、Mac のプロキシの外ではどのサーバーも受け付けない代用値の束だけだ。
同じ問題の日常版、つまりエージェント自身が秘密をトランスクリプトにコピーしてしまう話は トークンはトランスクリプトに残った を読んでほしい。侵害された npm パッケージから同じファイルを狙ったワームについては トークンの失効が引き金だった を参照。