这没问题:Vagrant虚拟机可访问整个宿主机文件系统 - phoenhex团队
2018年3月25日
作者:niklasb
去年九月在使用VirtualBox时,我注意到一些异常行为,最初以为这是VirtualBox中一个相当严重的安全漏洞:在使用Vagrant启动的虚拟机内运行非特权程序时,它可以获得对宿主机整个文件系统的读写访问权限。结果发现这实际上不是VirtualBox的bug,而更多是Vagrant的错误配置。
这个问题应该被认为是公开已知的,但仍然存在,尽管Vagrant现在会在每个宿主机上精确显示一次警告。如果你在Vagrant虚拟机内运行不受信任的代码,应该显式设置VAGRANT_DISABLE_VBOXSYMLINKCREATE
环境变量,例如通过在.profile/.zprofile
中添加:
|
|
我在34C3 CTF中以此作为babyvm挑战题,简化版本在3小时内被解决,困难版本也在比赛48小时内被一支队伍解决(向DragonSector的valis致敬!)。因此本文一石二鸟,既是对Vagrant的温和吐槽,也是两个CTF挑战的解题报告。
问题描述
Vagrant默认为其创建的每个同步文件夹设置SharedFoldersEnableSymlinksCreate
标志。这包括vagrant共享,除非通过在Vagrantfile中添加config.vm.synced_folder ".", "vagrant", disabled: true
显式禁用,否则默认在每个Vagrant虚拟机中启用。
VirtualBox文档对此标志有以下说明:
出于安全原因,默认不允许客户操作系统创建符号链接。如果您信任客户操作系统不会滥用此功能,可以通过以下方式为"sharename"启用符号链接创建:
1
VBoxManage setextradata "VM name" VBoxInternal2/SharedFoldersEnableSymlinksCreate/sharename 1
虽然文档关于启用此标志的含义可以更清晰,但Vagrant显然假设所有虚拟机都是隐式可信的,这至少违背了我的个人直觉:在我的心智模型中,Vagrant只是所用hypervisor的一个非常薄的包装器,不应增加额外的攻击面。简而言之,我期望它能提供与VirtualBox相同的安全保证。
从非特权上下文访问共享文件夹
VirtualBox中的共享文件夹通过HGCM服务(Host-Guest Communication Manager的缩写)实现。HGCM涉及一个相当简单的RPC协议,客户机可以通过该协议向hypervisor进行函数调用。VirtualBox的其他几个也需要客户机协作的功能也通过此机制实现,例如剪贴板共享、拖放和3D加速。
为了发起HGCM调用,例如读取或写入共享文件夹内的文件,或将数据放入剪贴板,必须向通过PCI暴露给每个VM的特殊VMM(虚拟机监控器)设备发出自定义请求。这通常需要内核权限。
但是,如果安装了VirtualBox客户增强功能,可以通过VBoxGuest驱动程序发出请求,该驱动程序以Windows上的VBoxGuest设备和Linux上的/dev/vboxuser
设备形式暴露给"世界"——即客户机中的非特权进程。由于Vagrant的同步文件夹使用共享文件夹功能,Vagrant虚拟机通常会预先安装VirtualBox客户增强功能。
快速说明:在我报告CVE-2018-2693(通过Linux上的/dev/vboxuser
在客户机中的权限提升+拒绝服务)后,Oracle在VirtualBox客户增强功能的5.2.6版本中完全禁用了该设备。然而,这在5.2.7测试版和5.2.8稳定版中很快被恢复,因为事实证明他们的某些功能依赖于此设备的可用性,这一事实在测试过程中 somehow 被忽略了……
使用符号链接访问宿主机文件系统
SharedFolders HGCM服务的核心由VirtualBox源文件src/VBox/HostServices/SharedFolders/service.cpp
中的函数svcCall
实现。对我们目的相关的HGCM函数有:
SHFL_FN_CREATE
:在共享文件夹中打开文件SHFL_FN_{READ,WRITE}
:读取/写入通过SHFL_FN_CREATE
打开的文件SHFL_FN_SYMLINK
:在共享文件夹中创建符号链接(这需要设置SharedFoldersEnableSymlinksCreate
标志)
如果共享文件夹通过正常的客户增强功能文件系统驱动程序挂载,并且打开了共享内的符号链接,它将在客户机内解析:
|
|
具体来说,文件系统驱动程序将首先查询文件类型以确定是否为符号链接,然后发出SHFL_FN_READLINK
调用来解析链接,然后递归回到内核以打开结果路径。
但是,由于SHFL_FN_CREATE
不检查请求的文件路径是否为符号链接(如果尝试检查可能会存在竞争条件),我们同样可以强制在宿主机上打开符号链接。
我的CTF挑战有一个意外的简单方法可以在客户机内获得root权限——事实证明passwd -d root
不会"删除"root密码而是清空它;也许我应该更经常阅读man手册。团队"pasten"注意到官方文件系统驱动程序有一个标志,可以使它在宿主机端打开符号链接,因此以下是挑战的简单解决方案:
|
|
这将打印宿主机上/flag
文件的内容。如果我没有为了使挑战更加稳健而显式将共享文件夹标记为只读,写入宿主机上的文件也同样容易。
当他们在CTF开始仅3小时后提出此解决方案,而我本意是让此挑战处于难度较高的一端时,我决定添加第二个版本的挑战称为babyvm2,希望在那里不容易获得root权限。相反,参与者应该滥用客户增强功能来实现相同的效果。
通过/dev/vboxuser
进行利用
在那里,我称之为利用。虽然这显然都是预期行为。无论如何,我已经描述了通过/dev/vboxuser
设备"使用"此行为所需的一切,剩下的只是一个编程挑战。我们必须找出如何通过设备进行HGCM调用,以及需要什么特定的HGCM调用顺序来实现我们想要的目标。因为我懒,我没有重新实现HGCM协议,而是修补了一个现有的客户端,称为VBoxControl,并添加了额外的"功能"。
该补丁应该可以干净地应用到VirtualBox 5.2.4代码库。我将跳过构建说明,因为它们在VirtualBox文档中有详细描述。
构建VirtualBox通常相当不愉快。Arch Linux用户有一定优势,因为他们可以修改官方的PKGBUILD:
|
|
修改后的VBoxControl有两个额外的命令称为symlink
和getfile
,可以如下使用:
|
|
这将转储宿主机上/flag
文件的内容。putfile
命令可用于写入先前创建的符号链接:
|
|
Vagrant的回应
我向Hashicorp报告了此问题。他们的解决方案如下:如果您在计算机上第一次运行vagrant up
,它将显示以下警告:
|
|
显示此警告后,将创建文件~/.vagrant.d/data/vbox_symlink_create_warning
,防止它再次显示。我不确定这实际上会吸引多少潜在易受攻击的安装的正确人员注意,但至少他们给了您做正确事情的机会,即如果您不完全信任在虚拟机内运行的代码,全局设置环境变量。