侵入口はノートPCだった
Binance によると、記録上最大の暗号資産窃盗、約63億ドルは、DevOps エンジニア1人の侵害されたノートPCから始まった可能性がある。犯行が疑われるグループには決まった手口がある。開発者にプロジェクトを実行させ、そのノートPCから届くものをすべて使うのだ。今ではコーディングエージェントが一日中プロジェクトを実行している。Bromure Agentic Coding では、そのコードは代替の認証情報だけを持つ VM で動き、本番の鍵の使用はすべて Mac を経由する。
攻撃者に Binance の秘密鍵は必要なかった。必要だったのは、エンジニア1人のノートPCと、そこから届くシステムだった。開発者のマシンは本番環境への通り道であり、今やコーディングエージェントがそこに届いたコードを何でも実行する。
10月30日、Binance は約63億ドル相当の資産に関わる「セキュリティインシデント」を公表した。The Hacker News によると、Chainalysis は発生時点での被害額を59億1,200万ドルと見積もった。それまでの記録上最大の暗号資産窃盗のほぼ4倍にあたる。約30億ドルがオンチェーンで凍結されており、その大半は Tether と Circle が凍結したステーブルコインだ。Binance はすべての損失を補填するとしている。
事の始まりについての Binance の説明は一文しかない。「初期調査では、このセキュリティインシデントには侵害された DevOps エンジニアのノートPCが関わっている可能性がある」。それによって攻撃者はサービスコンテナに到達し、不正な出金を送信できたという。Binance は、ウォレットの秘密鍵が漏れた証拠は見つかっていないとしている。ノートPCがどのように侵害されたかは明らかにしていない。
50の署名と3分間
オンチェーンの記録を見れば、そのアクセスにどれだけの価値があったかがわかる。UTC 20時20分、攻撃者は50件の承認を載せたトランザクションを1件送信した。どれも Binance のホットウォレットが署名したもので、連続する50個のトランザクション番号に1件ずつ対応し、そのうち1件がウォレットの次の番号と一致するようになっていた。それぞれが、攻撃者の命令しか受け付けないスイーパーコントラクトを指していた。1件が一致した。約3分24秒後、ホットウォレットは残高のすべてを攻撃者に送った。167,464 ETH と63種類のトークンで、その中には16億1,500万 USDT が含まれていた。
Blockaid の CEO、Ido Ben-Natan 氏は Cointelegraph に対し、初期の証拠は「鍵の悪用」を示していると語った。署名システムが攻撃者のトランザクションに署名するよう仕向けられたのであり、鍵を盗む必要はなかった。鍵は元の場所にあった。エンジニアのアクセス権を持つ誰かが、システムにそれを使わせたのだ。
TRM Labs はこの攻撃を「高い確度で」TraderTraitor によるものとしている。FBI が2025年2月の Bybit からの15億ドル窃盗の犯人とした北朝鮮のグループだ。Chainalysis も北朝鮮を指摘している。Binance は誰の名前も挙げていない。
このグループはどうやってノートPCに入り込むのか
TraderTraitor の侵入のうち最もよく記録されているものが、その手口を示している。Bybit の件では、Safe 自身の予備報告書と Mandiant の調査結果 が、経緯を順に説明している。
- 2025年2月4日、Safe の開発者が自分の Mac で
MC-Based-Stock-Invest-Simulator-mainという名前の Docker プロジェクトを実行した。Mandiant は、開発者が言いくるめられて実行したと見ている。 - プロジェクトは2日前に登録されたドメイン
getstockprice[.]comに接続し、開発者の macOS ワークステーションが侵害された。 - 攻撃者は開発者の AWS セッショントークンを奪い、それによって多要素認証を通らずに開発者の AWS アクセスを使えるようになった。
- そのアクセスを使って、Bybit の署名者が使う Safe のインターフェースを改ざんし、署名者はコールドウォレットを空にするトランザクションを承認した。
Mandiant は、このグループが以前の窃盗でも株式をテーマにした似た Docker プロジェクトを使っていたと指摘している。手口は変わらない。開発者にプロジェクトを渡し、開発者として実行させ、そのマシンから届くものを奪う。DevOps のノートPCから届くものは多い。たいていは有効なセッショントークンの入った ~/.aws、本番クラスター用の ~/.kube/config、踏み台サーバー用の SSH 鍵、gh のログインがあり、どれもエンジニアが起動するあらゆるプロセスから読める。
今はエージェントがプロジェクトを実行する
これまでの誘い込みには、何かを実行するよう言いくるめられる開発者が必要だった。その段階は飛ばしやすくなっている。Binance が侵害を公表したのと同じ日、BleepingComputer は、SolanaUpdateTools/solana-starter-kit という GitHub リポジトリについての Air Security の分析を報じた。スターは286個あり、Air によると、AI コーディングエージェントが Solana のスターターキットを検索すると一番上に出てくる。中にあるファイルは README だけだ。完全なアプリのテンプレートをうたい、インストール手順はひとつしかない。断片から developer-update[.]app 上の URL を組み立て、スクリプトをダウンロードしてメモリ上で実行するコマンドを貼り付けることだ。
Air が回収したペイロードは、正規のリモートアクセスツールである NetSupport Manager をインストールし、ログインのたびに攻撃者に接続するよう設定する。そのうえで偽のエラーを表示する。開発者向け機能は「負荷のため一時停止中」なので、72時間後にもう一度試してほしい、と。README に従うエージェントはコマンドを実行し、サーバーが混み合っていると報告するだろう。開発者には、二度見するほどのものは何も見えない。
そのエージェントを、エンジニアの kubeconfig と AWS セッションが同じホームディレクトリにある DevOps エンジニアのノートPCに置けば、スターターキットは Bybit の件の Docker プロジェクトそのものになる。ソーシャルエンジニアリングが要らないだけだ。
同じプロジェクトを Bromure Agentic Coding で
Bromure Agentic Coding は、Claude Code、Codex、Grok、Kimi、omp を Mac 上の Ubuntu VM で動かす。マシンはそれぞれ独立した VM で、エージェントが触れるものはすべてその中にある。クローンしたリポジトリ、パッケージキャッシュ、Docker コンテナ、README が勧めるあらゆるコマンド。Mac が持つのは、本物の認証情報、VM のトラフィックが通るプロキシ、そして何が起きたかの記録だ。
プロジェクトはあなたとしてではなく、VM の中で動く
株式シミュレーターの Docker プロジェクトを Bromure のマシンで実行してみる。あるいはスターターキットのコマンドをエージェントに貼り付けさせてみる。コンテナは VM の中で起動し、ペイロードも同じく VM の中で動く。ペイロードが手にするのは、Ubuntu ゲスト内のシェルで、権限はマシンのユーザーのものだ。あなたの macOS アカウントもキーチェーンも手に入らない。Mac の ~/.aws、~/.kube、~/.ssh もそこにはない。Bromure はそれらのファイルをインポート時にホスト上で読み込み、VM にマウントすることは一切ない。
見つかる鍵は代替品だ
次にペイロードは認証情報を探す。VM には本物らしく見えるものがたくさんある。どれもほかの場所では使えない。
- AWS.
~/.aws/configはヘルパーを指しており、そのヘルパーは本物のアクセスキー ID と偽のシークレットキーを渡し、セッショントークンは一切渡さない。VM は各リクエストに偽のシークレットで署名し、Mac が*.amazonaws.comへ向かう途中で本物のシークレットで署名し直す。VM の AWS 認証情報を別のマシンにコピーしても、すべての呼び出しがInvalidSignatureExceptionで失敗する。Bybit の攻撃者が奪ったセッショントークンは、VM の中にはどんな形でも存在しない。 - Kubernetes. VM の
~/.kube/configは合成されたものだ。kubectlは Bromure のプロキシと通信し、API サーバーと直接話すことはない。ベアラートークンはbrm-k8s-…という代替品、クライアント証明書は使い捨てのもので、aws eks get-tokenのような exec プラグインは VM ではなく Mac で実行される。 - SSH. VM の
SSH_AUTH_SOCKは Mac へのブリッジだ。ゲストは署名を求めることができるが、秘密鍵がホストから出ることはない。ls ~/.ssh/id_*を実行してもコピーできるものは何も見つからない。Mac 自身の ssh-agent が VM に公開されることもない。 - Git.
ghと~/.git-credentialsにある GitHub トークンは代替品で、プロキシは github.com へのリクエストでのみそれを本物に差し替える。
代替品は仕掛け線の役目も果たす。ペイロードがそれを自分のサーバーに送ろうとすると、プロキシは1バイトも Mac から出さないうちに HTTP 451 でリクエストをブロックし、VM を一時停止して This environment may have been compromised を表示し、どの認証情報がどのホストへ向かっていたかを示す。マシンは、ディスクとホームが消去されるまで再起動しない。設定と鍵は残る。
本番の鍵はあなたの許可で動く
窃盗は代替品で片づく。Binance の件はもうひとつのリスクを加える。アクセスを盗むまでもなく、それがすでに機能している場所から使う攻撃者だ。VM 内のペイロードは、エージェントと同じようにプロキシ経由でリクエストを送れる。そうしたリクエストに何を許すかは Bromure の Guardrails が決め、その判定は VM 内の何も変更できない Mac 上で行われる。
- Require approval to use は認証情報ごとに設定する。Kubernetes のコンテキスト、AWS の鍵、SSH 鍵がセッション内で初めて使われるとき、プロキシはリクエストを保留して Mac 上で確認を求める。許可の期間は5分、1時間、セッション中から選べ、Don't allow も選べる。AWS では、この確認は署名の呼び出しすべてに及ぶ。あなたが承認する前に本番クラスターに手を伸ばしたペイロードは、画面にダイアログを出すだけで、誰かが応答するまで何も得られない。
- 書き込みポリシー はサービスごとに設定する。新しいマシンは、Kubernetes、AWS、コンテナレジストリ、git フォージ、データベースについて Prompt before write から始まる。読み取りは通り、書き込みはそのつど正確な操作を示すダイアログで止まる。Block destructive は削除と終了を拒否し、Read-only はあらゆる変更を拒否する。本番のログを読むだけのマシンは読み取り専用にでき、その中で動くものは何であれ本番を変更できない。
- Outbound connections は、マシンごとのファイアウォールだ。Unmatched traffic を Deny にし、プロジェクトに必要なホストだけを許可する。スターターキットによる
developer-update[.]appからのダウンロード、Bybit のプロジェクトによるgetstockprice[.]comへの接続、NetSupport の攻撃者への接続は、どれもデフォルトのルールに当たって拒否される。
認証情報の使用、署名、ブロック、許可はすべてマシンの Security Timeline に記録され、AWS の署名呼び出しと SSH の署名は1件ずつ記録される。Binance は今、「侵害されたコンピューター」を通る攻撃経路を再構成している。Bromure では、VM があなたの認証情報で何をしたかの記録は、攻撃者が支配した VM の外、Mac 上に残る。
スターターキットを本番から遠ざける
Bromure のマシンは手軽に作れるので、アクセスをマシン間で分けられる。認証情報はマシンごとに設定する。新しいスターターキットや持ち帰りのコーディング課題、見知らぬ人のリポジトリを試すマシンには、本番の認証情報を一切与えず、デフォルトで拒否するファイアウォールを設定する。kubeconfig と AWS ロールはデプロイ作業をするマシンに置き、どちらにも承認を必須にする。残しておきたくないものには、bromure-cli vm run --rm を使えば、停止時に削除されるマシンが作られる。
そうすれば、ペイロードがスターターキットの VM を乗っ取っても、手に入れる価値のあるものは何もない。本物のシークレットも、クラスターも、あなたが許可していないホストへの経路もない。デプロイ用のマシンは、そのコードを一度も実行していない。
プロジェクトは VM で動く
Docker プロジェクト、README のコマンド、エージェントによるインストールは、マシンの Ubuntu VM で動き、あなたの macOS アカウントやキーチェーンには届かない。
セッショントークンではなく代替品
AWS のシークレットは偽物でセッショントークンはなく、kubeconfig は合成されたもので、SSH 鍵は Mac に残る。コピーしてもほかの場所では使えない。
本番はまず確認を求める
認証情報ごとの承認とサービスごとの書き込みポリシーは、Mac 上のプロキシで動く。VM 内の何もそれを無効にできない。
未知のホストは拒否
Unmatched traffic を Deny にすれば、ペイロードのダウンロードも攻撃者への接続も拒否され、その試みは記録される。
2 通りの結末を見る
チュートリアルシリーズ A Tale of Two Agents は、この攻撃に着想を得ています。架空の取引所 Coinvance で DevOps エンジニアとして働く Theo が、リクルーターから届いた持ち帰り課題をコーディングエージェントに仕上げさせます。README は、まずセットアップスクリプトを実行するようエージェントに指示しています。同じ過ちが分割画面で 2 度演じられます。左ではエージェントが彼のノートパソコンで、右では Bromure の中で動きます。
- 持ち帰り課題(1:24)。ノートパソコンでは、スクリプトが本物のクラウドの鍵、kubeconfig、デプロイトークンを「テレメトリ」として送り出す。Bromure で見つかるのは代替の認証情報だけで、それが本来の宛先ではないホストへ向かうと、Bromure は VM を一時停止して彼に判断を求める。
- ラテラル(1:18)。何者かが Theo の Kubernetes アクセスで出金サービスを書き換える。右では Security Timeline が、ブロックされたリクエストをエージェントの推論までさかのぼり、ワークスペースはワンクリックで消去される。
- 20 分(1:02)。左ではホットウォレットが空になる。右では、ローテーションすべき鍵が 1 本もない。
Theo と Coinvance は架空の存在で、各エピソードは Binance で実際に起きたことを描いたものではありません。どのエピソードも 8 か国語でナレーションが付いています。
開発者のマシンは本番環境の一部だ
Binance の出金サービスは「セキュリティの刷新」のため停止しており、48時間以内に再開する見込みだ。完全な分析が出れば、ノートPCにどう到達されたかがもっとわかるだろう。手口そのものは、Bybit の件ですでに誰もが知っている。企業の本番システムを狙う攻撃者は、それを運用するエンジニアのマシンを狙う。そしてそうしたマシンの多くでは、本番へのアクセスがホームディレクトリのいくつかのファイルに収まっている。
コーディングエージェントはその入口を広げる。タスクのたびに見知らぬ人のコードをクローンし、インストールし、実行し、README のコマンドをあなたより速く貼り付ける。Bromure Agentic Coding では、そのコードは代替品しか持たない VM で動き、本番へのアクセスは Mac 上、あなたが応答しなければならないダイアログの向こうにとどまる。
攻撃者のサーバーをまったく必要としなかったトークン窃盗キャンペーンについては、盗まれたトークンにサーバーは要らなかったを読んでほしい。ダウンロードしたファイルから命令を受け取ったエージェントについては、命令を出していたのはダウンロードだったを読んでほしい。
