GCP - Network Docker Escape

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

初期状態

この手法が記載されている両方の報告では、攻撃者はホストネットワークにアクセスできる GCP 管理下の Docker コンテナ内で root 権限を取得しました(およびケーパビリティ CAP_NET_ADMIN および CAP_NET_RAW)。

攻撃の説明

Google Compute Engine インスタンスでは、ネットワークトラフィックを監視すると、169.254.169.254metadata instance への多数の plain HTTP requests が定期的に確認されます。オープンソースのサービスである Google Guest Agent は、そのようなリクエストを頻繁に行います。

このエージェントは metadata の変更を監視する よう設計されています。特に、metadata には SSH 公開鍵用のフィールド が含まれています。新しい公開 SSH キーが metadata に追加されると、エージェントはそれを .authorized_key ファイルに自動的に 登録(authorize) します。必要に応じて 新しいユーザーを作成 し、そのユーザーを sudoers に追加することもあります。

エージェントは、すべての metadata 値を再帰的に取得するリクエスト(GET /computeMetadata/v1/?recursive=true)を送信することで変更を監視します。このリクエストは、前回取得時から metadata に変更があった場合にのみメタデータサーバーがレスポンスを返すよう設計されており、Etag(wait_for_change=true&last_etag=)で識別されます。さらに、timeout パラメータ(timeout_sec=)も含まれます。指定したタイムアウト内に変更がなければ、サーバーは 変更なしの値(unchanged values) を返します。

このプロセスにより、構成の変更がない場合には IMDS (Instance Metadata Service) が 60 秒 後に応答することが可能となり、guest agent に対して偽の構成レスポンスを注入するための潜在的な ウィンドウ が生まれます。

攻撃者はこれを悪用して Man-in-the-Middle (MitM) attack を実行し、IMDS サーバーからのレスポンスを偽装して 新しい公開鍵を挿入 することができます。これによりホストへの不正な SSH アクセスが可能になる可能性があります。

エスケープ手法

Google Compute Engine のネットワーク上では ARP spoofing は無効ですが、Ezequiel が開発した modified version of rshijack を通信のパケット注入に使用して SSH ユーザーを挿入することができます。

このバージョンの rshijack は ACK と SEQ 番号をコマンドライン引数として入力できるため、実際の Metadata サーバーのレスポンスより前にレスポンスを偽装しやすくなります。さらに、small Shell script を使って 特別に作成されたペイロード(specially crafted payload) を返します。このペイロードは Google Guest Agent に対して .authorized_keys ファイルに指定した公開鍵で ユーザー wouter を作成(create a user wouter させます。

スクリプトは同じ ETag を使用して、Metadata サーバーがすぐに Google Guest Agent に異なる metadata 値を通知するのを防ぎ、レスポンスを遅延させます。

spoofing を実行するには、次の手順を実行します。

  1. Metadata server へのリクエストを監視するtcpdump を使用):
tcpdump で metadata サーバーへのリクエストを監視 ```bash tcpdump -S -i eth0 'host 169.254.169.254 and port 80' & ```

次のような行を探してください:

tcpdump の出力行の例 ```