🐯

GCP-Goat で学ぶ Google Cloud セキュリティ Day1

2022/10/06に公開

はじめに

こんにちは、クラウドエースでSREディビジョンに所属している Shanks と申します。

クラウドエースではギルドと呼ばれる任意参加型の技術習得・自己学習制度が存在します。
その1つでもあるセキュリティギルド(セキュリティに関する学習・アウトプットが目的のグループ)に所属しましたので、Google Cloud に関するセキュリティのナレッジをアウトプットする場として技術ブログに連載していくことになりました。

gcp-goat
とはいえ、セキュリティの分野は幅広くどこから手をつけるべきか迷ってしまう、というのが正直なところかと思います。
そこで、GCP-Goat と呼ばれる、Google Cloudのセキュリティを学習および実践することができる環境・手法を展開する学習資材をを利用することにしました。
この学習資材では Google Cloud 上で展開しているシステムにどんな脅威があるのか、実践形式で学べるというものです。

各攻撃手法については章立てで別れており、環境セットアップや手法についてはスクリプト化されているためコピペをすればなぞることが出来るようになっています。
ですのでこの連載においてはそれらを掲載することはやめ、下記について調査・説明することにしました。

  1. 攻撃に使われた脆弱性はどんなものか
  2. 攻撃ではどんなことが行われていたのか(詳解)
  3. 攻撃からシステムを保護するにはどんなことに注意し、どんな対策をしていけばよいのか

この連載を通じて読んでくださる方のシステムがより安全になる一助になれば幸いです。

参考:https://gcpgoat.joshuajebaraj.com/about.html

ターゲットとなる読者層

  • Google Cloud 上で展開している・構築予定のシステムをより安全なものにしたい
  • どのような脅威があり、どのようにシステムを保護すべきか知りたい
  • 自社のセキュリティポリシーで Google Cloud の範囲がカバーできているか不安なので参考情報がほしい

この連載でやること・やらないこと

やること

  • GCP-Goat に掲載された攻撃の詳解
  • Google Cloud 特有機能や技術の詳解
  • 脅威からシステムを保護する方法
  • 事例の紹介(セキュリティインシデント・対策事例)

やらないこと

  • GCP-Goat の手順をそのままなぞること
  • 特定の製品の使い方(セキュリティ対策ソフト等)
  • Cloud Security Command Center のような有料契約(高額)製品の使用

注意事項

この連載はあくまで「脅威からどのようにしてシステムを保護するのか」を学ぶ場であり、攻撃を助長することが目的ではありません。
また、GCP-Goat では意図的に脆弱な環境を構成するため、決してこれを 本番環境へデプロイしないでください。

Compute Engine への攻撃

attacking-gce
Attacking Google Compute Engine [原文タイトル]
https://gcpgoat.joshuajebaraj.com/attacking-compute.html

この章では、SSRF と呼ばれる脆弱性ないしは攻撃手法から、GCE/GKE を保護する方法について学んでいきます。
SSRF 攻撃は、Google Cloud に限らず AWS/Azure 等でも広く利用されうる攻撃です。
SSRF 攻撃と Google Cloud での注意点を見ていきましょう。

metadata server

ssrf-metadata.drawio
Google Cloudには metadata server と呼ばれるユーザからは見えない(意識することのない)Google Cloud 基盤側のリソースがあり、すべてのGCE等は自動的にアクセスして必要な情報を取得するよう設計されています。
その中には通信の宛先情報であったり、VM 固有の情報、起動スクリプトなどが key:val の形式で保存されている重要な部分です。

実際には下記のようなエンドポイントに内部的にアクセスし、様々な情報を取得しています。

http://metadata.google.internal/computeMetadata/v1/

metadata server へのアクセス

ssrf-metadata2
公式ドキュメントでも案内されていますが、この metadata server へリクエストを送信しても、GCE インスタンスをホストする Google Cloud 基盤(物理ホスト)の外に出ることはありません。
一方で、外にレスポンスが出ないだけで内部では自由に取得することができてしまいます。
例えば、第三者が外部からレスポンスを受け取る際に GCE を経由して表示させてしまえば、簡単に取得することができてしまうわけです。
( metadata server は”内部”の GCE インスタンスに返しているので、正しい振る舞いと言えます)

それでは、通常どのようにリクエストを送信するのかを確認してみましょう。
metadata server は正しく利用すれば便利なものです。
追加の承認プロセスを経ることなく、設定したスタートアッププログラムを使用したり、VM 固有の情報をプログラム中で取得したりできます。

すべてのメタデータ値は、次のルート URL のサブパスとして定義されます。

http://metadata.google.internal/computeMetadata/v1

また、意図したソースからでないリクエストに対してのレスポンスを防ぐため、以下のヘッダーを付与する必要があります。
(そのリクエストがメタデータの値を取得する目的で送信されたものかどうか)

Metadata-Flavor: Google

では、手元の Mac Book Pro からアクセスをしてみましょう。
curl-error

$ curl "http://metadata.google.internal/computeMetadata/v1/?recursive=true&alt=text" -H "Metadata-Flavor: Google"
curl: (6) Could not resolve host: metadata.google.internal

ご覧の通り、internal ドメインのため外部からアクセスすることはできません。
この metadata.google.internal というドメインは、169.254.169.254 というリンクローカルアドレスが割り振られています。
つまり、外部からはアクセスできず、Google Cloud 内部ネットワークからのみ到達することができる宛先というわけです。

cloudshell-metadata

Google Cloud の VPC ネットワークには、同じ内部ネットワーク内同士で相互に通信できるよう、内部 DNS 機構が設けられています。
Compute Engine などは VPC ネットワーク内からの通信として扱われるため、この内部 DNS を使用して .internal ドメインにアクセスすることが可能というわけです。

cloudshell-nslookup

$ nslookup metadata.google.internal
Server:         169.254.169.254
Address:        169.254.169.254#53

Non-authoritative answer:
Name:   metadata.google.internal
Address: 169.254.169.254

参考:https://cloud.google.com/compute/docs/internal-dns?hl=ja

SSRF(Server Side Request Forgery) 攻撃

先ほど、metadata server のアクセスで「外部からはアクセスできず、Google Cloud 内部ネットワークからのみ到達することができる宛先」と説明しました。
では、攻撃者はどのようにしてこのエンドポイントにアクセスをするのでしょうか。

ssrf-about-ssrf

そもそも、SSRF 攻撃とは公開サーバ等を経由して非公開サーバにアクセスして不正に情報を入手する攻撃手法です。
そのため、まずは公開サーバを標的として攻撃をしかけます。
代表的な攻撃手法としては SQL インジェクションで DB のデータを不正に操作したり、APIの脆弱性などを利用して任意のURLにリクエストを送信するなどして、SSRF攻撃の入り口を作ります。
そのうえで、上述の metadata server のような内部向けの非公開サーバにアクセスし、機密情報(キーやアクセストークン等)を不正に入手するに至ります。

ssrf-ssrf-attacking

万が一先に述べた SSRF 攻撃を悪意ある第三者から受けた場合、これらの情報が漏洩するだけでなく、そこからさらなる攻撃経路を割り出される恐れがあります。
パッケージ製品等を代表する、アプリケーション要件としてマネージドサービス等が利用できずクラウド上のIaaSを選択するケースもありますが、その際は注意しておく必要があるかもしれません。

また、SSRF 攻撃は実際に起こりうる攻撃で、国際的な脆弱性報告プラットフォームとして有名な hackerone で検索すると多くの報告や情報交換が行われていることがわかります。
hackerone

metadata server にはアクセストークンや SSH キーなども含まれています。
また、ユーザがカスタムメタデータを設定することもできます。
そのため、直接的にセキュリティインシデントへ繋がるアクセストークン等の機密情報が含まれている場合は特に注意し、必要に応じて後述の対策を検討しておくとよい場合があります。
(特に、このアクセストークンを悪用されると、一部のリソースへのアクセスを承認させてしまうことに繋がります)

SSRF の実例

SSRF 攻撃は Google Cloud や それに限らず、現実に起こりうる攻撃手法です。
SSRF 攻撃の被害にあった実例を紹介します。

Shopify:GKE のクレデンシャル情報を盗まれ Root を乗っ取られた

metadata の宛先に v1beta1 エンドポイントを利用すると、リクエストに必要なヘッダー情報を付与せずリクエストをバイパスすることができる仕様を悪用された。
結果として GKE クラスタにアクセスするためのクレデンシャル情報を盗み取られ、Root を乗っ取られる事態へと発展してしまった。
参考:https://hackerone.com/reports/341876

Capital One:S3バケットに保管していた1億人超の個人情報が流出

AWS のオブジェクトストレージサービス S3 に、大量の個人情報を保管していた。
この S3 バケットを保護していた独自運用の WAF に設定誤りがあり、EC2 インスタンスのメタデータサーバにリクエストを送信することに成功。
このとき取得した認証情報を悪用して S3 バケットに sync を実行し個人情報を盗み取られてしまった。
参考:https://www.capitalone.com/digital/facts2019/
参考:https://www.capitalone.com/digital/responsible-disclosure/
参考:https://krebsonsecurity.com/2019/08/what-we-can-learn-from-the-capital-one-hack/

metadata から情報を取得してみよう

computeMetadata へリクエスト

先に述べたとおり、 metadata.google.internal には多くの情報が含まれています。
実際に下記のエンドポイントへアクセスし、どのような情報が取得できるか確認してみます。

http://metadata.google.internal/computeMetadata/v1/?recursive=true&alt=text  

含まれている代表的な情報は下記のとおりでした。
非常に多くの情報が含まれていることがわかります。
ssrf-attack-ans

  • startup-script
  • cpu-platform
  • ディスク情報
  • hostname
  • instance-id
  • instance-image(OS情報)
  • machine-type
  • 外部IPアドレス
  • 内部IPアドレス
  • MACアドレス
  • service-accounts
  • プロジェクトID

metadata server エンドポイント一覧

上述しているエンドポイントは一部の例となります。
すべてのエンドポイントの一覧は下記の通りです。

v1 系

v1beta1 系

また、Google Cloudに限らず他のパブリッククラウドのエンドポイントも紹介されていましたので参考情報として掲載します。

参考:https://cloud.google.com/compute/docs/metadata/overview
参考:https://gist.github.com/mrtc0/60ca6ba0fdfb4be0ba499c65932ab42e

どうすればリスクを緩和できるのか

metadata エンドポイント の無効化

GKEにデプロイされた Pod が驚異にさらされている場合、ノードの認証情報などを上述の方法で取得される恐れがあります。
そのため、実行中のワークロードから metadata server で管理されている機密情報を保護することをおすすめします。

例えば、GKEではレガシーエンドポイントを無効化することで対策することが可能です。

レガシーエンドポイントの無効化

非推奨となった古いエンドポイント(v1beta1系)に対してのリクエストを無効化することが可能です。
クラスタやノードプールの作成時に、下記のエントリを設定してください。

このエントリはGCEでも有効な手段です。
※ バージョン 1.12 以降、デフォルトで有効化されています。
※ 2020年9月30日以降、v0.1 と v1beta1 のメタデータ サーバー エンドポイントは非推奨となりシャットダウンされました。

disable-legacy-endpoints=true

disable-legacy-endpoints

参考:https://cloud.google.com/compute/docs/metadata/default-metadata-values#project-attributes-metadata
参考:https://docs.securestate.vmware.com/rule-docs/gcp-gke-instance-metadata-api-not-disabled
参考:https://cloud.google.com/kubernetes-engine/docs/how-to/protecting-cluster-metadata?hl=ja#disable-legacy-apis
参考:https://cloud.google.com/compute/docs/deprecations/v0.1-v1beta1-metadata-server?hl=ja

メタデータ隠蔽機能

Kubernetes v1.9.3 以降ではメタデータ隠蔽機能があり、これを有効にすることで Kubelet 認証情報やアクセストークンを保護することが可能です。
しかし、この機能は将来的に Workload Identity へ代替され削除される予定のため、現在は非推奨の方法となりますのでご注意ください。

メタデータ隠蔽

警告: Workload Identity は、メタデータ隠蔽機能に代わるもので、この 2 つに互換性はありません。
メタデータ隠蔽の代わりに Workload Identity を使用することをおすすめします。
メタデータ隠蔽機能は今後非推奨となり、削除される予定です。

Workload Identity の詳細については、公式ドキュメントをご確認ください。

参考:https://cloud.google.com/kubernetes-engine/docs/how-to/protecting-cluster-metadata#concealment

ラテラルムーブメントを防ぐ

最小権限の原則を徹底する

Google ではサービスアカウントやGoogleアカウントへの権限付与の際に、可能な限り最小限の権限のみを与えることをベストプラクティスとしています。
これにより、万が一の影響範囲を狭めることができます。

  • IAM の基本ロールである所有者、編集者、閲覧者の使用を禁止する
  • そのアカウントにとって必要最小限の権限のみを、必要なリソースのみに限定して付与する

上記を徹底し、必要に応じてカスタムロールを作成したり、レコメンド機能を活用して過剰な権限付与が行われていないか定期的に確認することをおすすめします。
また、組織ポリシーの設定によって、構成された組織外のメンバーに IAM ポリシーによる権限の付与が行われないように制限することも可能です。

参考:https://cloud.google.com/iam/docs/understanding-roles?hl=ja
参考:https://cloud.google.com/policy-intelligence/docs/role-recommendations-overview

その他の対策

Google Cloudにおけるラテラルムーブメント(侵入拡大)の防止措置として、Google Cloud公式ブログに様々な方法が掲載されていますので、本番環境を公開する前に今一度確認してみてはいかがでしょうか。

参考:https://cloud.google.com/blog/ja/products/identity-security/preventing-lateral-movement-in-google-compute-engine

セキュリティ製品の導入

弊社の事例でも、お客様のセキュリティポリシーに準拠する形でセキュリティ製品を導入しているケースがあります。
エージェント型のアンチマルウェアソフトやWAFなど、形態はいくつかあります。
例えば、Google Cloud 製品では Cloud Armor による SQL インジェクション や クロスサイトスクリプティング といった代表的な攻撃からアプリケーションを守る機能があります。
(OWASP ModSecurity Core Rule Set 3.0 と CRS 3.3 が事前定義済み WAF ルールとしてすぐに利用することができます)

Cloud Armor 以外では、ライセンスを保有している製品を Compute Engine 等の IaaS で展開しているお客様もいます。
こちらは皆様のご要件・セキュリティポリシーに応じてご検討いただけると良いかと思います。

参考:https://cloud.google.com/armor/docs/rule-tuning?hl=ja

まとめ

この章では以下のことについて、学んでいきました。

  1. Google Cloud(Public Cloud) 特有の metadata server について
  2. SSRF へ至る落とし穴や攻撃手法
  3. どのようにして驚異からシステムを保護するか

特に、レガシーエンドポイントの無効化などは十分に効果のある対策の1つでもありますので、ぜひご検討ください。
既に構築されたシステムや、これから展開予定のシステムを今一度見直し、より安全なものにする一助になればと思います。

Discussion