VirtualBox 3D Acceleration: An accelerated attack surface
August 29, 2018 | Abdul-Aziz HaririVirtualBox is a free hypervisor currently being developed and maintained by Oracle Corporation. While perhaps lesser known, it’s a direct competitor to VMware WorkStation and Microsoft Hyper-V. In July 2017, we started receiving vulnerabilities in VirtualBox 3D acceleration functionality, which is implemented with the Chromium library. Oracle warns in their documentation against enabling 3D Acceleration due to the security implications it imposes and the attack surface it exposes. What few know is that the code behind 3D Acceleration is very old. And by old, I mean it almost dates back to 2001. Yes, 2001.
In this blog post, I detail different types of vulnerabilities that we received through the ZDI program starting from July 2017. The first batch of vulnerabilities that we received were found by Vasily Vasiliev. Ever since then, research in this area has blossomed, and we’ve started receiving many more vulnerabilities in this attack surface.
The Bugs
Note that in order to trigger/exploit the vulnerabilities, 3D Acceleration must be manually enabled:
Because Chromium allows the rendering of OpenGL graphics, when 3D Acceleration is enabled, OpenGL apps will send rendering commands to the hypervisor, which runs the Chromium server. Selecting this option does not generate any warnings or dialog boxes providing any indication this option exposes a larger attack surface.
The bugs discussed below demonstrate different vulnerabilities affecting OpenGL rendering commands.
CVE-2018-2830: An Integer Overflow in crUnpackExtendProgramParameters4fvNV
Initially found by Vasily Vasiliev, this vulnerability is a classic integer overflow in the crUnpackExtendProgramParameters4fvNV method due to the lack of checks on user-controlled variables. Looking at the code:
The user has control over num. By sending specific values in num, an integer overflow occurs at [1] that forces a small allocation in params. Later at [2], num is used in a loop that overflows params.
The Patch
Oracle added a size check at [1] to avoid the overflow. The vulnerability was patched in Oracle’s April patch release and assigned CVE-2018-2830. Interestingly, this vulnerability was co-credited with another finder, Marche147 – an indication that multiple researchers are looking at the OpenGL attack surface. A very similar vulnerability (ZDI-18-686) with the same vulnerable pattern was found by (Root Object) Alisa Esage and fixed in the July patch release.
CVE-2018-2835: An Out-Of-Bounds Write in crStateTrackMatrixNV
Also found by Vasily Vasiliev, this vulnerability is a “little” bit more critical than the previous vulnerability as it allows writing a controlled value to controlled locations. The nature of the vulnerability is very simple:
At [1], address is used as an index to reference elements in the TrackMatrix array. In this case, address is user-controlled and can be used to perform an out-of-bounds write.
The Patch
An extra check was added at [1] to make sure that address does not exceed maxVertexProgramEnvParams. The vulnerability was also patched in Oracle’s April patch release and assigned CVE-2018-2835.
CVE-2018-2686: A Stack-based Buffer Overflow in crStatePixelMapuiv
Welcome (back) to the 90’s! Here’s a vanilla, stack-based buffer overflow that you’d never imagine to exist in a modern hypervisor codebase. This is one of my favorite vulnerabilities. Let’s take a look at the code:
The user controls mapsize and values. Later at [1], mapsize is used in a copy loop that eventually overflows fvalues.
The Patch
Oracle patched this vulnerability by adding a size check on mapsize at the very beginning of the function [1] to ensure that fvalues does not overflow later. The vulnerability was patched in Oracle’s January 2018 patch release and assigned CVE-2018-2686.
CVE-2018-2687: An Integer Overflow in crServerDispatchDeleteProgramsARB Integer
This vulnerability was also found by Vasily Vasiliev. Sadly, the pattern of this vulnerability is repeated a lot in this codebase (variant hunting anyone?). Let’s have a look at the code:
Since n is user-controlled, an integer overflow can be triggered at [1] forcing a small allocation of pLocalprogs. Later at [2], n is used in a copy-loop that overflows pLocalProgs.
The Patch
As expected, Oracle added a check at [1] to avoid the integer wrap at the crAlloc. The vulnerability was patched in Oracle’s January 2018 patch release and was assigned CVE-2018-2687.
Here is the PoC code that triggers this vulnerability. The PoC works from Ubuntu guest VMs.
Conclusion
Re-using old code for rendering OpenGL graphics is not the best idea, especially when it’s being used in a hypervisor. Regardless of the outdated and non-secure code, looking at the bright side of things: this can be a good place for people who would like to get into auditing code. ☺
You can find me on Twitter at @AbdHariri, and follow the team for the latest in exploit techniques and security patches.