VirtualBox 7.2.20 - 高危 - 本地 - 文件写入 - Guest Control copy-from DOTDOT
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vbox-guestctrl-copyfrom-dotdot
类别: 文件写入 触达: 本地(客户机)混淆代理
Oracle VM VirtualBox OSS 7.2.20(f2792cf44)- Oracle
宿主机 IGuestSession::directoryCopyFromGuest / VBoxManage guestcontrol copyfrom 将客户机 DIR_NOTIFY 名称拼接到目标路径上。FsList::AddDirFromGuest 仅跳过精确的 . 和 ..。GuestPath::Translate 采用斜杠风格并折叠双斜杠。BuildDestinationPath 在宿主机指定的目标根上拒绝 RTPATH_PROP_DOTDOT_REFS,而非在逐条目名称上拒绝。
客户机在响应宿主机发起的目录 copy-from 时返回包含 .. 的名称,即以 VBox UID 在目标目录之外写入文件。
| ID | 暂无 CVE |
| 类别 | 文件写入(宿主机目标逃逸) |
| 触达 | 本地(客户机) 混淆代理。宿主机发起复制。客户机命名文件。 |
| CWE | CWE-22 |
| CVSS | 高危:8.2 CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N |
| 产品 | Oracle VM VirtualBox OSS |
| 受影响版本 | 7.2.20(f2792cf44f663989818507e36d3db5f978523c5e) |
| 认证 | Guest Additions(或替代的 HGCM 客户端)以及宿主机发起的目录 copy-from |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1。源码测试框架。不启动 VirtualBox。 |
Guest Control 按设计是宿主机到客户机方向。此遗留问题方向相反:宿主机用户复制客户机目录,客户机以 GUEST_MSG_DIR_NOTIFY / GUEST_DIR_NOTIFYTYPE_READ 名称响应 HOST_MSG_DIR_READ。主程序将这些名称拼接到目标路径并打开它们。
| 方法 | 汇聚点 | 权限 |
|---|---|---|
宿主机 IGuestSession::directoryCopyFromGuest / VBoxManage guestcontrol copyfrom 复制客户机目录。客户机列表名称 ../oracle/VBOX-GUESTCTRL-COPYFROM-DOTDOT-WITNESS。 | CopyFrom::Run 执行 strDstAbs = dest + native_sep + pEntry->strPath,然后 GuestPath::Translate,再 fileCopyFromGuest -> RTFileOpen(RTFILE_O_WRITE | RTFILE_O_OPEN_CREATE)。 | 以 VBox UID 在目标目录之外创建/覆盖宿主机文件。实验目标 /work/vbox-copy。实验写入 /work/oracle/VBOX-GUESTCTRL-COPYFROM-DOTDOT-WITNESS。内容由客户机选择(文件读取通知)。 |
精确的 . 和 .. 目录名会被跳过,不会写入。名称中包含 .. 的文件会被存储并拼接。
| 方法 | 汇聚点 | 权限 |
|---|---|---|
相同的 copy-from。客户机列出 ../../../.ssh/authorized_keys(或 DOS 风格 ..\..\...),而宿主机目标为 /tmp/vbox-copy / C:\Temp\vbox-copy。 | 相同的拼接 + RTFileOpen。 | 创建或覆盖该 UID 可写入的任意宿主机路径。嵌套的 --recursive 名称可进一步遍历。 |
除宿主机已选择的目标目录外无其他信息。客户机无法通过此遗留问题获知额外的宿主机路径。
覆盖 VBox UID 可写入的文件。并非崩溃类遗留问题。CVSS A:N。
fileCopyFromGuest:目标路径完全由宿主指定;客户机仅向该路径提供字节内容。AddDirFromHost 在宿主目录列表中跳过 . / ..。/etc、其他用户的家目录)。HOST_MSG_*。svcCall 仅分发 GUEST_MSG_*。guestCtrlValidateDirEntryEx 中的路径清理器。该检查针对 UTF-8/大小,而非 ..。需要 Guest Additions(或拥有该会话的替代 HGCM 客户端)并且需要宿主发起的目录复制来源。无需 3D。无需 VRDP。非 PUEL。混淆代理:宿主用户从恶意客户机复制。
我固定了 VirtualBox/virtualbox v7.2.20(f2792cf44)。Guest Control 排查 H04。仅限客户机到宿主。共享文件夹 TOCTOU(P0 1037)是不同服务上的同类问题,且在此固定版本上已关闭(词法绝对路径后执行 RTPathStartsWith)。Guest Control 的复制来源拼接的是 DIR_NOTIFY 名称,而非 SHFL 名称。
AddDirFromGuest 从客户机 Name 构建 strEntry,并且仅跳过精确的 . / ..:
Utf8Str strEntry = strPathSub + Utf8Str(bstrName);
switch (enmObjType)
{
case FsObjType_Directory:
{
if ( bstrName.equals(".")
|| bstrName.equals(".."))
{
break;
}
vrc = AddDirFromGuest(strPath, strEntry);
break;
}
case FsObjType_File:
vrc = AddEntryFromGuest(strEntry, fsObjInfo->i_getData());
break;
}
CopyFrom::Run 随后将存储的路径拼接到 dest 上,并且只执行 Translates:
strDstAbs += PATH_STYLE_SEP_STR(PATH_STYLE_NATIVE);
strDstAbs += pEntry->strPath;
vrc = GuestPath::Translate(strDstAbs, mSession->i_getGuestPathStyle(), PATH_STYLE_NATIVE);
/* directoryCreateOnHost / fileCopyFromGuest -> RTFileOpen WRITE|OPEN_CREATE */
GuestPath::BuildDestinationPath 记录了“出于安全原因禁止 Dotdot 目录”,并拒绝 RTPATH_PROP_DOTDOT_REFS。该调用仅作用于目标根目录(GuestSessionImplTasks.cpp:1685-1686)。每个条目的名称从不经过它。Translate(GuestCtrlPrivate.cpp:2129-2208)会更改斜杠风格并合并 //。它不会拒绝 ..。
已记录的误区:将精确的 . / .. 跳过视为路径清理器;假设 Translate 会规范化;将目标根目录检查应用于每个条目;启动 VM 而不是使用源码测试框架;声称这是主机内核逃逸;将单文件 copy-from 目标或 copy-to-guest 视为遗留问题。花架子:反向 shell。判定依据是目标目录之外的见证文件。
cd lab
./run.sh
Compose 项目 vbox-guestctrl-copyfrom-dotdot。回环地址 127.0.0.1:19220。pin v7.2.20 peel f2792cf44 的源 harness:跳过精确的 . / ..,GuestPath::Translate(仅斜杠风格),CopyFrom::Run 目标+分隔符+条目拼接后写入/创建,目标根 BuildDestinationPath 拒绝 DOTDOT。不启动 VirtualBox 或 Guest Additions。将其绑定到回环地址。
SUCCESS vbox-guestctrl-copyfrom-dotdot skip-dot=yes translate-keeps-dotdot=yes escaped-write=yes dest-root-check-unused-per-entry=yes VBOX-GUESTCTRL-COPYFROM-DOTDOT-WITNESS
将每个拼接后的 dest 依次通过 GuestPath::BuildDestinationPath(或 RTPathParse 的 RTPATH_PROP_DOTDOT_REFS,或针对 dest 使用带 RTPATHABS_F_STOP_AT_BASE 的 RTPathAbsEx)处理。拒绝那些组件中包含 .. 的列表名称,而不仅仅是精确的 . 和 ..。保留 dest 根目录检查。仅靠它本身是不够的。
f2792cf44f663989818507e36d3db5f978523c5e)GuestSessionImplTasks.cpp AddDirFromGuest(1195-1235)、dest 根目录 BuildDestinationPath(1685-1686)、CopyFrom::Run 拼接(1806-1849)、fileCopyFromGuest RTFileOpen(684-693)GuestCtrlPrivate.cpp BuildDestinationPath(2067-2104)· Translate(2129-2208)GuestDirectoryImpl.cpp GUEST_DIR_NOTIFYTYPE_READ(523-561)GuestCtrlImplPrivate.h guestCtrlValidateDirEntryEx(1546-1559)