Windows Disk Cloning Vulnerability CVE-2016-7224

Introduction:

Microsoft has released many fixes in the month of November, MS16-138 focuses on the virtual hard disk driver(VHD) vulnerabilities. In article we will be focusing on the CVE-2016-7224, Google Project Zero disclosed this vulnerability to microsoft. The vulnerability also compromises confidentiality as it leaks information. We will first provide some background about virtual disks and then proceed to what the vulnerability is and how it is exploited.

Virtual Hard Disk (VHD) is public format which allows us to interface with a hard drive as a virtual disk. On a high level any virtual disk management operation in user mode utilizes functions defined in the VirtDisk.dll,which further interacts with kernel drivers Vhdmp.sys, VDrvRoot.sys, FsDepends.sys to execute the disk operations. The operations may include attaching, detaching, creating, modifying virtual disks with administrative privileges. 

Vulnerability:

While creating a new virtual disk, it is possible for us to create the new disk by cloning it from a physical drive without rights. This new virtual disk can be mounted and will contain the original file system. The exploit can be further extended by copying the new virtual drive to a network share. In normal cases the rights to clone physical drives lies with the administrator. The fact that we can achieve this without admin rights is an Elevation of Privilege vulnerability and as data is leaked we can add information disclosure as well.

Exploit:

The vulnerability is exploited by making a function call to CreateVirtualDisk() defined in VirtDsik.dll. CreateVirtualDisk() requires us to provide some information about how the new disk is to be created. One these requirements is ‘Parameters’ which is a structure of type CREATE_VIRTUAL_DISK_PARAMETERS, this structures contains a member called ‘SourcePath’  and as per the MSDN documentation this variable can point to virtual disk or a physical disk. So we point this to our target physical drive. For demonstration purposes we have created a small drive of 100MB with sample data.

Target Drive
Target Drive

We will execute our exploit from a console window with unprivileged user account.

Console windows privilege
Console windows privilege

Initially we will try to detect all the physical drives present on the machine. In the image below we can see our target drive.

Detecting Physical Drives
Detecting Physical Drives

If the exploit works successfully it will create a new .vhdx file.

Cloned virtual drive
Cloned virtual drive

When mounted this virtual disk will contain a replica of the original file system.

Mounting clone drive
Mounting clone drive

The reason this works is because of a failure to enforce access checks on the caller process. In Windows, driver and user components access almost all system defined objects or resources via handles. So to access an object we send a request for a handle via a function call and most of these function require us to provide OBJECT_ATTRIBUTES this basically defines the security parameters for a handle and the kind of access you are requesting. OBJECT_ATTRIBUTES is a structure which contains two members which convey this information – Attributes, SecurityDescriptor. 

typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
}

Above is the syntax of the OBJECT_ATTRIBUTES structure the member Attributes defines a bitmask of flags that specifies how the handle is created.

When a process tries to access an object it will use the handle and the operating system performs access checks based on the value set in ObjectAttributes.Attributes variable, and deny or allow access to the object. In our case the OS fails to do this check and allows an unprivileged process to secure a handle to an object that requires admin rights.

CreateVirtualDisk() internally calls VhdmpiTryOpenPhysicalDisk() which  fails to specify the appropriate Attributes value while calling ZwOpenFile(). And when the application uses the handle the OS does not check it.

ObjectAttributes.Attributes set to 240h
ObjectAttributes.Attributes set to 240h

In Windows drivers must specify one of the attributes listed below:

–  OBJ_KERNEL_HANDLE
–  OBJ_INHERIT
–  OBJ_FORCE_ACCESS_CHECK

These macros are defined in ntdef.h. So a value of 240h means Attributes is set to OBJ_KERNEL_HANDLE+OBJ_CASE_INSENSITIVE. Which means the handle is created in the context of a system process and can be accessed in kernel mode only, however it does not check if the access token of the calling process, in our case it is ‘poc.exe’

Post Patch Result:

After applying the patch we are unable to clone the physical drive from a normal privilege level. Only when we provide the admin rights are we able to clone the target drive.

After patch result
After patch result

In the code ObjectAttributes.Attributes is set to 640h in the call to  ZwOpenFile(). The bitmask now evaluates to  OBJ_KERNEL_HANDLE+ OBJ_CASE_INSENSITIVE+OBJ_FORCE_ACCESS_CHECK.

ObjectAttributes.Attributes is set to 640h
ObjectAttributes.Attributes is set to 640h

The OBJ_FORCE_ACCESS_CHECK flag ensures that access checks are performed even if a handle is being opened in kernel mode.

Conclusion:

Microsoft has fixed vulnerability in MS16-138. We request our customer to scan their machines with QID 91296.

References:

MS16-138:Security Update for Microsoft Virtual Hard Disk Driver
About VHD
CVE-2016-7224
VHDMP Arbitrary Physical Disk Cloning EoP

Leave a Reply

Your email address will not be published. Required fields are marked *