CVE-2020-15157:Containerd の脆弱性により、クラウドの認証情報が漏洩する可能性 #aqua #コンテナ #セキュリティ #脆弱性 #containerd #CVE-2020-15157
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
本ブログは「Aqua Security」社の技術ブログで2020年10月22日に公開された「 CVE-2020-15157: Vulnerability in Containerd Can Leak Cloud Credentials 」の日本語翻訳です。
CVE-2020-15157:Containerd の脆弱性により、クラウドの認証情報が漏洩する可能性
containerd に新たな脆弱性が発見されました。新しい CVE にはイメージマニフェストの操作が含まれており、攻撃者はレジストリから pull した際にホストのレジストリやクラウドの認証情報を漏洩させるようなイメージを作成できます。この漏洩は、イメージがサーバ上でコードを実行する前であっても発生します。
Containerd は、Linux と Windows 用のデーモンとして利用可能な業界標準のコンテナランタイムです。イメージの転送と保管、コンテナの実行と監視、ネットワークのアタッチメントなど、ホストシステムのコンテナのライフサイクルを管理できます。
コンテナイメージは、マニフェストファイルといくつかのレイヤーファイルの組み合わせです。マニフェストファイルには、イメージの名前/タグ、レイヤー、サイズ、ダイジェストなどの情報が JSON で表現されています。マニフェストには、リモートレジストリから取得した「外部レイヤー」を含めることができます。containerd を使用している場合、リモートレジストリが特定の HTTP ヘッダと共に HTTP 401 ステータスコードで応答するとホストは認証トークンを送信しますが、これを盗用される可能性があります。攻撃者はこの脆弱性を悪用して、ホストの認証トークンを漏洩するように設計された専用のコンテナイメージを構築し、それを利用してクラウドプロジェクトを乗っ取ることができます。
この脆弱性を深く掘り下げてみると、マニフェストは containerd の標準フォーマットである Docker Image Manifest Version 2, Schema 2 に則っています。マニフェストには、ファイルシステムのレイヤーとその実行方法が記述されており、コンテナランタイムがレイヤーを検証した後、引き続きレイヤーをダウンロードしてイメージを実行できます。マニフェストは、複数のプラットフォーム/アーキテクチャの組み合わせをサポートするマニフェストリストになることもあり、現在では「DockerHub」上のほとんどのイメージがマニフェストリストになっています。
Docker Image Manifest Version 2, Schema 2 のドキュメントを見てみると、マニフェストの例が以下のようになっています。
この JSON で表記されているマニフェストは、コンテナイメージの設定とレイヤーのセットを提供し、最後のレイヤーはURLフィールドを持つ「外部レイヤー」です。完全なマニフェストの仕様はこちらで確認できます。Image Manifest V2, Schema 2 Specification.
レイヤーの説明をさらに深く読むと、マニフェストはコンテンツを取得する外部 URL のオプションフィールドをサポートしていることがわかります。
この機能は containerd のイメージ pull 処理の脆弱な部分を保持しており、外部レジストリからレイヤーを pull するために containerd を起動するには、そのイメージマニフェストを編集しなければなりません。イメージは基本的にマニフェストであり、これはつまり、誰もがアップロードしたイメージからこの機能を起動できることを意味します。
さて、このイメージを pull する人は、全員そのレイヤーをダウンロードするためにリモートレジストリへリダイレクトされます。次に、リモートレジストリからイメージをダウンロードするクライアントが、認証プロセスに従って認証 OAuth トークンを要求できます。リモートの外部レジストリからの適切な応答があれば、認証を要求されたときに HTTP 401 と正しいRealmの応答で、これを実現できます。
この攻撃をシミュレートするには、イメージを GCR レジストリに push し、脆弱性のある containerd を実行している GKE クラスタ(脆弱性が発見された時点で)からそれを pull する必要があります。実行後に、外部レイヤーをダウンロードするように指示されたリモートの外部レジストリ(をシミュレートした「nginx」)のWebログを確認してみると、「Basic Auth」ヘッダを確認できます。これを base64 でデコードすると、認証トークンであることがわかります。このシミュレートでは、これは GCP サービスアカウント OAuth トークンとなります。
この例では、トークンはクラウドリソースに対して「プロジェクト」を編集する権限を持っていますが、スコープが制限されているため、権限を変更できません。しかしもし制限されていないと、このサービスアカウントの権限が変更され、アカウントの乗っ取りにつながる可能性があります。もちろん、GKE はこの問題が発生する可能性のある多くの例の一つに過ぎません。
まとめ
今回のケースのように、定期的に最新バージョンのソフトウェアを使用しているかどうかを確認することは、非常に良い習慣です。この CVE を修正するには、利用しているシステムで最新バージョンのコンテナランタイムが実行されていることを確認する必要があります。この脆弱性は containerd 1.2.4 でパッチが適用されています。また containerd 1.3.x でもテストが行われ、この脆弱性を含まないことが確認されています。
References NVD NIST CVE-2020-15157 |