abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vbox-hgcm-ssm-cparms
类别: 堆溢出 可达性: 本地(主机)
Oracle VM VirtualBox OSS 7.2.20(f2792cf44)- Oracle
实时 HGCM 仍然拒绝 cParms > 32。但保存状态加载不会。vmmdevR3HgcmLoadState 从 .sav 中读取 cParms,没有 VMMDEV_MAX_HGCM_PARMS 上限,然后用 uint32_t cbCmd 计算命令大小。当 cParms = 0x4000000 时,该乘积回绕为 sizeof(VBOXHGCMCMD)(约 120)。第一次 enmType 存储就已经是越过该块的 4 字节写入。
恢复恶意保存状态的主机用户会使 VM 进程堆溢出。客户机无法通过 Save 植入此问题。
| ID | 暂无 CVE |
| 类别 | 堆溢出(VM 进程越界写入;并非主机内核逃逸) |
| 可达性 | 本地(主机)(UI:R 保存状态 / 快照恢复) |
| CWE | CWE-190、CWE-787 |
| CVSS | 高危:7.8 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| 产品 | VirtualBox OSS |
| 受影响版本 | 7.2.20(f2792cf44f663989818507e36d3db5f978523c5e) |
| 认证 | 主机用户恢复已保存的 VM、快照或 .sav |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1。源码测试框架。不启动 VirtualBox,不解析 .sav。 |
交给操作员一个 VM 文件夹,其保存状态携带一个待处理的 VMMDev HGCM CALL。操作员点击已保存 VM 的“启动”、恢复快照或采用该 .sav。控制台恢复会经由 SSMR3 进入 vmmdevR3LoadExec,再进入 vmmdevR3HgcmLoadState。这就是 UI:R。遗留的入口是解析器,而不是客户机 hypercall。
VMMDev 默认开启。无需 3D。无需 Guest Additions。无需 VRDP。不是 PUEL。
| 步骤 | 位置 | 授予的能力 |
|---|---|---|
| 恢复 | 主机 UI / 对已保存 VM 执行 VBoxManage startvm | 主机用户打开恶意 .sav。这是唯一需要的点击。 |
| SSM 单元 | VMMDev vmmdevR3HgcmLoadState(VMMDevHGCM.cpp:2043-2091) | SSMGetU32 读入 cParms,没有 VMMDEV_MAX_HGCM_PARMS(32)上限。 |
| 分配回绕 | vmmdevR3HgcmCmdAlloc(VMMDevHGCM.cpp:376-381) | uint32_t cbCmd = sizeof(VBOXHGCMCMD) + cParms * (40+24)。cParms = 0x4000000 回绕为约 120。该大小的 RTMemAllocZ 在堆预算内成功。 |
| 首次存储 | 加载循环 paGuestParms[i].enmType(VMMDevHGCM.cpp:2085-2091) | paGuestParms 为 pCmd + sizeof(VBOXHGCMCMD),在回绕后这已经是分配末尾。第一个类型 dword 就是 4 字节越界写入。流只需要 CALL 头加一个参数类型。不需要 6700 万条记录。 |
| 类型 | 来源 | 攻击者获得什么 |
|---|---|---|
| 侦察 | 无 | 溢出字节由 sav 选择。这不是泄漏。堆内容不会返回给文件。 |
| 完整性 | 实验证明 | cParms=0x4000000 将 uint32_t cbCmd 回绕为 120。一次 i=0 的 enmType 存储就会破坏 0xA5 金丝雀。canary0=56424f58 是 VBOX-HGCM-SSM-CPARMS-WITNESS 的 VBOX 前缀。对照 cParms=2 则金丝雀保持完好。 |
| 完整性 | 推断 | 更多由 sav 控制的参数记录(类型 dword 加上 32/64 位或指针描述字段)会在 VirtualBoxVM / VBoxHeadless 中从约 120 字节的 RTMemAllocZ 线性写出。这是 VM 进程中的写原语,与 QEMU 迁移 memcorr 属于同一类。本包未演示指令指针控制。 |
| 可用性 | 推断 | 如果破坏未被转化为受控写入,VBoxVM 会崩溃。该测试装置是金丝雀破坏,而非 VirtualBox 进程崩溃。 |
vmmdevR3HgcmCallAlloc 仍会拒绝 cParms > 32(VMMDevHGCM.cpp:921-926)。客户机无法通过合法的 Save 植入回绕。VMMDEV_MAX_HGCM_PARMS 32,VMMDEV_MAX_HGCM_DATA_SIZE 128MiB)。offValue / cbValue 的 memcpy 只有在 HGCM 客户端在同一 sav 中恢复时才是第二个主机堆写入。这不是本实验。我固定了 VirtualBox/virtualbox 标签 v7.2.20 剥离 f2792cf44。实时 HGCM 是第一个阅读对象,因为 CVE-2013-5892 就属于这一类:参数大小回绕进入 VBOXHGCMCMD。实时路径仍有上限:
ASSERT_GUEST_STMT_RETURN( cParms <= (cbHGCMCall - sizeof(VMMDevHGCMCall)) / cbHGCMParmStruct
&& cParms <= VMMDEV_MAX_HGCM_PARMS,
LogRelMax(50, ("VMMDev: request packet with invalid number of HGCM parameters: ...")),
VERR_INVALID_PARAMETER);
vmmdevR3HgcmLoadState 从 sav 中获取 cParms,并调用同一个分配器:
const uint32_t cbCmd = sizeof(VBOXHGCMCMD) + cParms * (sizeof(VBOXHGCMGUESTPARM) + sizeof(VBOXHGCMSVCPARM))
+ (enmCmdType == VBOXHGCMCMDTYPE_CONNECT ? sizeof(HGCMServiceLocation) : 0);
AssertCompile 对此 pin 的注释将 CMD 放在 120,guestparm 放在 40,svcparm 放在 24。cParms = 0x4000000 使 64 位乘积变为 0x100000000 + 120。存储到 uint32_t 时保留 120。然后:
for (i = 0; i < cParms; ++i)
{
VBOXHGCMGUESTPARM * const pGuestParm = &pCmd->u.call.paGuestParms[i];
rc = pHlp->pfnSSMGetU32(pSSM, &u32);
pGuestParm->enmType = (HGCMFunctionParameterType)u32;
paGuestParms 位于 pCmd + sizeof(VBOXHGCMCMD)。回绕之后,这里就是分配区的末尾。第一次存储就已经越界。
已记录的误区:把活跃的 HGCM 当作残留(它仍然上限为 32);在 harness 中遍历 6700 万次存储(第一个 dword 就是证据);声称客户机可以通过 Save 植入这一点;将 VM 进程堆破坏夸大为宿主内核逃逸;串联公开的 IDispatch。
表演:反向 shell、.sav 解析器、启动 VirtualBox。判定依据是回绕加上对 VBOX-HGCM-SSM-CPARMS-WITNESS 的 canary 破坏。
cd lab
./run.sh
或从包根目录:
python3 vbox-hgcm-ssm-cparms-Abraxas-Labs.py
回环地址 127.0.0.1:19210 上的源测试框架。Compose 项目 vbox-hgcm-ssm-cparms。gadget.c 复制了 pin 大小、uint32_t cbCmd 公式、实时 32 上限,以及一处加载路径上的 enmType 存储。它不启动 VirtualBox,也不解析 .sav。将其绑定到回环地址。
SUCCESS vbox-hgcm-ssm-cparms wrap=yes oob=yes live-cap=32 canary-smashed=yes VBOX-HGCM-SSM-CPARMS-WITNESS
在 vmmdevR3HgcmLoadState 中(以及 v17 之前的 cLinAddrs 路径中),像 vmmdevR3HgcmCallAlloc 已经做的那样,将 SSM 的 cParms 限制在 VMMDEV_MAX_HGCM_PARMS 以内。用 uint64_t / size_t 来确定 cbCmd 的大小,并拒绝回绕。保存状态中的整数并不比活动客户机中的整数更可信。
f2792cf44f663989818507e36d3db5f978523c5e)VMMDevHGCM.cpp 实时上限 · 分配回绕 · SSM 加载VMMDEV_MAX_HGCM_PARMSAbraxas Labs - abraxaslabs.tech - github.com/abraxas - @abraxas_null - [email protected]