【前編】Sandbox による ESXi の保護: VM Sandboxing in ESXi 6.5

Share on:

Table of contents

本記事は vExperts Advent Calendar 2022 の8日目の担当です。

はじめに

ESXi には SELinux や AppArmor に似た強制アクセス制御の機能が実装されており、最新の ESXi 8.0 では各種プロセスからアクセスできるリソースや実行可能な処理を最小限に絞っています。

これにより、悪意のあるユーザーが脆弱性を攻撃してプロセスを乗っ取っても、乗っ取られたプロセスを利用した攻撃の影響範囲が最小限に絞られることになります。この強制アクセス制御の機能は vSphere 6.5 や 8.0 の What’s new では Sandbox と呼称されています。

以下は vSphere 6.5 で実装された VM Sandboxing のイメージ図です。ゲストOS内で何らかの仮想マシンの脆弱性を突き、VMX プロセスの権限でコードが実行可能になった場合でも、Sandbox の範囲外にアクセスする処理は許可されません。これにより乗っ取られた仮想マシンプロセスからホストや他の仮想マシンが保護されます。

今まではこの Sandbox は What’s new に概要が2~3行あるのみで具体的な公開情報がなかなか見当たりませんでした。しかし、ESXi 8.0 のリリースとともに Sandbox に関する KB がいくつか公開され、そこから Sandbox が間接的に関わっていた過去の KB もいくつか見つけられました。

今回はそれらの KB から確認した情報や簡単なコマンドで確認できる内容をベースに ESXi の Sandbox がどういった仕様なのか見ていきます。本記事では前編として Sandbox を実装する ESXi の仕組みと ESXi 6.5 の VM Sandboxing の概要を、後編の記事では ESXi 8.0 の新機能である Daemon Sandboxing の概要を見ていきます。

vSphere の運用で意識することは限りなくゼロに近いと言っても過言でないと思っていますが、悪意のあるユーザーによるどういった攻撃ベクトルがあるのか/どう役立つのかの理解、トラブルシューティング等のための ESXi のアーキテクチャや仕組みの理解に役立てば幸いです。

注意事項

What’s new の2~3行以外に体系的にまとまった情報がないため好奇心で調べてみましたが、ESXi の中でもだいぶマニアックな部類の内容です。私の説明の拙さから分かりにくい部分もあると思いますがご容赦ください(SELinux や AppArmor を触った経験があると理解の助けになるかもしれません)。

また、Sandbox や関連する機能の公開情報は限られており、2022/12 現在、体系的にまとまった公開情報は見当たりません。本記事は可能な限り公開情報や簡単な検証で確認できる情報をベースに構成するよう努めていますが、推測の範疇に留まる内容も多く含まれるため、正確性は保証できませんので予めご承知おきください。VMware社のドキュメントやナレッジベースに無いような情報はあくまでも参考程度の情報と考えていただければと思います。

加えて、基本的に Sandbox によるアクセス制御は既定の状態で正常動作するようにVMware社の評価が十分に行われているはずです。このため、明確に Sandbox に起因する問題のトラブルシューティングを目的として、かつ KB や製品サポートからの指示がない限り、Sandbox 関連の設定はデフォルトを維持することを強く推奨します。

ESXi における強制アクセス制御: secpolicy (仮称)

ESXi にはプロセスからリソースへのアクセスを制御するための強制アクセス制御が VMkernel 内のサブシステムとして実装されています。この強制アクセス制御の詳細や体系的な情報はVMware社からの公開情報がなく正式名称も不明ですが、本記事では便宜上、esxcli コマンドの名前空間に合わせて secpolicy と呼称します。

1# esxcli system --help
2Usage: esxcli system {cmd} [cmd options]
3
4Available Namespaces:
5    ...
6  secpolicy             Options related to VMkernel access control subsystem. These options are typically in place for specific workarounds or debugging. These commands should be used at the direction of VMware Support Engineers.

以下の資料は VMSA-2018-0027 の脆弱性を発見・報告したセキュリティ研究者が執筆した論文です。この論文中では vSphere 6.5 の VM Sandboxing の説明の一環として「Ubuntu の AppArmor ライクな強制アクセス制御」 「事前定義済みのポリシーに基づきシステムコール/ソケット/ファイルへのアクセスを制御する」と紹介されています。

Breaking Turtles All the Way Down: An Exploitation Chain to Break out of VMware ESXi | USENIX

Sandboxing.
Since vSphere 6.5, VMware ESXi has introduced a mandatory access control (MAC), similar to Ubuntu’s AppArmor, to enforce the security policy of guest VMs. (VMware vSphere is a commercial name for the whole VMware Suite, and ESXi is the hypervisor server of vSphere.) The sandbox maintains some pre-defined policies that contain some white lists of allowed syscalls, sockets, and file permissions in the file system (VMFS).

歴史的に secpolicy がいつから存在しているか調べてみたところ、2012 年の時点で海外の vExpert の方(ESXi-Customizer-PS の開発者の方)の個人ブログで言及されていました。

VMware Front Experience: A Daemon’s VIB - Part 3 (Building a software package for VMware ESXi)

The VMkernel Access Control System (SecPolicy)
The difference is that the FTP daemon is now (after having installed it) a part of the system image. And as such it is under control of the VMkernel access security system. This system is managed by the secpolicytools command and configured by the files that you find in the directory /etc/vmware/secpolicy.

その他にも色々と調べたところ、コミュニティ上に ESXi 3.5 Update 5 時点で secpolicy 自体は実装済みと思われる形跡がありました。現在と同等の機能が実装されていたかは不明ですが、secpolicy 自体はかなり初期の ESXi から存在していたようです1

上述の通り vSphere 6.5 で VM Sandboxing が追加されていることから、比較のため、まずはそれより前のバージョンである ESXi 6.0 を対象として secpolicy の中身がどうなっているかを見ていきます。

ESXi 6.0 での secpolicy の中身を見てみる

secpolicy の管理には secpolicytools コマンドを使うようです。ヘルプを見てみると -d オプションでポリシーが一覧できるようです。

1# secpolicytools -h
2Usage: secpolicytools <options>
3     ...
4   -d|--display-policy                       Display the current policy.
5     ...

secpolicytools -d コマンドを実行するとアクセス制御のセットとおぼしき「ドメイン」が一覧で表示されました。公開情報がないので詳細は明確には分かりませんが、名前など個々の単語からファイルやソケットなどの各種リソースへのアクセスや実行可能な処理の許可/拒否が定義されていることが読み取れます。

 1# secpolicytools -d
 2---------------------------------------------------------------
 3Domain Name: appDom  Kernel Id: 2  Enforcement Level: enforcing
 4---------------------------------------------------------------
 5-a appObj file_create grant
 6-a appObj file_delete grant
 7-a appObj file_exec grant
 8  ...
 9-c inet_dgram_socket_create grant
10  ...
11-s genericSys grant
12
13  ...

grep してみると ESXi 6.0 のデフォルトでは7個ほどのドメインが存在していました。

1# secpolicytools -d | grep Domain
2Domain Name: appDom  Kernel Id: 2  Enforcement Level: enforcing
3Domain Name: ioFilterDom  Kernel Id: 3  Enforcement Level: enforcing
4Domain Name: pluginDom  Kernel Id: 4  Enforcement Level: enforcing
5Domain Name: pluginFrameworkDom  Kernel Id: 5  Enforcement Level: enforcing
6Domain Name: regularVMDom  Kernel Id: 1  Enforcement Level: enforcing
7Domain Name: superDom  Kernel Id: 0  Enforcement Level: enforcing
8Domain Name: swMgmtDom  Kernel Id: 6  Enforcement Level: enforcing

強制アクセス制御といえば SELinux があります。SELinux の Type Enforcement ではプロセスに割り当てるタイプをドメインと呼び、上述の secpolicy のドメインも同じような意味と推測されます。このため、プロセス情報を表示する ps コマンドのヘルプを見ると、プロセスのドメインを表示する -Z オプションの存在が確認できます。

1# ps -h
2      ...
3    -Z           Display the security domain
4      ...

KB2107172 の ps コマンドに -Z オプションを追加してみると、ESXi 6.0 では以下のように表示されます。実行結果の※印の値 (SecurityDomain 列) がプロセスのドメインIDと推測できます。

 1# ps -TcjstvZ
 2WID    CID    WorldName                      GID   Type    State   Wait    CPU   Time          SecurityDomain  Command
 334106  34106  sh                             34106  User,Native    WAIT    UWAIT   0,1       0.3288    0※             /bin/sh /sbin/watchdog.sh -s hostd hostd ++min=0,swapscope=system,group=hostd /etc/vmware/hostd/config.xml
 434124  34124  hostd-worker                   34124  User,Native    WAIT    UFUTEX  0,1       2.288095  0※             hostd /etc/vmware/hostd/config.xml
 5  ...
 634989  34989  cimslp                         34989  User,Native    WAIT    USLP    0,1       0.390056  5※             /bin/cimslp
 734994  34994  sfcb-ProviderMa                34994  User,Native    WAIT    USOCKR  0,1       0.280823  5※             /bin/sfcbd -d -l 3
 8  ...
 935413  35413  vmx                            35413  User,Native    WAIT    UPOL    0,1       0.820796  1※             /bin/vmx -s sched.group=host/user -# product=2;name=VMware ESX;version=6.0.0;buildnumber=3029758;licensename=VMware ESX Server;licenseversion=6.0; -@ transport=3;msgs=ui /vmfs/volumes/63419cd9-6ffb16a0-6555-0050569bd54d/TestVM/TestVM.vmx
1035414  0      vmm0:TestVM                    35413  VMM    WAIT    IDLE    0,1      16.709134  1※

secpolicytools のドメインと ID を比較してみると、多くのプロセスは superDom、仮想マシンに関連する vmx / vmm / mks 等のプロセスは regularVMDom、sfcbd や OpenSLP のような CIM 関連のプロセスは pluginDom や pluginFrameworkDom、といったドメインで実行されていることが確認できます。superDom は恐らく特権レベルのドメインと思われます。

これらの内容から、リソースへのアクセス制御ポリシーをドメインとして定義し、プロセスに割り当てることで詳細なアクセス制御を行っていることが推測できます。

なお、プロセスが secpolicy に違反するとどうなるか調べたところ KB2129825 や KB1037405 に関連する公開情報がありました。詳細は次の VM Sandboxing の紹介で合わせて説明しますが、違反したプロセスは停止(クラッシュ)に至るようです。

vSphere 6.5 の新機能: VM Sandboxing

vSphere 6.5 では ESXi の新機能として VM Sandboxing が実装されました。

An update to the ESXi architecture further ensures the safety and security of VMs by running them in an operational “sandbox” with strict controls as to hypervisor capabilities available to them. No configuration is necessary for VM sandboxing.

これは What’s new の説明にも記載の通り、個々の仮想マシンのプロセス (VMX, VMM, MKS, etc…) が持つ権限を最小限の範囲に絞り、必要以上のハイパーバイザー機能にはアクセスさせないよう制御する機能となっています。

一例として、悪意のあるユーザーがゲストOS内から仮想マシンの何らかの脆弱性を突き、VMX プロセスとしてコードを実行できるようになったケースを考えます。この場合、VMX プロセス自体が可能な操作が VM Sandboxing によって制限されているため、任意のコードではなく VMX が許可された最小限の範囲に閉じたコードしか実行できません。これによりその他の仮想マシンや ESXi は乗っ取られた仮想マシンから保護されることになります。

内部的には secpolicy のドメインを仮想マシンごとに適用しているようです。ps コマンドで見てみると、ESXi 6.0 では regularVMDom で共通でしたが、ESXi 6.5 では仮想マシンごとに異なるドメインが割り当てられていることが分かります。

1# ps -TcjstvZ
2WID    CID    WorldName                            GID   Type    State   Wait    CPU   Time          SecurityDomain  Command
367857  67857  vmx                                  67857  User    WAIT    UPOL    0,1       0.77909   7※             /bin/vmx -s sched.group=host/user -# product=2;name=VMware ESX;version=6.5.0;buildnumber=4564106;licensename=VMware ESX Server;licenseversion=6.0; -@ transport=3;msgs=ui /vmfs/volumes/6378f864-f5e9b610-54ce-0050569b9693/Test/Test.vmx
467858  0      vmm0:Test                            67857  VMM    READY   NONE    0,1       3.841906  7※
5
667877  67877  vmx                                  67877  User    WAIT    UPOL    0,1       0.72843   8※             /bin/vmx -s sched.group=host/user -# product=2;name=VMware ESX;version=6.5.0;buildnumber=4564106;licensename=VMware ESX Server;licenseversion=6.0; -@ transport=3;msgs=ui /vmfs/volumes/6378f864-f5e9b610-54ce-0050569b9693/aaa/aaa.vmx
767878  0      vmm0:aaa                             67877  VMM    WAIT    IDLE    0,1       3.408468  8※

secpolicytools -d を見てみると、仮想マシンディレクトリに対する read や write のパーミッションらしき行が確認できます。仮想マシンのファイルへのアクセス権限をディレクトリパスで指定しているように見えるため、仮想マシンに関係しないファイルにはアクセスできないようになっていると推測できます。

 1# secpolicytools -d
 2-------------------------------------------------------------
 3Domain Name: hostd1 Domain ID :7 Enforcement Level: enforcing
 4-------------------------------------------------------------
 5  ...
 6-r /vmfs/volumes/6378f864-f5e9b610-54ce-0050569b9693/Test rw
 7  ...
 8
 9-------------------------------------------------------------
10Domain Name: hostd2 Domain ID :8 Enforcement Level: enforcing
11-------------------------------------------------------------
12  ...
13-r /vmfs/volumes/6378f864-f5e9b610-54ce-0050569b9693/aaa rw
14  ...

なお、個々の仮想マシンに割り当てられた hostdX というドメインは仮想マシンのパワーオフ時には存在せず、仮想マシンのパワーオンの際に動的に生成されているようです。/etc/vmware/secpolicy 配下にも同名のファイルは見当たりませんでした。

ユーザーの作業で VM Sandboxing に違反する事例

先ほど、プロセスが secpolicy のアクセス制御に違反した場合の例として KB1037405 を挙げていました。

/productLocker は ESXi にバンドルされた VMware Tools の配置場所(既定は Locker パーティション)へのシンボリックリンクです。何らかの理由でターゲットのディレクトリが消失した場合は KB1037405 の手順でデータストア上のディレクトリに必要なファイルを抽出して /productLocker を再作成する必要があります。

 1# esxcli storage filesystem list
 2Mount Point                                        Volume Name  UUID                                 Mounted  Type            Size          Free
 3-------------------------------------------------  -----------  -----------------------------------  -------  ------  ------------  ------------
 4/vmfs/volumes/6378f864-f5e9b610-54ce-0050569b9693  datastore1   6378f864-f5e9b610-54ce-0050569b9693     true  VMFS-5  142270791680  138636427264
 5/vmfs/volumes/6378f85e-607034b2-49d9-0050569b9693               6378f85e-607034b2-49d9-0050569b9693     true  vfat       299712512      83927040
 6
 7# readlink -f /productLocker
 8/vmfs/volumes/6378f85e-607034b2-49d9-0050569b9693/packages/6.5.0
 9              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10              # 既定は Locker パーティションのファイルシステム UUID
11
12  ~KB1037405 の Resolution を実施~
13
14# readlink -f /productLocker
15/vmfs/volumes/6378f864-f5e9b610-54ce-0050569b9693/packages/6.5.0
16              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17              # KB1037405 の実施後はデータストアの UUID に変わる

この場合、/productLocker のターゲットが Locker パーティションのパスからデータストア上のパスに変わり、実行中の仮想マシンのドメインが許可する /productLocker の絶対パスとの不整合が発生します。

 1# secpolicytools -d
 2  ...
 3-------------------------------------------------------------
 4Domain Name: hostd1 Domain ID :7 Enforcement Level: enforcing
 5-------------------------------------------------------------
 6  ...
 7-r /vmfs/volumes/6378f85e-607034b2-49d9-0050569b9693/packages/6.5.0 r
 8                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 9                 # /productLocker のシンボリックリンクを再作成しただけでは
10                 # 仮想マシンのドメインは更新されず /productLocker の実体と不整合が発生

この状態で仮想マシンが /productLocker にアクセスを試みた場合、許可されていないファイルへのアクセスになるためセキュリティ違反とみなされ、仮想マシンプロセスの停止に至るようです。

Note: If the host is running with ESXi 6.5 up to the version before 6.5U1, not putting the host in maintenance mode may lead to VM crashes due to the host security policy when VMs try to access the new /productLocker link.

ESXi 6.5 Update 1 provides a tool ‘updateProductLockerPolicy’ to avoid the need for putting host in maintenance mode. …

このため、/productLocker の再作成の前後でホストをメンテナンスモードに切り替え/復帰してから仮想マシンをパワーオンする、または ESXi 6.5 U1 以降では updateProductLockerPolicy コマンドを使用することで、ドメインに含まれる /productLocker のターゲットのアクセス制御の更新が必要となります。

以下の KB2129825 は ESXi にバンドルされる VMware Tools のイメージのバージョンを更新/変更する手順です。この手順で /productLocker のターゲットを変える場合にも同様に仮想マシンのドメインのアクセス制御の更新が必要となります。

これらのケースを見ると、VM Sandboxing の実装によりセキュリティが向上しますが、トラブルシューティング中に VM Sandboxing が関連するとオペレーションの複雑さが増大することが分かります。ただし、通常運用時に VM Sandboxing を意識する必要はなく、いずれも作業内容そのものはそれほど難しいものでもありません。この程度のトレードオフであれば、許容するのに十分なメリットがある印象です。

VM Sandboxing の不具合による脆弱性

VM Sandboxing は上述の通り仮想マシンプロセスが乗っ取られてもホストを可能な限り侵害しないようにアクセスを制御してくれます。

しかし、VM Sandboxing も人間が作っている以上は完璧なものではありません。プロセスによる許可・制限すべきアクセスを全て網羅することは難しく、時にはアクセス制限の漏れが脆弱性として発現することもあります。

直近では VMSA-2022-0004 が一例として挙げられます。このアドバイザリでは5つの脆弱性が挙げられていますが、関連するものは以下の 3a ~ 3d の4つです。

  • 3a. Use-after-free vulnerability in XHCI USB controller (CVE-2021-22040)
  • 3b. Double-fetch vulnerability in UHCI USB controller (CVE-2021-22041)
  • 3c. ESXi settingsd unauthorized access vulnerability (CVE-2021-22042)
  • 3d. ESXi settingsd TOCTOU vulnerability (CVE-2021-22043)

これらのうち 3c は VM Sandboxing のアクセス制御の漏れにより仮想マシンプロセスがシステムのプロセスにアクセス出来てしまう脆弱性です。以下はこれらの脆弱性と VM Sandboxing がどのように関係するのか見ていきます。

VMSA-2022-0004 の各脆弱性の概要

CVE-2021-22040 / CVE-2021-22041 は仮想マシンの USB コントローラの不具合を突いて VMX プロセスを乗っ取る脆弱性です。両脆弱性は USB のバージョン(XHCI or UHCI)や攻撃手法に差異はあるものの、VMX を乗っ取ってコードを実行する点は同様です。

Known Attack Vectors
A malicious actor with local administrative privileges on a virtual machine may exploit this issue to execute code as the virtual machine’s VMX process running on the host.

CVE-2021-22040 / CVE-2021-22041 の脆弱性のみであれば、VM Sandboxing により VMX の権限に閉じた範囲の処理のみが実行できることになります(とはいえこれだけでも危ないです)。

ESXi 7.0 には CVE-2021-22042 の脆弱性が存在することにより、より強い権限を持つ settingsd プロセス2への VMX プロセスからのアクセス経路が存在します。VM Sandboxing のアクセス制御の不備3により、VMX が settingsd を操作するためのチケットにアクセス可能になっていたようです。

Description
VMware ESXi contains an unauthorized access vulnerability due to VMX having access to settingsd authorization tickets. …

Known Attack Vectors
A malicious actor with privileges within the VMX process only, may be able to access settingsd service running as a high privileged user.

CVE-2021-22043 は、settingsd の一時ファイルの処理の不具合によって、任意のファイルに書き込みを行って権限昇格に繋げることが可能となる脆弱性です。

Description
VMware ESXi contains a TOCTOU (Time-of-check Time-of-use) vulnerability that exists in the way temporary files are handled. …

Known Attack Vectors
A malicious actor with access to settingsd, may exploit this issue to escalate their privileges by writing arbitrary files.

以上の一連の脆弱性を見ていくと、仮想 USB コントローラの脆弱性で乗っ取った VMX から VM Sandboxing の脆弱性で settingsd にアクセスし、その settingd の脆弱性で最終的にホストの権限を奪取する、といった流れが見えてきます4

VMSA-2022-0004 は複数の脆弱性を組み合わせてチェーンが構成されています。もし Sandbox のアクセス制御に問題がなければ VMX プロセスからのアクセス経路がないため、ホストの権限の奪取までには至らず、脆弱性のチェーンを断ち切ることができます。

To be continued…

本記事では VM Sandboxing とそのバックエンドである secpolicy の概要を見ていきました。

vSphere 6.5 で VM Sandboxing が実装されたことで、仮想マシンプロセスが乗っ取られた場合の影響範囲が最小限に抑えられるようになりました。しかし、人間が作っている以上は Sandbox も完璧ではありませんので、VMSA-2022-0004 のように Sandbox をバイパスする脆弱性が見つかる可能性はあり得ることです。一般的な脆弱性対応と同様に修正パッチが公開された場合は早急に適用しましょう。

後編の記事では ESXi 8.0 で実装された Daemon Sandboxing の概要を見ていきます。


  1. ESXi 4.x までは secpolicytools ではなく esxcfg-secpolicy というコマンドが管理に使われていたようです。secpolicytools は ESXi 5.0 で追加された旨が中の人のブログで言及されていました。 ↩︎

  2. settingsd は vSphere 7.0 で追加された vLCM 関連の ESXi 側のサービスです。KB82795 などに少し言及があります。 ↩︎

  3. VMSA-2022-0004: Questions & Answers だと「VM Escape を防ぐための Sandbox は ESXi 7.0 で導入された。ESXi 6.7 以前に Sandbox はない」との記載があります。本記事でも記載した公式の What’s new で公開されているように VM Sandboxing は ESXi 6.5 から存在しており、FAQ に矛盾があるように見えていますが詳細は不明でした。修正後の ESXi で secpolicytools -d 等を漁った限りでは、/var/run/vmware/tickets へのアクセス制御など関連しそうな修正が仮想マシンのドメインに加えられているように見えていますが、知っても実運用で役立ちそうにないのでこれ以上は調べていません。 ↩︎

  4. このようなゲストOSからホスト側のシステムにアクセスする攻撃は一般には Virtual Machine Escape (VM Escape) と呼ばれています。 ↩︎