本文の内容は、2021年4月16日にStefano Chiericiが投稿したブログ(https://sysdig.com/blog/cve-2021-20291-cri-o-podman/)を元に日本語に翻訳・再構成した内容となっております。
CVE-2021-20291 中程度の脆弱性が container/storage Go ライブラリに見つかりました。脆弱なコンテナエンジンがレジストリからインジェクトされたイメージをプルすると、サービス妨害 (DoS) が発生します。
影響を受けるコンテナエンジンは以下の通りです:
これらの脆弱なコンテナエンジンに依存しているコンテナ化されたインフラストラクチャーは、KubernetesやOpenShiftなども含めて影響を受けます。
この脆弱性を悪用すると、報告されている脆弱なコンテナエンジンを使用しているあらゆるコンテナ化されたインフラストラクチャーに対してサービス妨害を引き起こした後、エンジンの実行を停止させることができます。
この記事では、CVE-2021-20291がどのように機能するか、Kubernetesのどの部分が影響を受けるか、そしてどのように緩和するかを理解します。
予備知識
CVE-2021-20291自体の話を始める前に、コンテナエンジンがどのようにイメージをプルするかを簡単に理解する必要があります。
Dockerイメージは、アプリケーションの実行に必要なソースコード、ライブラリ、依存関係、ツールなどのファイルを含むイミュータブルな(変更不可能な)ファイルです。読み取り専用であることから、これらのイメージはスナップショットと呼ばれることもあります。
Dockerイメージを構成する各ファイルは、レイヤーと呼ばれています。これらのレイヤーは一連の中間イメージを形成し、段階的に構築され、各レイヤーはすぐ下のレイヤーに依存しています。
レジストリからイメージをプルする際にエンジンが行う動作の1つに、レイヤーリストを読み込んで、リストされたすべてのコンポーネントのダウンロードとupackを開始するというものがあります。
CVE-2021-20291の問題
CVE-2021-20291 は、v1.28.0 までの container/storage Go ライブラリに影響します。影響を受けるコンテナエンジンは以下の通りです。
お使いのシステムにインストールされている現在のバージョンを確認するには、次のようにします:
Podman --version # or crio --version
CVE-2021-20291を悪用するには、攻撃者は、イメージの脆弱性を悪用する悪意のあるレイヤーを追加し、それをレジストリにアップロードする必要があります。犠牲者がイメージをプルすると、インジェクトされたレイヤーがエンジンにダウンロードされて解凍され、脆弱性が誘発されます。
エンジンの実行フローでは、以下のステップで3つのルーチンを実行します。
- メインルーチンは、悪意のあるレイヤーを含む、インジェクトされたイメージのレイヤーをダウンロードします。
- 2番目のルーチンが起動し、ダウンロードしたレイヤーを解凍し、その出力を標準出力に書き込みます。3 番目のルーチンは、すべてのレイヤーが終了するまで待って chdone チャネルを閉じます。
- ステップ2の出力がデータの解凍に使われる。この時点で、解凍されたデータがtarアーカイブでない場合、アクションはエラーで終了し、残された残りのデータの読み取りをブロックします。
- 3つ目のルーチンの待ち時間は、発生したエラーのために終わらず、デッドロック状態になります。メイン・ルーチンも同様に、3番目のルーチンの終了を待ちます。
ロックを取得したまま解放されないデッドロック状態で実行が終了します。これにより、他のスレッドやプロセスが実行を停止して永遠に待ち続けるため、最終的にDoSが発生します。
CVE-2021-20291の影響
CVSSシステムによると、CVE-2021-20291の深刻度は6.5と中程度です。
この脆弱性は、攻撃の複雑性が低く、コンテナエンジンの機能を停止させるため、可用性への影響が非常に高くなります。一方で、機密性や完全性の観点からは影響がありません。
影響を受けるコンテナエンジンは、KubernetesでサポートされているCRI-OとPodmanです。つまり、これらのエンジンを使用しているKubernetesクラスターも、この脆弱性の影響を受けます。
悪意のあるイメージを複数のノードにデプロイすると、すべてのノードが破壊され、ノードの再起動が必要になります。
CVE-2021-20291の緩和策
この脆弱性の影響を受けている場合は、CRI-O v1.20.2およびPodman v3.1.0に修正プログラムがリリースされています。
すぐにパッチを当てることができない場合でも、この脆弱性を悪用しようとする行為を検知することは、攻撃を防止または阻止するために重要です。脆弱性の影響を受けるシステムやコンテナをすでにアップグレードしている場合でも、環境内での悪用の試みや侵害後の活動を検出する必要があります。
dockerイメージのベストプラクティスに従うことは、この種の脆弱性を軽減するのに役立ちます。特に、プライベートレジストリや署名などのセキュリティ技術を使用することで、デプロイされたイメージが信頼できるものであることを確認し、改ざんの試みを防ぐためにセキュリティ署名を行います。
プライベートレジストリ
先に述べたように、この脆弱性を利用するためには、被害者はレジストリから悪意のあるイメージをクラスターにプルする必要があります。この場合、プライベートレジストリを使用することで、脆弱性を軽減することができます。
最もよく知られているコンテナレジストリはDockerHubで、DockerとKubernetesの標準的なレジストリとなっています。パブリックレジストリの問題点は、その動作を完全にコントロールできないことと、誰でもカスタムイメージをアップロードできることです。カスタムイメージには、敵対者があなたの環境にアクセスしたり、よく知られている脆弱性を利用したりするための隠しコードが含まれているかもしれません。
プライベートレジストリは、複数の異なるストレージおよび認証オプションを提供し、お客様の個々の要件に合わせてカスタマイズすることができます。
さらに、セキュリティの観点からも、プライベートレジストリは以下のようなメリットがあります。
- イメージの保管場所の管理
- イメージへのアクセス方法の管理
- 所有権のあるプライベートなイメージのプライバシー保護
ほとんどのイメージスキャナは、デプロイされたイメージがお客様のプライベートレジストリからのものであることを保証するツールを提供しています。
Sysdig Secureでこれらのポリシーを適用すると、イメージスキャナは、信頼できる内部レジストリからのイメージだけを通過させ、パブリックレジストリからのイメージはすべて失敗させます。
イメージスキャナをアドミッションコントローラと組み合わせることで、スキャンに合格しなかったイメージをデプロイからブロックすることができます。このケースに適用すると、パブリックレジストリーからのイメージはすべて停止し、プライベートリポジトリからのイメージは許可することになります。
Sysdig Secureでのアドミッション・コントローラ・ポリシーの設定
コンテナイメージの署名
悪意のあるイメージを環境へデプロイする事を避けるためには、プライベートレジストリの利用に加えて、コンテナイメージサイニングが役立ちます。イメージ署名・検証プロセスでは、イメージに秘密の暗号署名を追加することができ、デジタル署名を追加することで、イメージがオリジナルである事の証明、真正性、証明性を確保することができます。
コンテナイメージの署名は以下を可能にします:
- コンテナイメージがどこから来たのかを検証する
- イメージが改ざんされていないことの確認する
- 検証されたイメージをホストにプルできるかどうかを決定するポリシーを設定する
検証側では、署名のないイメージや不正な署名をプルしてきた場合、ホストはレジストリからイメージをプルする事ができなくなります。
アドミッションコントローラーの仕組みを使えば、署名された信頼できるイメージだけが環境にデプロイされるようになり、意図的に悪意のあるイメージがデプロイされるのを防ぐことができます。
まとめ
ここまで、CVE-2021-20291が細工されたイメージレイヤーを悪用して、インフラにDoSを引き起こす方法を見てきました。
幸いにも、最新のバージョンにアップグレードし、コンテナイメージのベストプラクティスに従うことで、このような攻撃や同様の攻撃を回避することができます。
Sysdig Secureは、Kubernetesクラスターのベンチマークや、PCI、NIST、CISなどのセキュリティ基準を用いたセキュリティ態勢のチェックをサポートします。今すぐお試しください!