いまさらながら,情報セキュリティ系論文紹介 Advent Calendar 2016あるいはBitVisor Advent Calendar 2016に投稿されるはずだった文章を供養する.

はじめに

 本稿では,シン,すなわち薄いハイパーバイザ (thin hypervisor) の動向を紹介する.
 薄いハイパーバイザとは,小規模であることを志向したハイパーバイザだ——ということにしておこう.小規模というのは,一部のイベントのみトラップするということだ.メリットとしては,実装・学習コストやオーバーヘッド,TCB (trusted computing base) を削減できる点が挙げられる.
 用語の初出はBitVisorの論文[T. Shinagawa, et al. VEE’09]だが,多くはWindows向けルートキットとして開発されたBlue Pillという手法[J. Rutkowska. Black Hat USA’06]の流れを汲んでいる.そのため,ブート時からゲストを掌握するのではなく,のちほど——あえてchain of trustの構築を放棄して——カーネルドライバとしてロードされるものが一般的である.そのほか,単一のゲストのみ対象とする,セキュリティを意識しているといった傾向が見られる.
 前編となる今回は,3種類の薄いハイパーバイザを見ていく.

ksm

リポジトリ https://github.com/asamy/ksm
形態 カーネルドライバ
仮想化支援機能 Intel VT-x with EPT
サポートしている環境 Windows 7/8/8.1/10, Linux
言語 C, アセンブリ言語
ライセンス GNU GPL v2

 ksmは高速,拡張可能かつ小規模であることを旨としているハイパーバイザで,アンチウイルスソフトウェアやサンドボックスへの利用を意識して開発されている.機能は以下の通り:

  • IDT Shadowing
  • EPT violation #VE (Broadwell以降)
  • EPTP switching VMFUNC (Haswell以降,もしサポートされていなければVMCALLで代替)
  • Builtin Userspace physical memory sandboxer (ビルドオプション)
  • Builtin Introspection engine (ビルドオプション)
  • APIC virtualization (実験的機能)
  • VMX Nesting (実験的機能)

 主なソースコードは以下の通り:

main_nt.c, main_linux.c カーネルドライバのエントリポイント,ioctlディスパッチ
ksm.c ハイパーバイザ全体の初期化
vmx.S, vmx.asm IDTやEPT violationのトラップ,ゲストのレジスタ退避
vcpu.c VMCSの読み書き
exit.c VMExitのハンドラ
um/um.c ユーザーランドのエージェント
sandbox.c サンドボックス機能
introspect.c イントロスペクション機能
epage.c EPTフック機能
mm.c メモリ管理
hotplug.c CPUホットプラグに関する処理

 カーネルドライバをロードし,ユーザーランドのエージェントからioctlを発行,サンドボックス機能またはイントロスペクション機能,EPT機能を呼び出すという流れになっている.詳細はDocumentation/SPEC.rstを参照のこと.

SimpleVisor

リポジトリ https://github.com/ionescu007/SimpleVisor
形態 カーネルドライバ
仮想化支援機能 Intel VT-x with EPT, AMD-V
サポートしている環境 Windows 8/8.1/10, UEFI
言語 C, アセンブリ言語
ライセンス 2 clause BSD

 SimpleVisorは,名前の通り極力シンプルであることをめざしたハイパーバイザだ.全体で1700行程度.開発者はWindows Internalsの著者のひとりで,README.mdにはこう書かれている:

Have you always been curious on how to build a hypervisor? Has Intel’s documentation (the many hundreds of pages) gotten you down? Have the samples you’ve found online just made things more confusing, or required weeks of reading through dozens of thousands of lines and code? If so, SimpleVisor might be the project for you.

 そういうわけで,SimpleVisorはIntel SDM (とくに,ハイパーバイザまわりはVol. 3C) の解読にうんざりした人向けだ.学習にはもってこい.CPUID, INVD, VMX, XSETBVのみトラップするようになっており,ネストには対応していない.しかし,XenやBochsでさえ追いついていない最新の仮想化支援機能にいちはやく追随しようとしている.
 主なソースコードは以下の通り:

nt/shvos.c カーネルドライバのエントリポイント
shv.c VMExit/VMEntryのコールバック関数の登録
shvvp.c コールバック関数の実体,仮想CPUの初期化
shvvmx.c VMCSの初期化
shvvmxhv.c VMExitのハンドラ
shvutil.c GDTの変換

 シンプル.

HyperPlatform

リポジトリ https://github.com/tandasat/HyperPlatform
形態 カーネルドライバ
仮想化支援機能 Intel VT-x with EPT
サポートしている環境 Windows 7/8.1/10
言語 C++, アセンブリ言語
ライセンス MIT

 HyperPlatformは,カーネルランドで動くコード,すなわちWindows向けルートキットやWindowsカーネル自体の解析を目的として開発されているハイパーバイザ.物理メモリと仮想メモリへのアクセス,関数呼び出し,命令単位のコード実行を監視できるようになっている[S. Tanda. REcon’16]
 主なソースコードは以下の通り:

driver.cpp カーネルドライバのエントリポイント,各種コールバック関数の登録
log.cpp ログ出力
global_object.cpp グローバル変数の初期化
performance.cpp パフォーマンス計測
util.cpp PTE_BASEの取得,メモリアドレス変換,VMCALLのラッパなど
power_callback.cpp 電源状態のコールバック関数
hotplug_callback.cpp CPUホットプラグのコールバック関数
vm.cpp 仮想CPUの初期化,VMCSの読み書き
ept.cpp EPTの構成
vmm.cpp 命令のトラップ,VMExitのハンドラ
Arch/x64/x64.asm, Arch/x86/x86.asm VMX命令呼び出しにともなう命令列
kernel_stl.cpp ntoskrnl経由でカーネルドライバからSTLを利用する

 エントリポイントから手続き的に書き下されていて,わかりやすい.ハイパーバイザとしての機能もさることながら,STLを強引に呼び出すハックがかっこいい.
 この拡張例には以下がある:

MemoryMon カーネルランドへのコード挿入を検知する
EopMon マルウェアによる特権昇格攻撃を検知する
DdiMon EPTを用いたAPIフック
GuardMon PatchGuardの挙動解析

 いずれもカーネルドライバのエントリポイントで追加機能を初期化するしくみ.
 やや温め納豆は遠くなりにけり.

おわりに

 いずれもSandy Bridge以降のいまどきの環境であれば動作する.
 卒業研究ではQEMUをベースとしたマルウェア解析環境を開発していたのだけど,やはり速度面に難があるし,このあたりの技術を再検討しないとなー.
 なお,今回取り上げなかったハイパーバイザには以下のようなものがある:

MoRE ルートキット文脈のハイパーバイザ.やや古い
HyperBone HyperPlatformと似た機能をもつ.やや古い
Noah 未踏のアレ.OS X上でLinuxバイナリを動かす.MacBook持ってないので試せないのだわ
Bareflank type 1, 2, ドライバいずれの形態のVMMもサポートしたライブラリ.しかもC++で書ける

 なかでもBareflankがヤバいので後編ではこれを読んでいきます.