すべての投稿に戻る
公開日 · 著者 Renaud Deraison

そのコマンドは npm install で始まっていた

2026 年 8 月 24 日、Cato Networks の CTRL チームが公開したキャンペーンは、「codex macos download」というクエリにスポンサー付きの Google 検索結果を買い、開発者を OpenAI の Codex ポータルを装った Google Sites のページへ誘導し、一行目が Codex の本物の npm install であるターミナルコマンドを貼り付けさせる。その行より後はすべて base64 だ。Bromure Agentic Coding は、コーディングエージェントを探しに行かせることがない。インストールコマンドは Bromure 自身のイメージカタログに書かれた固定文字列であり、使い捨ての Linux VM の中で走り、そこにある資格情報は囮であり、未一致の外向き通信を拒否しておけばローダーの三回の取得はマシンから出ていかない。

この二年間、業界はコーディングエージェントが何をインストールするかに対する 制御を築いてきた。このキャンペーンはその一歩手前に回り込み、コーディング エージェントをどうインストールするかを汚染する。その段階にはレジストリも ロックファイルも来歴の証明もない。あるのは検索ボックスと、正しく見える ページと、キーボードに置かれたあなた自身の手だけだ。

ある開発者が Mac で OpenAI の Codex CLI を試したくなり、Google に codex macos download と打ち込む。最初の結果はスポンサー付きで、OpenAI 自身の 掲載よりも上にある。それは正しいロゴと正しいタイポグラフィを備えた、清潔な ダウンロードポータルへ通じている。ホストは sites.google.com だ。ページには こうある。ターミナルを開いて、これを貼り付けてください。

彼は貼り付ける。コマンドは npm install で始まり、パッケージ名も正しい。

8 月 24 日、Cato Networks の研究チーム CTRL が そのキャンペーンの分析 を公開し、同日中に Infosecurity MagazineSiliconANGLETechzine が取り上げた。最終ペイロードは macOS 向けの情報窃取マルウェアだ。分析に値する のは配送のほうである。

ページをホストしたのは Google。餌をホストしたのは別の誰か。

Google Sites はサイトビルダーだ。アカウントさえあれば誰でも Google ドメイン上に ページを持てるし、証明書も鍵アイコンも URL の前半も、すべて Google のものだ。 それが借り物の信頼である。

ページそのものには何もない。Cato はそこに悪意あるコードをひとつも見つけなかった。 餌は攻撃者インフラを指す iframe で届き、Cato の分析によればそれは Google の 静的コンテンツプロキシを経由するため、二段目のホップさえ Google が何かを取りに 行っているように見える。Techzine は iframe のホストのうち二つ、 bright-links[.]comswiftsaverfin[.]com を挙げている。

この分離は運用者に二つのものをもたらす。目に見えるページは決して変わらないので、 評価システムに引っかかることも再審査されることもない。そして彼らは iframe の 向こう側でペイロードを好きなときに差し替える。Cato は三つの独立したインフラ 一式を数え、三つ目は一つ目の iframe ホストを再利用していた。

残りは成熟した広告詐欺の運用そのものだ。生きた餌は難読化されたパス /codexx/ の 下にあり、/codex/ は無害なものを配る。運用者は訪問者をフィンガープリントし、 もっともらしい macOS の標的でないものには良性のコンテンツを見せる。それが研究者と サンドボックスへの彼らの答えだ。ドメインは巡回する。ペイロードの URL も変わる。

一行目は本物だった

ClickFix はファイルを配らない。指示を渡し、境界の向こうへペイロードを運ぶ 仕事をあなた自身にさせる。Techzine の言い方を借りれば、「アンチウイルス製品が ブロックできるようなファイルは、一つもダウンロードされない」。

貼り付けるコマンドは、Codex 用の一見まっとうな npm install 文字列で始まる。 仕掛けはそれで全部だ。Node の CLI をこれからインストールしようとしている開発者は npm install を見て、自分が検索したパッケージ名を見て、脳がその行を正しい ものとして片づける。続く base64 のブロブはシェル演算子ひとつ隔てた先、同じ行の 上、コピーボックスの折り返しの向こうにある。前半が期待どおりのコマンドである とき、人はそのコマンドの後半を読まない。

デコードするとリモートのスクリプトを取得し、zsh に流し込む。以下、三段階が 続く。

第一段階は、死んだコードと未使用の変数で水増しされたシェルスクリプトで、 最後に eval へ渡されるエンコード済みのブロブを包んでいる。水増しはパターン マッチを破るため、そしてファイルを流し読みする人間に諦めさせるために存在する。

第二段階は、ほかの何をするよりも先に event=pasted というパラメータを付けて 攻撃者へビーコンを返す。これは配達受領証だ。向こう側の誰かが、マーケターが コンバージョンを測るのと同じやり方で、ランディングページの貼り付け率を測って いる。

第三段階はバイナリを /tmp/helper にダウンロードし、xattr -c を実行して macOS がネットワーク由来のものすべてに付ける検疫属性を剥がし——これが Gatekeeper の警告を黙らせる——実行可能にして起動する。バイナリはユニバーサル Mach-O なので、 Intel でも Apple Silicon でも動く。

Cato は、運用者がまだローダーを開発中だと指摘している。古い検体は圧縮付きの base64 を使っていたが、新しいものはスクリプト中に散らばった変数から鍵を組み立てる AES 暗号化 gzip コンテナを使う。

最終ペイロードについて、Cato はこの配送フレームワークを Atomic macOS Stealer に結びつける。ローダー URL の構造、テレメトリ要求の形、/tmp/helper という ステージングパス、xattr の除去、アップデートを装ったペイロード URL。彼らは その重なりを強く一貫していると呼び、バイナリの名指しは控えている。それは正しい 判断であり、この話を再び語るときにも保つ価値がある。

配送:被害者が見るすべてcodex macos downloadスポンサー付きの結果、OpenAI 公式より上にsites.google.comCodex ポータルの偽物、独自の悪意あるコードなしiframe:本当の餌bright-links[.]comswiftsaverfin[.]com「ターミナルでこれを貼れ」DL なし開発者が読む唯一の行npm install ... codex ...; base64 -d ... | zsh実行:三段階、三回の外向き取得1 · ローダー死んだコードと未使用変数で水増しされたシェルスクリプトeval "$blob"2 · 受領証テレメトリのビーコン?event=pasted運用者のコンバージョン指標3 · ペイロード/tmp/helperxattr -c ; chmod +xユニバーサル Mach-O
検索ボックスから実行中のバイナリまでの連鎖。そのどこにもエクスプロイトはない。スポンサー広告、何も含まない Google ホストのページ、すべてを含む iframe、そして貼り付けによって自ら境界の向こうへペイロードを運ぶ人間。被害者が目にする唯一のコマンドは Codex 用の本物の npm install 行で始まり、続く base64 が第一段階を取りに行く。第二段階の event=pasted ビーコンは、運用者自身の配達受領証である。

スキャナーより一段上流の工程

業界がこの二年、コーディングエージェントのために築いてきた制御を並べてみよう。 レジストリの評判スキャン。ロックファイルと完全性ハッシュ。ビルドの来歴と証明。 SBOM。新しいパッケージバージョンに対する最低経過日数のゲート。生成コードの静的 解析。どれも機能するし、どれも同じ前提から出発している。開発者はすでに動作する ツールチェーンを持っており、リスクはその先、それで何をするかの側にある、と。

このキャンペーンはそのすべてより上流に座っている。ここでの偽物はエージェント そのものであり、それはどのレジストリより前に、どのロックファイルより前に、 開発者が自分の手で自分のターミナルに打ち込むコマンドとして届く。スキャナーには 採点すべき成果物がない。成果物はウェブページ上の一文なのだから。

ターゲティングは経済のもう半分だ。codex macos download に入札する者は、まさに その瞬間コーディングエージェントを構築中の人物のマシンを買っている。一時間以内に API トークン、SSH 鍵、~/.aws/credentials ファイル、GitHub の PAT を抱えることに なるマシン、しかもそのどれもが情報窃取マルウェアの探し方を知っているものだ。 インストールの瞬間は、そこに居るのに最も安い時間である。

その逆側は以前に扱った。 FakeGit と AgentBaiting では、エージェント が検索し、人間にインストール手順を手渡した。ここでは人間が検索する。どちらも 成立するのは、発見してから貼り付けるという流れがソフトウェアのインストールその ものであり、その輪のどちらの端にもスキャナーが座っていないからだ。

インストールコマンドはどこから来るのか

Bromure Agentic Coding にはそんな輪がない。理由は、エージェント がどこから来るかにある。

あなたはコーディングエージェントを探しに行かない。Codex はプロファイルの Agents パネルにあるトグルで、Claude Code や Grok Build の隣に並んでいる。 オンにして、認証方法を選べば、次のセッションではもうエージェントがそこにいて、 プロファイルの VM 内の kitty タブで動いている。

そのトグルの裏にあるのは固定文字列だ。Bromure は自身のカタログからベースイメージ をプロビジョニングし、Codex の項目は一行である。

npx --yes @socketsecurity/cli npm install -g --silent @openai/codex

Claude Code は同じ型で @anthropic-ai/claude-code、Kimi Code は @moonshot-ai/kimi-code。パッケージ名はアプリにコンパイル済みで、発見されるもの ではない。レジストリは registry.npmjs.org であって、iframe が指名する任意の ホストではない。インストールは socket.dev の CLI でラップされ、取得はホストの MITM プロキシを通って外へ出る。そこでプロファイルの Supply Chain ポリシーが 効く。既定で有効な二日間の経過日数ゲートに加えて、OSV の照会、socket.dev または Delpi によるフィルタリング、そして有効化できるインストールスクリプトの除去だ。

その経路には検索結果もなければ、なりすます対象のページもない。攻撃者が金を払って 汚染したチャネルが、ワークフローから丸ごと欠けている。そして欠けていることは、 操作を忘れる心配のある制御ではない。

普通のやり方でインストールする誰が成果物を名づけるか広告オークションの落札者誰が配信するかそっくりページ上の iframe何が動くか最初の行より後にあるすべてどこであなたの Mac、あなたのアカウント、隣は~/.ssh · ~/.aws · ~/.git-credentialsGatekeeper は xattr -c で黙る四つの未解決の問い、答えるのは見知らぬ他人。Bromure プロファイルで有効にする誰が成果物を名づけるか@openai/codex、イメージカタログから誰が配信するかregistry.npmjs.org、ホストプロキシ経由何が動くか組み込み済みのコマンド一つ、自由入力なしどこで使い捨ての Linux VM、検索より前に構築済み — 鍵は中にない、資格情報は囮、外向き通信は監視下同じ四つの問い、訊く前に答えが出ている。
コーディングエージェントを手に入れる二つの道。左では、取得の工程は検索ボックスとコピーボタンだ。成果物の名前も、それを配るホストも、それをインストールするコマンドも、すべて広告オークションの落札者が決め、その結果は開発者の鍵を抱えた Mac の上で走る。右では、成果物名はアプリにコンパイルされ、レジストリは固定され、取得はホストプロキシで濾され、インストールはこれが始まるより前に構築された使い捨ての VM の中で走る。

それでも貼り付けてみる

アーキテクチャは、誰かがそれを無視する日を生き延びなければならない。このキャン ペーンを取り上げ、勝たせてやり、プロファイルの中を歩かせてみよう。誰かが偽の ポータルを見つけ、コマンドをコピーし、自分がエージェント作業に使っている端末—— Bromure Agentic Coding では VM 内の kitty タブ——に貼り付ける。

バイナリは動かない。 ユニバーサル Mach-O は macOS の実行ファイルだ。ゲストは Ubuntu である。xattr は Linux のコマンドではないし、/tmp/helper は捨てられる ために存在するシステムディスク上のパスだ。Resources → Storage には /home/ubuntu 用の Erase home… と、共有の読み取り専用ベースイメージから ワークスペースのシステムディスクを再クローンする Reset to base… がある。

三回の取得は外へ出ない。 この連鎖の各段階はどれもネットワークを必要とする。 第一段階を引っぱる base64 デコード済みの URL、event=pasted のビーコン、そして ペイロードのダウンロード。Guardrails → Outbound connections は pf 風のルール テーブルだ。アクション、プロトコル(tcpudpwebany)、ホストまたは CIDR、ポート、そして web なら HTTP メソッドのリスト。上から下へ照合し、最初に 一致したものが勝つ。Unmatched traffic は Allow か Deny に設定する。Deny にして、 自分の作業が必要とするホストを並べればよい。bright-links.com はその一つでは ない。Bromure はこのテーブルを仮想スイッチとプロキシの中、ホスト側で強制するので、 ゲストが自分の環境に何をしようと答えは変わらない。

腰を据えて眺める価値があるのは第二段階だ。event=pasted は運用者のコンバー ジョン指標であり、ランディングページが機能していること、そしてどの程度機能して いるかを彼らに告げる ping である。その要求がホストで死ぬとき、彼らのもとに届くの は感染失敗の報告ではない。届くのは沈黙で、それはコンバージョンしなかった広告 インプレッションのように読める。

盗み出しても返るのはプレースホルダーだ。 Atomic 級の窃取マルウェアが狙うのは ブラウザのデータ、ウォレット、そして開発マシンなら資格情報である。Bromure の プロファイルでは、本物の値がそもそも VM に入らない。汎用 API キーは環境変数として エクスポートされた brm_… の偽物で、ホストのプロキシが通信路上で差し替える。 kubeconfig は合成物で、使い捨てのクライアント証明書が付く。AWS の要求はホスト側で 再署名されるので、プロキシを迂回したものはすべて InvalidSignatureException を 受け取る。~/.docker/config.json には偽の base64 ブロブが入っている。SSH の秘密鍵 はそこに読み出せる形で存在しない。 最初からなかったのだ。資格情報ごとに Require approval to use を有効にすれば、差し替えのたびにホスト側のダイアログが 出て、時間で区切られた許可を与えることになる。五分、一時間、セッションの残り。 プロファイルが共有するのはあなたが選んだ最大八つのフォルダだけなので、Mac の残り はディレクトリを辿った先にはない。

相関はもうあなたの画面の上にある。 Cato 自身の結論は、このキャンペーンはどの 単一段階を見ても露見しない、というものだ。検出には、スポンサー検索による配送、 埋め込まれたウェブコンテンツ、ターミナルでの実行、そして外向きの活動を、まとめて 相関させる必要があった。証跡がブラウザとシェルとネットワークタップに分かれている とき、それは難しい問題だ。プロファイルの中ならそれは一枚のウィンドウで済む。 Security Log(Window → Security Log…)は、パッケージの判定、ファイア ウォールの決定、資格情報の差し替え、プロンプトインジェクションの検出を、ホスト側 で時系列にまとめた単一のテーブルである。ゲストのコードはそれを編集できない。 ゲストのコードはそこへ届かないからだ。

有効にする

経過日数ゲートは既定で二日に設定されている。ほかの層は設定であり、二分をかける 価値がある。Guardrails → Outbound connectionsUnmatched traffic を Deny にし、自分の作業が必要とするホストの許可リストを置く。Supply Chain → OSV vulnerability check、鍵があるなら socket.dev または Delpi によるフィルタリング、 そしてインストールスクリプトの除去。Credentials → 金を使えるもの、データを 消せるものすべてに Require approval to use。あとは Security Log のウィンドウを 一週間、二枚目のディスプレイに開いたままにして、自分のビルドが何と話している のかを見ればいい。

スポンサー付きの検索結果はこれからも玄関であり続けるし、信頼されたドメイン上の サイトビルダーはこれからもポーチを貸し続ける。Google がこれらのページを落とせば 三つ新しく立つ。経済がクリック数ドル対クラウド資格情報入りの開発ワークステーション だからだ。Bromure Agentic Coding をインストールし、 ダウンロードページではなくプロファイルエディタからエージェントを有効にして、次に 貼り付けられるコマンドを、捨てるために造られたマシンの中へ着地させよう。