导语:VirtualBox是一款开源虚拟机软件,它号称是最强的免费虚拟机软件,它不仅具有丰富的特色,而且性能也很优异。

timg.jpg

VirtualBox是一款开源虚拟机软件,它号称是最强的免费虚拟机软件,它不仅具有丰富的特色,而且性能也很优异!它简单易用,可虚拟的系统包括Windows(从Windows 3.1到Windows10、Windows Server 2012,所有的Windows系统都支持)、Mac OS X、Linux、OpenBSD、Solaris、IBM OS2甚至Android等操作系统!使用者可以在VirtualBox上安装并且运行上述的这些操作系统! 与同性质的VMware及Virtual PC比较下,VirtualBox独到之处包括远端桌面协定(RDP)、iSCSI及USB的支持,VirtualBox在guests端操作系统上已可以支持USB 2.0的硬件装置,不过要安装 VirtualBox Extension Pack。

不过在去年9月用VirtualBox时,我无意中发现了VirtualBox中非常严重的漏洞。具体过程是,当我在使用Vagrant生成的虚拟箱中运行非特权程序时,它可以获得对主机整个文件系统的读取和写入访问。准确地说,它实际上并不是VirtualBox的漏洞,而是由Vagrant错误配置造成的不当操作。

要知道这个问题可是公开的,且一直存在,不过Vagrant现在都会对此问题提醒一次用户。如果你在VirtualBox中运行不受信任的代码,则应该明确设置VAGRANT_DISABLE_VBOXSYMLINKCREATE环境变量,例如,通过以下代码段。

export VAGRANT_DISABLE_VBOXSYMLINKCREATE=1

以上代码段会出现在.profile/.zprofile。

我在CTF的挑战赛中,仅用了3小时就解决了该问题。

问题介绍

在默认情况下,Vagrant会将标记SharedFoldersEnableSymlinksCreate设置为它创建的每个同步文件夹。这包括vagrant共享,默认情况下它会在每个VirtualBox中启用,除非用户明确地通过添加进行抑制。

config.vm.synced_folder ".", "vagrant", disabled: true

以上代码段会出现在 Vagrantfile, VirtualBox文档对此标志有如下说明:

出于安全原因,guests帐户操作系统默认情况下是不允许创建符号链接的。如果你相信guests操作系统不滥用该功能,则可以通过以下方式为“sharename”创建符号链接:VBoxManage setextradata "VM name" VBoxInternal2/SharedFoldersEnableSymlinksCreate/sharename 1。

尽管VirtualBox文档可以明确地表明启用这个标志的含义,但Vagrant显然假设所有的虚拟箱都是隐含信任关系的,这与我的个人直觉相反。我认为Vagrant只是一个非常简单的虚拟机管理程序,并且不应该添加额外的攻击途径。总之,我期望它能给我类似于VirtualBox相同的安全保证。

从非特权的上下文中访问共享文件夹

VirtualBox中的共享文件夹可以实现为HGCM服务(Host-Guest Communication Manager的简称)。HGCM涉及一个相当简单的RPC协议,通过它,guests可以对管理程序进行函数调用。VirtualBox的其他几个功能也需要与guests合作,通过这种机制实现比如如剪贴板共享,拖放和3D加速等。

为了启动HGCM调用,例如在共享文件夹中读取或写入文件,或将数据放入剪贴板,必须对通过每个虚拟机监控的特殊VMM设备进行自定义请求PCI。这通常需要内核特权。但是,如果安装了VirtualBox guest虚拟机添加项,则可以通过VBoxGuest驱动程序进行请求,这些驱动程序以Windows上的VBoxGuest设备和/dev/vboxuser设备的形式暴露,即guest虚拟机中的非特权进程暴露在Linux上。由于Vagrant的同步文件夹利用了共享文件夹功能,因此,在已经安装的VirtualBox guest中通常会出现Vagrant Box。

在我向Oracle报告了此问题后,该公司在VirtualBox添加的5.2.6版本中完全禁用了该设备。然而,这在5.2.7测试和5.2.8稳定版本中此漏洞又出现了,因为它们的某些功能依赖于此设备的可用性,这在某些测试过程中难免会遇到。

使用符号链接访问主机文件系统

SharedFolders HGCM服务的核心由VirtualBox源文件src/VBox/HostServices/SharedFolders/service.cpp中的函数svcCall实现。 利用HGCM的相关功能,我要实现以下目的:

1.SHFL_FN_CREATE在共享文件夹中打开文件;

2.通过SHFL_FN_CREATE,SHFL_FN_ {READ,WRITE}可以对文件进行读写;

3.SHFL_FN_SYMLINK在共享文件夹中创建符号链接(这需要设置SharedFoldersEnableSymlinksCreate标志)

如果通过普通guest添加文件系统驱动程序安装共享文件夹,并且共享内部的符号链接已打开,则它将在guest虚拟机中解析。

360截图16171115062437.jpg

最重要的是,文件系统驱动程序将首先查询文件类型以确定它是否是符号链接,然后发出SHFL_FN_READLINK调用来解析链接,然后递归到内核中以打开生成的路径。但是,由于SHFL_FN_CREATE并不检查请求的文件路径是否是符号链接,因此我也可以强制在主机上打开符号链接。

我在CTF挑战中,使用了一个意想不到的简单方法,即在guest虚拟机内获得root权限。事实证明,passwd -d root不会删除root密码,但是会清空它。我注意到官方的文件系统驱动程序有一个标志可以使它打开主机端的符号链接,以下就是是解决这个挑战的简单方法。

$ su
# umount /vagrant
# rmmod vboxsf
# modprobe vboxsf follow_symlinks=1
# mount -t vboxsf vagrant /vagrant
# ln -s /flag /vagrant/flag
# cat /vagrant/flag

这就是出现在主机file/flag的内容,如果我没有明确地将共享文件夹标记为只读,那么在主机上写入文件就可以轻松完成。

通过/dev/vboxuser进行攻击

现在我已经描述了通过/ dev/vboxuser设备使用这种行为所需的一切条件,剩下的仅仅是编程方面的挑战。我必须找出如何通过设备进行HGCM调用以及HGCM调用的具体顺序,以达到我们想要的目标。因为我很懒,所以我没有重新实现HGCM协议,而是修补了一个名为VBoxControl的现有客户端,并添加了一些额外的功能。

补丁应该适用于VirtualBox 5.2.4代码库,我将跳过构建说明,因为它们在VirtualBox文档中有详细描述。构建VirtualBox通常很复杂,不过 Arch Linux用户有一定的优势,因为他们可以修改官方的PKGBUILD。

$ svn checkout --depth=empty svn://svn.archlinux.org/community
$ cd community
$ svn update virtualbox
$ cd virtualbox/trunk

修改后的VBoxControl有两个额外的命令,称为symlink和getfile。

$ ./VBoxControl symlink vagrant foo /flag
$ ./VBoxControl getfile vagrant foo ./test
$ cat ./test

这会将file/flag的内容转储到主机上,可以使用putfile命令来写入以前创建的符号链接。

$ ./VBoxControl symlink vagrant foo /home/niklas/.bashrc
$ echo 'echo owned' > ./test
$ ./VBoxControl putfile vagrant foo ./test 0644

Vagrant的应对之策

我向Hashicorp报告了这个问题。他们的解决方案如下:如果你第一次在你的计算机上运行vagrant,它将显示以下警告:

Vagrant is currently configured to create VirtualBox synced folders with
the `SharedFoldersEnableSymlinksCreate` option enabled. If the Vagrant
guest is not trusted, you may want to disable this option. For more
information on this option, please refer to the VirtualBox manual:

  https://www.virtualbox.org/manual/ch04.html#sharedfolders

This option can be disabled globally with an environment variable:

  VAGRANT_DISABLE_VBOXSYMLINKCREATE=1

or on a per folder basis within the Vagrantfile:

  config.vm.synced_folder '/host/path', '/guest/path', SharedFoldersEnableSymlinksCreate: false

显示此警告后,将创建文件~/.vagrant.d/data/vbox_symlink_create_warning,以防止再次显示该文件。但是,我不确定这种安全提示是否能引起人们的注意。

源链接

Hacking more

...