hypervisors and high-performance fuzzing.
最近学习模糊测试,一些fuzzer借助硬件辅助来提高效率,在找资料时找到了不错的教程,因此学习(CV一下 : Hypervisor 101 in Rust
介绍
Global Cybersecurity Camp 2023 Singapore.
硬件辅助的高性能fuzzer开发,Fuzzing UEFI + 配套练习
课程前提
- 熟悉x86_64架构
- Rust经历有用,但是不是必要的
- 下载相关文档
- Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 3
- AMD64 Architecture Programmer’s Manual Volume 2: System Programming
- 需要一台能支持Intel-VT/AMD-V的电脑
课程目标
- 理解x86_64硬件辅助虚拟化技术
- 熟悉如何将虚拟化技术应用到高性能fuzzing中
动机
Hypervisor
- cool: 云服务的基础,KVM, hyper-V, Xen, Nitro Hypervisor
- 有趣的:
- 主要的安全特性基础, Virtualization Based Security, Secured-core PC
- 安全研究, BitVisor, Intel’s Virtualization Based Hardening
- 方便:
- 系统级隔离: VMware Workstation/Fusion, ACRN, Nitro Hypervisor, Qubes OS
- 系统级监视: Asahi Linux m1n1 Hypervisor, Cuckoo Sandbox, HVMI, kAFL/Nyx, Cheat Engine DBVM, Blue Pill, antivirus-hypervisors
如何完成
我无法创造的,我就不理解。– 费曼
熟悉相关的特性,引用开源的实现
- 看文档 + 看代码,知道如何实现或者CV
可以学习到什么
- 一个可以运行并且fuzz目标的hypervisor
- 跨平台的hypervisor开发和debug
- 为自己的测试扩展功能
- 更好的理解/阅读现存的hypervisor相关实现的代码
- 开发自己的hypervisor
fuzzer设计
灰盒测试,基于变异,边覆盖率引导
快照功能
输入:快照文件,样本库,patch 文件
hypervisor设计
从快照创建一个虚拟机
开始fuzzing
- 向内存注入变异的输入
- VM运行
- 观察/收集可能的BUG
一次迭代后恢复快照
运行尽可能多的VM
使用Rust书写的UEFI
在Bochs/VMware测试,选择裸机型号(应该时选择Intel or AMD?)
不是如下的课程类型
- Rust编程课
- 模糊测试课程
- 可以在这里寻求相关建议: Awesome Fuzzing
- 学习已经存在的软件相关原理
- 比较详细提供代码的细节,一些注释可能过于简单并且可能是不正确的
Demo
应该是作者现场演示,我们可以clone下来代码仓库运行
为什么是Hypervisor
优点
- 不局限于用户态的fuzzing
- 比模拟器块
比较优秀的案例
- Customized hypervisors: KF/x (Xen), kAFL/Nyx (KVM), HyperFuzzer (Hyper-V)
- Using hypervisor API: What The Fuzz, Rewind, Hyperpom, Snapchange
- Original hypervisors: FalkVisor, Barbervisor
UEFI 应用
先于操作系统启动,更快的BIOS
Unified Extensible Firmware Interface Forum
UEFI好处
- 减少系统资源的浪费
- 与操作系统无关的设计和开发环境
- 兼容性好
- 比较容易访问硬件特性
- 文档比较齐全
Rust
为什么选择了rust
- 相对与C/C++来说,更方便的UEFI
- 更多的lib和crate
- 编译器比较严格,减少BUG
- 具有安全意识的工程师,现如今应该选择Rust
hypervisor…
Hypervisor
VMM: Virtual Machine Monitor,和 hypervisor 等价。
两类虚拟化技术:
- 直接运行在硬件上:VMware ESXi, Windows Hyper-V…
- 运行在操作系统上:VMware Workstation,VirtualBox,QEMU…
虚拟化主要分为几大类:
- 计算虚拟化,针对CPU和内存资源虚拟化技术。
- 网络虚拟化,针对网络链路资源虚拟化技术。
- IO虚拟化,针对IO资源虚拟化技术。
- 存储虚拟化,针对磁盘存储资源虚拟化技术。
Intel-VT
虽然说本机电脑时AMD CPU,但是网上Intel-VT内容比较多,有问题也好解决,因此首先学习了部分知识。并且知识都是相通的
因此介绍不会很细😋,毕竟有了源码也不能用😭
不错的学习资源,因为是AMD的CPU,主要还是了解概念以及思路
在Intel® 64 and IA-32 Architectures Software Developer Manuals搜索Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 3
部分一些专业术语
- Intel VT-X: Virtualization Technology for x86
- guest-mode: VMX non-root operation
- host-mode: VMX root operation
- VMX: Virtual-Machine eXtensions
- VMCS: virtual-machine control data structures
- EPT: Extend Page Table
- VT-D: Virtualization Technology for Directed I/O
- GPA: Guest Physical Address
- HPA: Host Physical Address
VMX
VMM host-guest
- VMM通过执行
VMXON
指令进入VMX操作,然后就是类似一个操作系统的启动过程。 VM Entry
:VMM 可以进入 guest。 VMM使用指令VMLAUNCH
和VMRESUME
进行VM切换(可以有很多guest);使用VM Exit
返回host。VM Exit
: 将控制转移到VMM指定的入口点。 VMM可以针对VM Exit
的原因采取适当的操作- 最终,VMM 可能决定自行关闭并离开 VMX 操作。 它通过执行 VMXOFF 指令来实现这一点。
**VMCS 组成:**(VMCS 区域是4 KB(位 11:0 必须为零),必须与 4KB 边界对齐)
- guest state area:在 VM-entry时,处理器的状态信息从guest-state区域中加载。在VM-exit时,处理器的当前状态信息保存在guest-state区域。
- host state area:在VM-exit时,处理器的状态信息从host-state区域中加载。
- VM-execution control field:在进入VM后,处理器的行为由VM-execution控制区域中的字段提供控制。
- VM-EXIT control field:控制处理器在处理VM-exit时的行为,也影响返回VMM后处理器的某些状态。
- VM-ENTRY control field:控制处理器在处理VM-entry时的行为,也决定进入VM后处理器的某些状态。
- VM-EXIT infomation field:记录引起VM-exit事件的原因及相关的明细信息。
一个大致的框架:
- 检查硬件是否支持VMX:
CPUID.1:ECX.VMX[bit 5] = 1
- 启用VMX: 令
CR4.VMXE[bit 13] = 1
,然后通过执行VMXON指令进入VMX操作。 - 检查内核中的VMX支持情况: IA32_FEATURE_CONTROL MSR(MSR 地址 3AH)以查看 锁定位 是否已设置
- 分配VMXON区域: 物理地址并使用分配区域的指针执行VMXON指令,并且查询
MSR_IA32_VMX_BASIC
。(Intel 手册:在执行 VMXON 之前,软件应将 VMCS 修订标识符写入 VMXON 区域。 具体来说,它应该将 31 位 VMCS 修订标识符写入 VMXON 区域前 4 个字节的位 30:0;位 31 应清除为 0。) - 分配VMCS区域: VMPTRLD,处理器中可能同时存在多个 VMCS,但当前只有其中一个处于活动状态,并且 VMLAUNCH、VMREAD、VMRESUME 和 VMWRITE 指令仅在当前 VMCS 上运行。
- 终止VMX并释放我们之前分配的所有内存: VMOFF,并且释放分配的内存(将
VMXON
和VMCS Region
转换为虚拟地址
for example
阅读一下 Intel VT-x based hypervisor aiming to provide a thin VM-exit filtering platform on Windows
一个框架,而不是具体应用。因此可能缺少一点逻辑
DriverEntry
DriverEntry() 调用了 VmInitialization()
1 | // Checks if a VMM can be installed, and so, installs it |
首先检查是否之前安装过
1 | void __cpuid( |
检查CPU和操作系统支持
1 | // Checks if the system supports virtualization |
DriverUnload
调用VmTermination关闭VMM
1 | // Terminates VM |
回调函数,调用VmpStopVm
,使用Cr4 disable VMX
1 | // Stops virtualization through a hypercall and frees all related memory |
UtilVmCall调用AsmVmxCall,最后是如下
1 | ; unsigned char __stdcall AsmVmxCall(_In_ ULONG_PTR hypercall_number, |
VMM && VM
核心功能
VMM是host主要负责的功能,各种行为的handler,处理vmcall
- ring -1 掌控着真正的硬件资源
vmcall/hypercall
- 类似syscall,但是guest OS
- vmcall 会 vmexit 进入host,因此我们需要相应的Exit Handler来处理
VM Exit: 存在一个reason,我们需要进行分别的处理
1 | switch (exit_reason.fields.reason) { |
VM是guest OS,类似一个操作系统的启动流程
1 | // 初始化VM |
EPT
内存虚拟化
Shadow paging,不需要硬件支持
- 直接将 gva -> hpa
- 运行guest时,切换 host CR3 到 shadow paging (hypervisor 拦截 guest 对 CR3的修改
EPT, nested paging, 嵌套页表
- guest操作系统维护一张页表,用于生成guest的物理地址。CR3/EPTP
- 另一个页表由 VMM 维护,它将 guest 的物理地址映射到 host 的物理地址。
Windows 四级页表:9-9-9-9-12 (1)
- PML4T: page map level4 table
- PDPT: page directory pointer table
- PD: page directory
- PT: page table
- entry + offset
Physical Address Extension
: PAE物理地址扩展,处理器功能,使 x86 处理器能够在支持访问超过 4 GB 的物理内存。Page Size Extension
: PSE,是在IA32架构中,实现大于传统的4KB的页面
AMD-V
在AMD Developer Documentation中搜索AMD64 Architecture Programmer’s Manual Volume 2: System Programming
,第15章
因为笔者的机器是AMD CPU,因此主要学习AMD-V。下一篇文章😋
More
不错的项目文章:Hypervisor Development in Rust Part 1 - memN0ps
Cr8:Irql权限等级。CPU的当前优先级。当中断挂起时,将中断向量号的7:4位与CR8进行比较。如果向量更大,它将被服务,否则它将被挂起,直到CR8被设置为较低的值
Windows hype-V 可以开启嵌套虚拟化。
kAFL: 借助Intel PT 和 VT-x 的硬件反馈fuzzer
- PT: Processor tracer, 跟踪信息
Ring -1: Intel VT