再び脆弱性が判明:Kubernetes のログクエリーにおけるコマンドインジェクション

Tomer Peled

執筆者

Tomer Peled

January 24, 2025

Tomer Peled

執筆者

Tomer Peled

Tomer Peled は Akamai の Security Researcher を務めています。脆弱性から OS 内部まで、幅広く調査を行うことが彼の業務です。休暇には、料理、クラヴ・マガ、PC ゲームなどを楽しんでいます。

この脆弱性に対して、まだパッチを適用していない場合は、優先的に適用することをお勧めします。
この脆弱性に対して、まだパッチを適用していない場合は、優先的に適用することをお勧めします。

編集・協力:Tricia Howard

エグゼクティブサマリー

  • Akamai のセキュリティリサーチャーである Tomer Peled は最近、Kubernetes の脆弱性(CVE ID:CVE-2024-9042)を発見しました。

  • この脆弱性により、Kubernetes クラスター内のすべての Windows エンドポイントで SYSTEM 権限を使用してリモートコード実行(RCE)が可能になります。この脆弱性の悪用が発生するためには、新しいロギングメカニズムである「ログクエリー」を実行するようにクラスターが設定されていることが条件となります。

  • この脆弱性は、リモートノードへの簡単な GET 要求でトリガーされる可能性があります。

  • この脆弱性の悪用が成功すると、クラスター内のすべての Windows ノードで完全な乗っ取りが成立する可能性があります。

  • この脆弱性は、ベータ版機能の使用をオプトインする Kubernetes のデフォルトインストール(バージョン 1.32.1 よりも前のバージョン)で悪用される可能性があり、オンプレミスデプロイメントと Azure Kubernetes Service の両方に対してテストされました。

  • このブログ投稿では、概念実証用の curl コマンドを提示し、取り得る緩和策について解説します。

はじめに

Kubernetesコンテナは全般的に見て、セキュリティの世界では特に注目を浴びており、(当社を含む)世界中の研究者が関心を寄せる研究材料となっています。調査において、まずたどり着いたのが、CVE-2023-3676 です。これは、悪意のある YAML ファイルをクラスターに適用することで悪用される可能性のあるコマンドインジェクションの脆弱性です。この調査により、Kubernetes のソースコードには、他にもクラスターの完全な乗っ取りを成立させるいくつかの問題があることが明らかになりました。

私たちが発見した脆弱性はこれだけではありません。サイドカープロジェクトの git-sync の調査結果も注目すべきものでした。私たちは DEF CON 32 の Red Team Village でこれらの調査結果を発表しましたが、この発表の準備中に偶然見つけたのが、今回のブログ投稿のトピックです。それは、ログクエリーという、より大規模なロギングフレームワークを実現する Kubernetes のベータ版機能が、コマンドインジェクションのもう 1 つの機会になるというものです。

ログクエリーとは

ログクエリーでは、CLI または curl を使用して、リモートマシンのシステムステータスの照会が可能になります。たとえば、次のコマンドを入力すると、リモートノードの kubelet サービスのステータスを照会できます。

  kubectl get --raw "/api/v1/nodes/node-1.example/proxy/logs/?query=kubelet"

上記のコマンドを見たとき、以前の調査を思い出しました。そして浮かんだのが、「リモートマシンに送信されたクエリーは検証されるのだろうか」という疑問です。

図 1 はログクエリーのソースコードの例で、ここには複数の PowerShell コマンドが組み込まれています。

これらのコマンドは、Windows サービス名、使用時間パターンなど、さまざまなパラメーターに基づいて、特定のノードからログを取得するために使用されます。

以前の経験(CVE-2023-3676)から、Kubernetes は、PowerShell コマンドを作成する際に、必ずしもパラメーターとして挿入する前にユーザー入力を検証しているわけではないことがわかっています。私たちは、これがログクエリーの場合にも当てはまるかどうか知りたいと考え、サービス名が事前定義の正規表現を使用して実際に検証されることを確認しました(図 2)。

reServiceNameUnsafeCharacters という名前は、このチェックがサービスのみを対象としていることを示唆しています。パースプロセスにおいて他の正規表現は見つからず、この仮説の確度は高まりました。

他のパラメーターを調べた結果、やはり、検証されているパラメーターはサービス名だけであることが明らかになりました。これは、他のパラメーターに注目すればコマンドインジェクションを実行できるということを意味します。ログクエリーでは、ユーザーが指定できるオプションパラメーターがいくつかありますが、文字列であるパラメーターはパターンパラメーターだけです(図 3)。前述したように、パラメーターの検証は(長さ以外)行われません。

注目すべき点は、この脆弱性の悪用は簡単ではないということです。私たちは、PowerShell のペイロードに、ブラケットを追加したり、セパレーターを使用したりするなど、さまざまな置換と組み合わせを使用してリモートコンピューター上でコマンドをトリガーしようとしましたが、作用は確認できませんでした。エラーもなかったため、解明は容易ではありませんでした。

問題はペイロードではない

コマンドインジェクションのさまざまな手法を試した結果、最終的にはペイロード自体には問題がないことがわかりました。この脆弱性を悪用するには、通常の klog フレームワークではなく、ETW にネイティブにステータスをロギングするサービスを指定する必要がありました。脆弱性チェックがあるのは Windows のイベントトレース(ETW)へのロギング時のみであるからです。

Calico(Kubernetes の一般的なオープンソースのネットワークインタフェース)を使用した Kubernetes 環境では、Non-sucking Service Manager(NSSM)を通じてこの脆弱性を確実に悪用することができます。

  • Calico 設定では、通常、Kubernetes のサービスの状態を制御するために NSSM を使用します。他の環境や設定では、サービスの状態を処理するために異なる方法を使用します。

  • Kubernetes は NSSM のロギング出力を管理することなく、ログが klog を通さずに直接 ETW に書き込まれるようにします。

クエリーの悪用の例

クエリーの悪用の例を以下に示します。

  curl  "<Kubernetes API Proxy server IP>/api/v1/nodes/<NODE name>/proxy/logs/?query=nssm&pattern=’\$(Start-process cmd)’"

*API サーバーと通信するために必要な認証トークンは編集されています

鋭い読者は、悪意のあるコマンドをエスケープするのに使用されているアポストロフィについて疑問に思われたかもしれません。これは、Kubernetes が次のコマンドを使用して入力を挿入するために必要なのです。

  …Where-Object -Property Message -Match '%s'... 

従来の SQL インジェクション攻撃と同様に、パターンをエスケープするアポストロフィを追加して、入力が別のコマンドとして解析されるようにする必要があります(図 4)。

優先パッチ

この脆弱性の影響を受けるのは、1.32.1 より前のバージョンの Kubernetes を使用しているユーザーになると考えられます。この脆弱性に対して、まだパッチを適用していない場合は、優先的に適用することをお勧めします。これは、クラスター内に Windows ノードがある組織に特に当てはまります。それが脆弱性が存在する部分であるからです。 

しかし幸いなことに、これは業界標準ではないようです。管理者は、クラスターコントローラーで次のコマンドを実行して、組織のクラスターに Windows ノードが含まれているかどうかを簡単にテストできます(図 5)。

脆弱性はあるか

これで、脆弱かどうかを簡単に判断できます。「os=windows」の部分に注目してください。Windows ノードがない場合、コマンドを実行しても何も出力されません。つまり、脆弱性はないということです。

これはベータ版機能であるため、クラスター自体もこのフレームワークを使用するように設定されている必要があります。

この機能が有効になっているかどうかは、管理者が「feature-gate」スタートアップパラメーターで「kubelet」を探せば確認できます。 詳細は、Kubernetes のサイトで確認してください。

パッチ分析

この脆弱性を修正するために、Kubernetes は、PowerShell コマンド自体に値を渡す前に「kubelet_pattern」という名前の環境変数を使用することにしました。

こうすることで、ユーザー入力は、評価が必要な式の一部ではなくリテラル文字列であるとみなされます。

緩和策

この脆弱性を緩和するために、管理者はロールベース・アクセス・コントロール(RBAC)モジュールを使用して、ログクエリーへのアクセス権を持つユーザーを制御したり、ログクエリーへのアクセスを完全に無効にしたりすることができます。RBAC は、ユーザーの操作をユーザーが誰であるかに応じてセグメント化する方法です。たとえば、各ユーザーは独自の名前空間に Pod を作成することだけ、または許可された名前空間の情報を閲覧することだけができます。これにより、RCE が実行されるリスクだけでなく、検出のリスクも軽減されます。多くの場合、ユーザーの異常なふるまいは被害の発生を示しています。 

この脆弱性は Windows ノードにのみ影響することに留意してください。Kubernetes クラスターに Windows ノードがない場合は、この脆弱性の影響はありません。ただし、できるだけ最新のパッチを適用し、他の未知の脆弱性を回避できるようにしておくことが推奨されます。 

この問題はソースコード内に潜んでいるため、この脅威に曝される危険性は依然としてあり、悪用される可能性が高まりそうです。したがって、Windows ノードがまったくないとしても、クラスターにパッチを適用することを強くお勧めします。

結論

このブログの投稿では、クエリーの権限を持つ攻撃者がクラスター内の任意の Windows ノードでコマンドを実行する方法について説明しました。この脆弱性は、YAML ファイルの送信を必要とせず、簡単な curl コマンドによって悪用される可能性があります。このような悪用は緩和や検知が難しいため、大きなリスクが発生します。以前にも議論したように、Kubernetes のサニタイズの問題はログクエリーに限ったことではありません。

ブルーチームのメンバーは、組織内で発生する異常なふるまいに注意を払う必要があります。これらの攻撃ベクトルは、クラスターの完全な乗っ取りにつながる可能性があります。そのため、意識を向上させ、セキュリティ管理者が潜在的な危険を把握できるよう支援することが重要です。

Akamai Security Intelligence Group は、このような脅威を継続的に調査し、お客様やセキュリティコミュニティ全体に報告します。私たちの現在の取り組みに関するリアルタイムの最新情報については、X(旧 Twitter)でフォローをお願いいたします。

Kubernetes チームの対応と開示に感謝します。

タイムライン

2024/06/28 — Kubernetes チームに脆弱性を開示

2024/07/18 — Kubernetes チームが問題解決に着手

2024/07/30 — Kubernetes チームが CVE を割り当て

2025/01/16 — Kubernetes が CVE 修正パッチをリリース 

2025/01/24 — ブログ記事を公開



Tomer Peled

執筆者

Tomer Peled

January 24, 2025

Tomer Peled

執筆者

Tomer Peled

Tomer Peled は Akamai の Security Researcher を務めています。脆弱性から OS 内部まで、幅広く調査を行うことが彼の業務です。休暇には、料理、クラヴ・マガ、PC ゲームなどを楽しんでいます。