ゼロから始めるHyper-Vのアーキテクチャ

はじめに

こんにちは,morimolymolyです.
皆さん,Hyper-V脆弱性報酬プログラムはごぞんじですか?
https://www.microsoft.com/en-us/msrc/bounty-hyper-v

なんとHyper-VのRCE(Remote Code Execution)を発見するだけで$250,000も貰えてしまうのです!!
最近では360 Core Securityの研究者がVMEscapeの脆弱性をみつけて$200,000をゲットしています.

$250,000も貰えたら働かずに毎日ごろごろしていても数年は余裕で持ちますね.
というわけでHyper-V脆弱性を発見する前に,これのアーキテクチャを学ぼうというわけです.

Hypervisor概要

ハイパーバイザにはType-1(Baremetal)とType-2(Host)の2種類あります.
Type-1はハイパーバイザがハードウェア上で直接動作します.
例: XenKVM,BitVisor,Bareflank
Type-2はホストOS上のプロセスとして動作するハイパーバイザです.
例: VirtualBoxVMWareQEMUBochs

Hyper-VはType-1ハイパーバイザにあたります.

Hyper-Vアーキテクチャ概要

f:id:morimolymoly:20190125210041p:plain
上図がHyper-Vアーキテクチャです.
Hyper-VはAttack Surfaceをなるべくへらすために,コード量を最小限にするという設計理念があります.
そのためデバイス仮想化などの機能はHyper-Vには実装していません.
Hyper-VがインストールされたホストOSがデバイス仮想化などのあらゆるサービスを担当します.
そのおかげでHyper-VはホストOSに実装されているデバイスドライバをそのまま利用できます.

Hyper-VにはPartitionという単位でVMが存在します.
Hyper-VがインストールされたホストOSをRoot Partitionと呼び,これは仮想マシンの管理,ゲストのメモリの操作,デバイスエミュレーションサービスの提供,実デバイス操作を行います.
XenでいうとDom0(特権ドメイン)です.

ゲストマシンはPartitionと呼びます.
ゲストマシンは別のPartitionの物理メモリにアクセスできませんし,ハードウェアの直接アクセスができません.
すべてはRoot Partitionと通信してデバイスの操作などを行ってもらいます.
またこの通信は厳格に定義されたインターフェースを通じてのみ行なえます.

このアーキテクチャから分かる通り,セキュリティ野郎が注目するべきはRoot Partitionです.
詳しくは以下の記事を参照.
docs.microsoft.com

Hyper-Vのメモリ

Hyper-Vのメモリは以下のように定義されます.

  • PA(Physical Address) 物理メモリ空間
  • SPA(System Physical Address) RootPartitionの物理メモリ空間
  • SVA(System Virtual Address) RootPartitionの仮想メモリ空間
  • GPA(Guest Physical Address) ゲストの物理メモリ空間
  • GVA(Guest Virtual Address) ゲストの仮想メモリ空間

SPA,SVAは他のハイパーバイザだとHPA(Host Physical Address),HVA(Host Virtual Address)と呼ばれることが多い気がします*1

Root Partitionの役割

f:id:morimolymoly:20190125213147p:plain
上図はRoot Partitionで提供されるサービスの例です.
以下に用語を説明します.

  • VDEV(Virtual Device) Rootのユーザ空間で動くエミュレートまたは準仮想化されたデバイス
  • VSP(Virtualization Service Provider) Rootのカーネル空間でVDEVと協調して動く準仮想化されたデバイス
  • IC(Integration Component) ゲストがアクセスできるRootのユーザ空間で動くコンポーネント

また次のようなサービスが提供されています.

f:id:morimolymoly:20190125220823p:plain

このようにRootPartitionのユーザ空間でホストされるサービスもあれば,RootPartitionのカーネル空間でホストされるサービスもあります.

ゲストのデバイス操作の流れ

f:id:morimolymoly:20190125214731p:plain
上図はゲストがデバイスを操作するときの概要図です.
流れは以下のとおりです.

  1. ゲスト内のVSC(Virtualization Service Client)がvmbusを通じてRoot Partition内のVSPに操作を依頼
  2. VSPがホストOSのデバイスドライバに操作を依頼
  3. デバイスドライバがデバイスを操作

でばストレージ操作のVSPをみてみましょう.
f:id:morimolymoly:20190125221027p:plain


ユーザ空間のVSPも見てみましょう.
f:id:morimolymoly:20190125213849p:plain
VMWPとはVirtual Machine Worker Processの略で仮想マシンごとに用意されるVSPを提供するためのユーザ空間のプロセスです.
この例ではユーザ空間にSMBのサービスであるVSMBを動作させています.

Hyper-VLinuxでの実装

当然このような仮想化支援技術はゲストカーネルに実装されていなければなりません.
Linuxでは以下のようなディレクトリにコードがあるようです.
f:id:morimolymoly:20190125222048p:plain

実際にヘッダファイルを眺めてみるとなかなか面白いです.
github.com

おわりに

簡単でしたが,以上がHyper-Vの基本的なアーキテクチャになります.

予告

次回はHyper-Vリバースエンジニアリング環境を構築します.
また既知の脆弱性についても解説したいと思います*2

*1:ほんま統一してくれ

*2:クローズドソースなので当時のバイナリをビルドして実験できないから解説する意味があるのかわからんが