本文の内容は、2021年9月24日にAlberto Pellitteriが投稿したブログ(https://sysdig.com/blog/cve-2021-25741-kubelet-falco)を元に日本語に翻訳・再構成した内容となっております。
CVE-2021-25741は、Kubernetesにおいて新たに発見された脆弱性で、subPathボリュームマウントを持つコンテナを作成すると、ホストファイルシステムを含むボリューム外のファイルとディレクトリへのアクセスが可能となります。
2021年9月に公開されたもので、Kubernetesの各ノードで動作するノードエージェントであるkubeletに影響します。特にCVE-2021-25741は、以下のKubernetesバージョンのkubeletに影響します。
- v1.22.0 – v1.22.1
- v1.21.0 – v1.21.4
- v1.20.0 – v1.20.10
- <= v1.19.14
この脆弱性の実際の影響をよりよく理解するために、CVE-2021-25741をどのように軽減し、検出するかを検討します。
予備知識:Kubernetesにおけるボリューム
Kubernetesのボリュームは、コンテナストレージの刹那的な性質に関連するさまざまな問題を解決します。コンテナを実行し、そのファイルシステム内に新しいファイルを直接保存すると、コンテナがクラッシュした場合、そのファイルを失うことになります。しかし、ボリュームを使用すれば、コンテナやポッドの寿命を超えてデータを保存することができます。
また、同じポッド内の複数のコンテナからファイルにアクセスできるようにしたい場合もあります。ボリュームを使用すると、一貫性のある方法でこれを実現できます。
つまり、ボリュームはポッドのコンテナからアクセス可能なディレクトリです。これらのボリュームにはさまざまなタイプがあり、起動時にポッドの仕様で直接指定します。これらのボリュームタイプの1つがsubPathです。これは通常、1つのポッド内の異なるコンテナ間で1つのボリュームを複数の目的で共有したい場合に使用されます。これは、CVE-2021-25741の影響を受けるシナリオであり、この記事で取り上げるシナリオでもあります。
subPathマウントはどのように機能しますか?
コンテナが起動すると、kubeletボリュームマネージャーは、ホストシステム上の専用ディレクトリの下に、ポッドで指定された、必要なすべてのボリュームをローカルにマウントします。ボリュームのマウントに関する情報は、その後、必要に応じてコンテナに戻されます:- コンテナ内のボリュームのパス
- ホスト上のボリュームのパス
CVE-2021-25741 の問題点
この脆弱性によって生じる問題は、utils-linux のマウントにおけるシンボリックリンクの解決に関連しています。実は、K8sではマウントのsyscallを直接使用せず、シンボリックリンクを解決するutils-linuxのsyscallを使用しています。そのため、Volume Subpathを使う場合、Kubernetesはボリュームをマウントした後、Subpathのバインドマウントを行い、ランタイムに渡します。ちなみに、マウント操作は作成されたコンテナによって制御されるため、悪意のあるユーザーが行うこともあるので、シンボリックリンクの交換は防ぐべきです。
ここでは、この脆弱性の背後にある真の問題とその解決策について報告しています:

古い関数「MountSensitiveWithoutSystemd」(赤)が「MountSensitiveWithoutSystemdWithMountFlags」(緑)に置き換えられ、新たに「–no-canonicalize」という文字列のパラメータが追加されています。これは、ドキュメントでも報告されているように、utils-linuxのマウントは、デフォルトですべてのパスを正規化するからです。
-c, --no-canonicalize Don't canonicalize paths. The mount command canonicalizes all paths (from the command line or fstab) by default...
悪意のあるユーザーがこの脆弱性を悪用して得られるものをよりよく理解するために、ここではこの脆弱性の潜在的な影響を探っていきます。
CVE-2021-25741の影響
CVSSシステムによると、これは深刻度の高いセキュリティ問題で、スコアは8.8です。この脆弱性に対する公開されたエクスプロイトはまだリリースされていませんが、この高いスコアリングは、攻撃の複雑さが低いことと厳密に関係しています。
さらに重要なことは、CVE-2021-25741の影響が非常に深刻であるということです。ホストのファイルシステムにアクセスできるということは、ホスト自体の制御権を得ることであり、他のコンテナに関連するデータが含まれている可能性のあるホストデータにもアクセスできるということです。これにより、悪意のあるユーザーがホスト環境を操作し、そのファイルシステム内のデータにアクセス、改ざん、削除することができる可能性があります。
ちなみに、この脆弱性は、コンテナがrootで実行されている場合にのみ悪用されるようです。つまり、幸いなことに、コンテナを起動しようとするユーザーには何らかの権限が必要となります。
最も深刻な影響を受ける可能性があるのは、hostPathマウントを作成する機能が制限されている環境です。
これは、CVE の悪用によってその制限がバイパスされ、hostPath 機能を使用せずに hostPath のようなアクセスが可能になるためです。
CVE-2021-25741 の修復
CVE-2021-25741 は以下の Kubernetes のバージョンで修正されています:- v1.22.2
- v1.21.5
- v1.20.11
- v1.19.15
したがって、あなたの環境がこの脆弱性の影響を受けている場合は、できるだけ早くKubernetesのバージョンを更新する必要があります。
直ちに修復することができない場合は、他の戦略を採用することでリスクを軽減することができます。ここでは、この脆弱性の影響を軽減し、悪用を検知する方法をご紹介します。
CVE-2021-25741を軽減する方法
公式のKubernetesリポジトリで提案されているように、この脆弱性を緩和するためには、kubeletとkube-apiserverでボリュームサブパス機能を無効にし、既に使用しているポッドを削除することができます。しかし、別の解決策として、OPAをアドミッションコントローラーとして導入することもできます。
アドミッションコントローラーレベルでの軽減
Kubernetesのアドミッションコントローラは、K8s APIへのリクエストをインターセプトして処理し、セマンティックオブジェクトの検証を実施して、作成したいオブジェクトの永続化の前に、リクエストがオーソライズされて認証された後に、リクエストを処理します。そのため、例えば、クラスターのリソースが不足していたり、イメージが安全でなかったり、ポッドやデプロイメントに付与された権限が尊重されていない場合、ACはポッドの実行をブロックすることができます。
Kubernetesのアドミッションコントローラーについては、以下の記事で詳しく紹介しています。
5分でわかるKubernetesのアドミッションコントローラー →
アドミッションコントローラでイメージスキャンを利用し、Kubernetesランタイムを保護→

OPA Gatekeeperをアドミッションポリシーの仕組みとして採用することで、特定の制限をかけるポリシーを作成することができます。
CVE-2021-25741は、ユーザがroot権限でSubpathフィールドを持つコンテナをデプロイすると悪用される可能性があるため、以下のようなポリシーを実施するためにOPAを活用してみることができます:

そこで、root権限と”SubPath”specのコンテナをデプロイすると、以下のように出力されます。
Error from server: error when creating "test-pod.yaml": admission webhook "validating-webhook.openpolicyagent.org" denied the request: Container nginx may exploit CVE-2021-25741.
CVE-2021-25741 の悪用前と悪用後の検知について
このCVEに対する公開されたエクスプロイトがリリースされていないとしても、脆弱なシステムに関連する不審な活動を監視することは重要です。ルートコンテナのデプロイメントや、ホストのファイルシステムへのアクセスがあった場合にアラートを出すことで、侵害の可能性を示すいくつかの行動を検出することができます。これらの不審なイベントを検出するために、Falcoを使用します。FalcoはCNCFのオープンソースプロジェクトで、アプリケーションの予期せぬ動作を検出し、ランタイムでアラートを送信するために使用されます。これは、形式的でシンプルな言語に基づいており、事前に定義されたルールのセットを備えています。そして、これらのデフォルトのルールは、あなたの環境でターゲットを絞った検出を行うために、カスタマイズや拡張が可能です。
ここでは、いくつかの不審な動作を監視するためのデフォルトのFalcoルールを見てみましょう。
Falcoルール:ルートユーザーとしてコンテナを実行
前述したように、rootとしてコンテナを実行すると、悪意のあるユーザーがCVE-2021-25741を利用できる可能性があります。このようなコンテナの存在を検出するには、次のルールを使用できます。- rule: Container Run as Root User desc: Detected container running as root user condition: spawned_process and container and proc.vpid=1 and user.uid=0 and not user_known_run_as_root_container enabled: false output: Container launched with root user privilege (uid=%user.uid container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag) priority: INFO tags: [container, process]
Falcoルール:信頼されていない機密ファイルの読み取り
このルールは、ユーザー/パスワード情報などの機密ファイルの読み取りを検出します。- rule: Read sensitive file untrusted desc: > an attempt to read any sensitive file (e.g. files containing user/password/authentication information). Exceptions are made for known trusted programs. condition: > sensitive_files and open_read and proc_name_exists and not proc.name in (user_mgmt_binaries, userexec_binaries, package_mgmt_binaries, cron_binaries, read_sensitive_file_binaries, shell_binaries, hids_binaries, vpn_binaries, mail_config_binaries, nomachine_binaries, sshkit_script_binaries, in.proftpd, mandb, salt-minion, postgres_mgmt_binaries, google_oslogin_ ) and not cmp_cp_by_passwd and not ansible_running_python and not run_by_qualys and not run_by_chef and not run_by_google_accounts_daemon and not user_read_sensitive_file_conditions and not mandb_postinst and not perl_running_plesk and not perl_running_updmap and not veritas_driver_script and not perl_running_centrifydc and not runuser_reading_pam and not linux_bench_reading_etc_shadow and not user_known_read_sensitive_files_activities and not user_read_sensitive_file_containers output: > Sensitive file opened for reading by non-trusted program (user=%user.name user_loginuid=%user.loginuid program=%proc.name command=%proc.cmdline file=%fd.name parent=%proc.pname gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository) priority: WARNING tags: [filesystem, mitre_credential_access, mitre_discovery]
Falcoルール:プライベートキーまたはパスワードの検索
攻撃者が機密データやファイルを見つけようとしているかどうかを検出できるようにします。- rule: Search Private Keys or Passwords desc: > Detect grep private keys or passwords activity. condition: > (spawned_process and ((grep_commands and private_key_or_password) or (proc.name = "find" and (proc.args contains "id_rsa" or proc.args contains "id_dsa"))) ) output: > Grep private keys or passwords activities found (user=%user.name command=%proc.cmdline container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag) priority: WARNING tags: [process, mitre_credential_access]
Falcoルール:ssh情報の読み取り
このルールは、sshディレクトリ以下の読み取りの試みを検出を試みます。- rule: Read ssh information desc: Any attempt to read files below ssh directories by non-ssh programs condition: > (consider_ssh_reads and (open_read or open_directory) and (user_ssh_directory or fd.name startswith /root/.ssh) and (not proc.name in (ssh_binaries))) output: > ssh-related file/directory read by non-ssh program (user=%user.name command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline) priority: ERROR tags: [filesystem, mitre_discovery] Add a new Falco rule
まとめ
CVE-2021-25741 により、ユーザが root としてコンテナを作成し、 subpathボリュームをマウントすることができれば、 いつでもホストファイルシステムにアクセスすることができます。これは、ノードの機密データの漏洩につながり、潜在的にはノード自体や他のコンテナの危険性にもつながります。この脆弱性の影響を受けているKubernetesクラスターは、ためらわずに新しいバージョンにアップデートしてください。そうしないと、クラスターの整合性やデータが危険にさらされる可能性があります。
CVE-2021-25741の影響を軽減したい場合は、アドミッションコントローラーを使用することができます。そして、侵入後の不審な行動を検出するために、Falcoのデフォルトルールまたはカスタムルールを採用することもできます。
Falcoについてもっと知りたい方は、こちらをご覧ください:
- Falco.orgをご覧ください。
- GitHubでFalcoプロジェクトをチェックしてください。
- Falco コミュニティに参加する。
- Falco Slackでメンテナに会う。
- ツイッターで @falco_org をフォローする。