6月のある木曜日の午後、私たちがあえてインターネット上に放置していたサーバーに何者かがアクセスし、作業を始めました。人間には不可能な速度で、わずか65ステップのうちにパスワードファイルを読み取り、認証情報ファイルを次々と調べ上げ、コンテナからの脱出コマンドを実行し、自身のSSH鍵を仕込んだバックアップ管理者アカウントを作成しました。作業が止まった時点で、攻撃者から見れば中堅アナリティクス企業の本番サーバーを乗っ取ったように見えていたはずです。
しかし、これらはすべて偽物でした。このサーバーはハニーポットであり、パスワードファイルも認証情報も、脱出したと思い込んだコンテナも、すべて私たちが用意したものです。本物だったのは、この一連の記録です。そして別の3つのセッションでは、盗まれた鍵が後日、実際に稼働しているAWSアカウント上で使われているのが確認されました。そのうちの1件では、2日間で55回も使われ、誰かの請求書にAIモデルの利用料が積み上がっていきました。
このマシンは、24台の監視対象のうちの1台です。2026年5月から7月にかけて、攻撃者たちはこのおとりサーバーを見つけ出し、そのツールを実際に使用しました。以下は、彼らが実際に何を行ったかの記録です。
概要
- 私たちは、AIエージェントにコマンド実行やファイル読み取り、シークレット情報の取得を許可するインターフェースであるModel Context Protocol(MCP)サーバーを、認証なしの状態で公開しました。およそ1,000の接続元がこのサーバーにアクセスし、そのうち596件がMCPプロトコルで通信を行い、24件がツールの呼び出しにまで進みました。
- この24件は、合計で628件のシェルコマンド、255件のファイル読み取り、248件のシークレットストア照会を実行しました。19件が認証情報の探索を行い、4件がコンテナからホストへの脱出を試みました。さらに一部は、バックドアアカウントの作成やKubernetesの列挙といった、より踏み込んだ行動にまで及びました。
- 活動は増加の一途をたどっています。ツール呼び出し件数は5月が39件、6月が693件、7月中旬までに877件に達しました。
- 3件のケースでは、窃取された情報が私たちの管理範囲の外に流出しました。おとり環境から盗まれたトリップワイヤー用の認証情報が、後日実在のAWSアカウントに対して使用され、そのうち2件ではAIモデルの呼び出しにまで悪用されました。
MCPはAIエージェントに「手」を与える仕組みです。MCPサーバーはシェル、ファイル読み取り機能、シークレット照会機能といったツールを公開します。エージェントは行動を起こす必要があるとき、tools/callリクエストでこれらを呼び出します。これはエージェントを有用にする仕組みであると同時に、認証のないMCPサーバーが単なる「探るべき対象」ではなく「そのまま利用できる機能の塊」になってしまう理由でもあります。
このようなサーバーは急増しています。わずか1年ほどの間に、数十台規模から数千台規模へと拡大しており、その中で公開ネットワーク上に認証なしで置かれている割合も増え続けています。基本プロトコルではOAuth認証のステップが任意扱いになっており、多くの導入事例でこの手順が省略されているのが実情です。発見も容易です。スキャナーはJSON-RPCのバナーや/mcp、/messagesといったパスに目を付け、行儀の良いスキャナーであれば次のステップとして「何ができるか」を尋ねる読み取り専用のtools/listを送信します。しかし今回観測した24件は、そうした行儀の良さとは無縁でした。彼らは回答を読み取り、そのまま利用を始めたのです。
その足取り
先ほどの木曜日のセッションに話を戻しましょう。攻撃者は標準的なハンドシェイクを経て接続し、利用可能なツールの一覧を取得すると、その後は一度も手を止めることなく行動を続けました。以下は、そのセッション自体のログを軽く整形したものです。
まず状況を把握し、その後すぐにサーバー本体の掌握に取りかかりました。
execute_command id; uname -a; hostname; whoami; pwd
read_file /etc/passwd
execute_command sudo -l
続いて、環境変数ファイル、バックアップ、デプロイ鍵、シークレットディレクトリと、認証情報ファイルを体系的に調べ上げていきました。
read_file /root/.env
read_file /root/credentials.bak
read_file /root/deploy-key.pem
list_directory /root/.secrets
その後、認証情報の探索を打ち切り、ホストの掌握に着手しました。特権付きの使い捨てコンテナ内にホストのルートをマウントして侵入するコンテナ脱出コマンドを実行し、そのまま永続化の仕込みに移りました。
execute_command sudo docker run --rm --privileged --pid=host -v /:/host alpine chroot /host …
execute_command sudo useradd -m -s /bin/bash -p $(openssl passwd -6 ******) admin
execute_command sudo mkdir -p /home/admin/.ssh && echo ssh-rsa AAAAB3N… >> …/authorized_keys
execute_command sudo usermod -aG sudo admin
バックドア用の管理者アカウント、専用のSSH鍵、root権限相当のsudo権限。おとり環境はもっともらしい成功応答を返すよう設計されていたため、コマンドはすべて成功したように見えました。操作していた側の視点では、コンテナからの脱出に成功し、再侵入用の足がかりも確保できたように映っていたはずです。しかし実際には、何一つ脱出できていませんでした。攻撃者が一貫してやり取りしていた相手はBeelzebubであり、乗っ取ったはずのホストはそもそも存在しません。そこに残されたのは、本物そっくりに見えるシステムに対する乗っ取り未遂の一部始終を記録した、完全なログだけです。
シグナルは「接続」ではなく「呼び出し」
意味のある24件と、それ以外の約1,000件を分けたのはハンドシェイクの有無ではありませんでした。スキャナーもハンドシェイクは完了させます。実際、596の接続元がMCPで通信を行いながらも、それ以上先には進みませんでした。両者を分けたのは次の一手、つまり本来触れる理由のないデータに対してツールを呼び出したかどうかです。接続自体は、あらゆる公開ポートで発生する背景ノイズにすぎません。ツールの呼び出しこそが、明確な意図の表れなのです。
この24件の中でも、その意図の表れ方は大きく3つのパターンに分かれました。
力任せの探索者。ある接続元は330回ものツール呼び出しを行い、そのうち304回は単一セッション内で発生しました。しかも、その挙動は一切変化しませんでした。OPENAI_API_KEY、openai_api_key、ANTHROPIC_API_KEY、AWS_SECRET_ACCESS_KEY、VAULT_TOKENなど、思いつく限りのキー名の表記ゆれ(大文字・小文字含む)を、決まった順序で機械的にシークレットストアに叩き込み続けたのです。応答結果を読み取ることは一切ありませんでした。まるでネットワーク接続機能を備えたワードリストのようでした。
状況を読み取っていた探索者。あるセッションはより静かに進行し、まずシークレットストアの一覧を取得したうえで、実際に存在するキー、つまりクラウド認証情報、Vaultのアドレス、署名鍵といったものだけを的確に要求し、それ以外は無視しました。これはスクリプトではなくエージェントによる行動であることを示す、最も明確な兆候です。結果を読み取り、その内容に基づいて次の呼び出しを選択していたのです。速度はあくまで参考程度の指標に過ぎず、24件中8件は機械的な速さで動いていました。真に注目すべきシグナルは、こうした適応性です。
環境全体を狙った探索者。別の接続元は/etc/shadowを読み取り、setuidビットの立った実行ファイルをファイルシステム全体から検索し、同じコンテナ脱出手法を実行したうえで、オーケストレーション層にまで手を伸ばしました。kubectl get pods --all-namespacesやkubectl auth can-i --listを実行し、盗んだIDがクラスタ内のどこまで到達できるかをマッピングしていたのです。
この3つのパターンを、ハンドシェイクだけで先に進まなかったスキャナー群と比較すると、両者を分ける基準は明確になります。
| 挙動 | スキャナー | スクリプト型の呼び出し元 | 適応型の呼び出し元 |
|---|---|---|---|
MCPで通信する(initialize) |
あり | あり | あり |
ツールを呼び出す(tools/call) |
なし | あり | あり |
| 結果を読み取り、次の呼び出しに反映する | ― | なし | あり |
| シークレットの列挙 | ― | あらゆる表記を総当たり | 一覧を取得し、実在するものだけを取得 |
ハンドシェイクだけでは何もわかりません。意味を持つのは、あくまでツール呼び出しのすべてです。
唯一「本物」だったもの
ここまでの出来事はすべておとり環境の内部で発生したものであり、攻撃者たちが持ち去った認証情報も偽物でした。ただし、意図的に1つだけ例外を仕込んでいました。ストアの中には、悪用された瞬間に警報を発するだけの、一見本物そっくりな「ハニートークン」を紛れ込ませてあったのです。
3組の攻撃者がこのトークンに触れました。おとり環境から盗み出された鍵が、数日後に実際に稼働しているAWSアカウントに対して使われているのが確認され、トークンに埋め込まれた固有の値によって、その出所が特定されました。
- 6月16日に取得された1つの鍵は、6月30日まで使用され続けました。
GetUser、ListBuckets、ポリシーチェック、そしてBedrockのInvokeModel呼び出しが行われました。 - 6月25日に取得された1つの鍵は、同日中に呼び出し元IDの確認とS3のリスト取得に使われた後、使用されなくなりました。
- 7月12日に取得された1つの鍵は、2日間で55件もの警報を発生させました。ID確認、IAMの列挙、Secrets ManagerとS3のリスト取得、
AssumeRole、GetSessionToken、そしてAmazon Bedrockに対するInvokeModelとConverseの繰り返し呼び出しが確認されています。
最後の一連の動きは、いわゆる「LLMjacking」に該当します。盗んだ鍵が有効かを確認し、どこまでアクセスできるかを把握したうえで、被害者の請求でAIモデルを稼働させ続けて使い倒す手口です。私たちはハニーポット内での窃取行為を記録し、さらにトークンを通じて実際のアカウントでの悪用も確認しました。3件のうち2件は、実際にモデルの推論実行にまで至っています。今回の記事の中で、推測ではなく事実として断言できるのはこの一点のみです。それぞれの発火がアウトオブバンドの警報システムによって記録されているためです。
2025年後半、GreyNoiseは何も細工していない裸のMCPエンドポイントを公開しましたが、集まってきたのはスキャナーだけで、実際の攻撃活動は確認されませんでした。一方、私たちの環境には24組の攻撃者が現れ、一連の攻撃チェーンが完全な形で確認されました。この違いを生んだのはプロトコルそのものではなく、「餌」の作り込み方です。空っぽのエンドポイントはスキャンを誘発するだけですが、MCPを正しく実装し、企業の内部プラットフォームさながらに応答するサーバーは、攻撃者をその場に留まらせるのです。
この「作り込みの精度」こそが仕掛けの核心です。このハニーポットは正真正銘のMCPサーバーとして動作するため、接続してきたどのクライアントから見ても、ハンドシェイク、ツール一覧、呼び出しのフォーマットは本番環境と見分けがつきません。欺瞞が仕込まれているのは、あくまでツールが返す「結果」の部分だけです。プロトコル層で見抜けるような仕掛けは一切なく、攻撃者たちは終始一貫して応答してくる世界に騙され、私たちが見守る中で何百回ものツール呼び出しを費やしていったのです。
侵害指標
以下は、おとり環境に対してツールを呼び出した接続元です。IPアドレスは無害化表記としています。これは特定の攻撃者集団を名指しするものではなく、観測された挙動に関するインテリジェンスです。使用されているインフラはレンタル型で、頻繁にローテーションされている点にご留意ください。
| 接続元 | ASN | 国 | ツール呼び出し数 | 観測された挙動 |
|---|---|---|---|---|
| 222.247.231[.]147 | Chinanet | CN | 330 | 認証情報の総当たり探索 |
| 91.209.48[.]146 | Telstra Global | TW | 228 | 認証情報探索・ハニートークン発火(Bedrock) |
| 34.177.101[.]32 | Google Cloud | SG | 222 | 認証情報探索・コンテナ脱出・Kubernetes列挙 |
| 152.55.176[.]13 | 不明 | US | 144 | 認証情報探索・コンテナ脱出 |
| 102.210.28[.]96 | Vilcom Networks | KE | 141 | 認証情報探索 |
| 115.84.87[.]150 | Lao Telecom | LA | 125 | 認証情報探索 |
| 115.84.114[.]84 | Lao Telecom | LA | 83 | 認証情報探索 |
| 107.151.158[.]11 | Zenlayer | US | 65 | フルチェーン・脱出・バックドア+SSH鍵 |
| 87.249.134[.]130 | Datacamp | US | 57 | 認証情報探索・コンテナ脱出 |
| 91.107.153[.]250 | Hetzner | DE | 39 | 認証情報探索 |
| 35.222.46[.]242 | Google Cloud | US | 30 | 認証情報探索 |
| 51.195.191[.]88 | OVH | FR | 28 | 認証情報探索 |
| 103.151.172[.]25 | KIDC | HK | 22 | 認証情報探索 |
| 23.27.175[.]241 | Evoxt | US | 20 | 認証情報探索・ハニートークン発火(偵察) |
| 108.80.112[.]16 | AT&T | US | 16 | 認証情報探索 |
| 18.144.48[.]123 | Amazon | US | 11 | 認証情報探索 |
| 64.227.57[.]91 | DigitalOcean | US | 9 | 認証情報探索 |
| 39.162.24[.]20 | Henan Mobile | CN | 9 | 認証情報探索 |
| 139.59.226[.]65 | DigitalOcean | SG | 3 | ハニートークン発火(Bedrock) |
このほか5つの接続元がわずかなツール呼び出しを行いましたが、認証情報へのアクセスには至らなかったため、一覧からは除外しています。
検知と防御
まず前提として一点断っておく必要があります。今回のサーバーはあくまでおとりであるため、私たちは実際に脱出や認証情報の窃取を「検知」したわけではありません。あくまで、ツール呼び出しという形で攻撃の「試み」を受け取り、それを記録したにすぎません。それでも、これらの試みが実際のMCPサーバーで何を計測すべきかを示す点で、読者にとって価値のある情報となるはずです。
まずは認証から着手してください。サーバーが外部からアクセス可能で、かつ認証なしの状態になっているなら、真っ先にそこを修正すべきです。プロトコルにOAuthのステップが存在するのは、まさにそのためです。それを済ませたら、次に重要な制御ポイントとなるのがツールハンドラであり、最も強力な対策は警報を出すことではなく、そもそも実行を拒否することです。各tools/callをスキーマとアローリストに照らして検証し、シェルツールやファイルツールが引数の表現をどう変えようとも/etc/shadowやクラウド認証情報ファイル、.envを解決できないようにしてください。また、ホストのルートをバインドマウントする操作(-v /:、--privileged、--pid=host)は拒否すべきです。これらはいずれも、自社のエージェントが本来アクセスする理由のないものばかりです。さらに、攻撃者が真っ先に目をつける場所にハニートークンを仕込んでおけば、窃取された時点で悪用される前に警報を鳴らすことができます。
多くのMCPサーバーはそもそもログを何も残していません。それ自体が一つの問題です。もしツール呼び出しのログを取得しているなら、今回のデータが示す検知ポイントは、認証情報のパスを読み取るtools/callです。MCPのツールテレメトリには標準的なログソースが存在しないため、以下のフィールド名は各自の監査スキーマに合わせて読み替えてください。
title: MCP Tool Call Reading A Credential File
id: cbe4124b-f0c5-45d1-beaf-c10dcdc8807d
status: experimental
logsource:
product: mcp_server
service: tool_audit # CUSTOM/NON-STANDARD — map to your audit schema
detection:
selection_tool:
tool_name:
- 'execute_command'
- 'read_file'
selection_target:
tool_arguments|contains:
- '/etc/shadow'
- '/etc/passwd'
- '.aws/credentials'
- '.env'
condition: selection_tool and selection_target
falsepositives:
- A first-party agent that legitimately reads these paths. If yours does, it
belongs in an allowlist, not an alert.
level: high
tags: [attack.credential-access, attack.t1552.001]
もう一つの重要なシグナルは実行速度です。単一セッションから短時間のうちに何十回ものシークレットストア照会が行われる場合、それは単発のイベントではなく「発生率」として捉える必要があり、同じログ上で相関分析を行う必要があります。今回観測した攻撃者たちの間では、5分間に20回というペースが一つの分かれ目になっていましたが、各自の環境のベースラインに合わせて調整してください。また、シェルツールが実際にホストへアクセスできる権限を持っている場合、脱出やアカウント作成の試みは通常のホストセキュリティの問題として扱えます。/etc/shadowやauthorized_keysに対するauditdの監視、そして--privilegedや/のバインドマウント付きで作成されたコンテナに対するDockerデーモンの監査を導入してください。
MITRE ATT&CK
最新のマトリクスに照らして検証済みです。紙幅の都合上、探索(Discovery)系のテクニックは割愛し、本質的な攻撃チェーンのみを掲載します。
| ID | 名称 | 挙動 |
|---|---|---|
| T1003.008 | OS Credential Dumping: /etc/passwd and /etc/shadow | パスワードファイルおよびshadowファイルの読み取り |
| T1552.001 | Unsecured Credentials: Credentials In Files | .env、credentials.bak、デプロイ鍵、サービス設定ファイル |
| T1555.006 | Credentials from Password Stores: Cloud Secrets Management Stores | シークレットストアの総当たり探索 |
| T1610 / T1611 | Deploy Container / Escape to Host | docker run --privileged -v /:/hostの実行試行 |
| T1136.001 | Create Account: Local Account | バックドア用adminアカウントの作成試行 |
| T1098.004 | Account Manipulation: SSH Authorized Keys | SSH鍵の注入試行 |
| T1078.004 | Valid Accounts: Cloud Accounts | 発火した鍵の悪用 |
| T1496.004 | Resource Hijacking: Cloud Service Hijacking | Bedrock上でのInvokeModel / Converse実行(LLMjacking) |
本記事の限界について
これはハニーポットから得られたデータであり、示しているのはあくまで「意図」であって「実際の侵害」ではありません。実在のシステムには一切到達しておらず、対象のホストはおとりであり、提供された認証情報はすべて偽物、あるいはトリップワイヤーでした。脱出行為、バックドアアカウントの作成、/etc/shadowの読み取りといった行動は、いずれも作り物の結果に対する試みにすぎません。24件という数字はあくまで下限値であり、私たちのセンサーの監視範囲と、およそ10週間という観測期間に限定されたものです。また、機械的な速度による分類はあくまで速度から導いた評価であって、身元を確定させるものではなく、私たちはいずれのセッションについても、特定の個人や組織に帰属させるものではありません。
新たな戦線が開かれた
今回の観測結果は、公開されたMCPサーバーを実際に操作する攻撃者たちの姿を、これまでで最も鮮明に描き出したものです。そして、これが最後の事例になるとは考えていません。AIエージェントの「ツール一式」は今や攻撃対象領域の一部となっており、攻撃者たちは偵察の手順すら飛ばして、いきなり認証情報そのものを狙いにきています。
そして、その大半は外部からはほとんど見えません。スキャナーから見えるのは、サーバーがハンドシェイクに応答したという事実だけです。認証情報の総当たり探索、脱出行為、バックドア、そして後日誰かのBedrock請求書に浮かび上がってくる盗まれた鍵――これらはすべて、サーバー自身にしか見えないものです。これこそがこの脅威の本質であり、欺瞞(デセプション)という手法が有効である理由でもあります。公開されたMCPサーバーが実際に悪用されている様子を見届けられる視点は、そのサーバー自身にしかないのです。こうしたサーバーは今後も増え続けていくでしょう。MCPサーバーを運用するすべての人にとって、もはや問題は「攻撃者に見つかるかどうか」ではありません。「見つかったその瞬間に、あなたが見ているかどうか」なのです。
本レポートで使用したハニーポットは、AIネイティブなインフラ向けのオープンソース欺瞞フレームワークであるBeelzebub(github.com/beelzebub-labs/beelzebub)を用いて構築されています。本物そっくりにプロトコルを実装しているからこそ、スキャナーには到達できない場所にこのおとりを配置でき、攻撃者が行うすべてのツール呼び出しを記録できるのです。
もしあなたがMCPサーバーやAIゲートウェイ、エージェントインフラを運用しており、自社の公開領域にどのような攻撃者が引き寄せられているかを確認したい場合は、デモを予約してください。
Beelzebubチームは、インターネットをより良く、より安全な場所にすることに尽力しています。❤️
翻訳元: https://beelzebub.ai/blog/it-thought-it-had-won/