DirtyPipe (CVE-2022-0847) は新たなDirtyCoW?

DirtyPipe

数日前、セキュリティリサーチャーのMax Kellermann(マックス・ケラーマン)氏がDirtyPipeという脆弱性を公表し、CVE-2022-0847として新たに指定されました。この脆弱性はLinuxカーネルに影響を与え、悪用された場合はローカルの攻撃者がroot権限を取得することが可能です。この脆弱性はカーネル5.8以降を搭載したすべてのLinuxベースのシステムに影響を与え、特に悪用するための前提条件もないため、多くのメディアで取り上げられました。

本ブログではDirtyPipe脆弱性の概要と修正方法に関するガイダンスおよび本脆弱性に関する調査の一環として発見した緩和策について説明します。

DirtyPipe脆弱性(CVE-2022-0847)とは?

DirtyPipeはLinux カーネルにおけるローカル権限昇格の脆弱性であり、ローカルの攻撃者は特定の条件下で任意のファイルのパーミッションをバイパスし、任意のデータを書き込むことができます。この脆弱性は Linux カーネルバージョン5.8 以降に影響を与え、最新のカーネルバージョン(5.16.11, 5.15.25, 5.10.102)で修正されています。

本脆弱性は読み取り専用のリソースにデータを書き込むことができるという点で、2016年に発見されたDirtyCoW脆弱性に類似しています。ただし、DirtyPipeでは攻撃者が読み取り専用のファイルに書き込むことができるのに対し、DirtyCoWでは読み取り専用のメモリマップに書き込むことができる点が大きな違いです。

CVE-2022-0847の技術的概要

CVE-2022-0847 はsplice()システムコールを使用している際に発見されました。基本的に、このシステムコールはファイル記述子とパイプの間でデータを移動しますが、データがユーザーモード/カーネルモードアドレス空間の境界を越える必要がないため、マシンのパフォーマンスを向上させることができます。通常、ファイルを送信する際にはメモリページ(通常4KBの大きさ)がページキャッシュと呼ばれるメモリ管理された空間にコピーされます。そこからデータはユーザ空間にコピーされ、不要なハードディスクI/Oを避けるためにキャッシュに残ります。

ファイルをパイプに読み込む際(splice()システムコールを使用)、同時に任意のデータをパイプに書き込むと、このバグによる誤った状態により、ファイルが使用しているのと同じページキャッシュにデータが残ってしまい、その結果、ファイルが読み取り専用モード (O_RDONLY) で開かれたとしても、パイプに書き込んだデータはファイルに残ってしまいます。詳細については技術的な記述をご参照ください。

この脆弱性を利用することで、以下の条件下でローカルの攻撃者はパーミッションに関係なく任意のファイルに任意のデータを書き込めます。

  1. 攻撃者が読み取ることができるファイルであること
  2. 上書きされたオフセットがページ境界であってはならない(ページサイズは通常4096)
  3. ページ境界を越えて書き込むことはできない
  4. ファイルサイズを変更することはできない

誰がCVE-2022-0847の影響を受けるのか?

CVE-2022-0847は5.8から5.16.11, 5.15.25, 5.10.102より前のバージョンのLinux カーネルに影響を及ぼします。この問題はLinux カーネルの一般的に使用されるコードに関係するため、デフォルト設定ではUbuntuやDebianを含むすべての主要なLinux ディストリビューションに影響を及ぼします。

クラウドサービスのプロバイターはCVE-2022-0847の影響を受けるのか?

現在、主要なクラウドプロバイダーはすべて影響を受けており、AKS、EKS、GCPからプロビジョニングされたインスタンスで脆弱性を悪用される可能性があります。

CVE-2022-0847のインパクトは?

この脆弱性を利用した場合、例えばローカル攻撃者は「“/etc/passwd”」のような機密ファイルを書き換えたり、ELFを悪意のあるコードで上書きして任意のsetuid-root binaryをハイジャックするなど、簡単にルート権限を獲得できます。

CVE-2022-0847はコンテナから取得するために使用できるか?

通常、コンテナ内にマウントされたファイルはホストに保存されないため、通常の条件下では本脆弱性によって攻撃者がコンテナから取得することはできないと考えられます。しかし、機密性の高いホストファイルがコンテナ内に読み取り専用でマウントされている場合、本脆弱性により、コンテナ内の攻撃者がファイルを変更し、コンテナから取得できる可能性があります(これらのファイルの使用状況に依存します)。

CVE-2022-0847の修正方法

Linux kernelを5.16.11, 5.15.25, 5.10.102以降のいずれかのバージョンにアップグレードすることを推奨します。また、それが不可能な場合はこちらのパッチを用いてLinuxカーネルにパッチを適用することを強く推奨します。

ディストリビューション 脆弱性バージョン 修正バージョン
Ubuntu 20.04.2以降 パッチなし
Debian Bullseye 5.10.84-1 Bullseye 5.10.92-2
bookwormとsid 5.16.11-1
Red Hat 影響なし* パッチなし

なお、RHEL8(Linux カーネル 4.18 を使用)はCVE-2022-0847(初期化の欠落)の根本的な問題がバージョン 4.9 からカーネルに存在しているため、Red Hatにより影響を受けると書かれています。しかし、現在知られている唯一の悪用経路 (PIPE_BUF_FLAG_CAN_MERGEの使用)はバージョン 5.8 で導入されました。そのため、4.9から5.7までのLinuxカーネルバージョンは将来的に別途悪用される可能性がありますが、現状はこれらのバージョンでは機能しません。

CVE-2022-0847 に対して、どのような緩和策があるのか?

カーネルのアップグレードやパッチ適用が不可能な場合、spliceシステムコールを無効にするseccompプロファイルを導入することができます。これは一部のソフトウェアパッケージで問題を引き起こすかもしれませんが、このシステムコールの使用は比較的まれであるため、通常、このシステムコールをブロックしても、正当なアプリケーションに影響を与えることはありません。

具体的にはDockerコンテナを保護するために、Dockerのデフォルトのseccompプロファイルを変更し、許可されるシステムコールのリストからspliceを削除することが可能です。

List of allowed syscalls

カスタムseccompプロファイルを作成した後、新しいDockerコンテナに適用する場合、以下を実行します。

docker run --security-opt seccomp=/path/to/seccomp/profile.json …

JFrogセキュリティリサーチ最新情報

JFrogセキュリティリサーチチームからの最新の発見や技術的な更新はセキュリティリサーチブログの記事やTwitterの@JFrogSecurityでフォローしてください。

JFrog Xrayで脆弱性のあるバージョンを検出

新しい脆弱性や脅威を明らかにするだけでなく、JFrogはJFrog Xray SCA ツールによる自動セキュリティスキャンにり、開発者やセキュリティチームが自社のソフトウェアの最新の関連情報に容易にアクセスできます。