Whenever I get a shell on a Windows system with VMware installed I feel a certain frustration at not being able to access the filesystem of the available virtual machines. Although it would be possible to download the .vmdk files to my host and mount them locally this solution is very noisy and heavy due to their high size. The ideal solution would be the one where you could mount the corresponding vmdk files on the “victim’s system” using the own resources offered by the VMware installation.
This made me remember the malware developed by Hacking Team, dubbed as Crisis or DaVinci. You can find a nice analysis here. One of the post-exploitation techniques used by DaVinci is the possibility to mount .vmdk files by making use of the driver vstor2 provided by some versions of VMware. Since the source code was leaked I decided to keep an eye on it to see how they implemented that functionality. You can find that code in the HM_PDAAgent.h file.
However, the way in which they do this functionality is quite limited and not very clear. Look, for example, the following code.
The comment in Italian: “// XXX – Per ora riesce to mount only his Z” meaning “for now only able to mount it in Z” reflects some limitations of the code. If the victim already has a Z unit mounted the code will not work. Furthermore the function responsible for communicating with the driver via DeviceIoControl receives a parameter called “drive_letter” that is never used. They just send a hardcoded bunch of bytes to the VMware driver to mount a specific .vmdk file. So there is no option to choose the mount point (the drive letter) or even the mode (only-read or write).
To better understand how this works I spent some time researching the vstor2 driver and the VMware dlls in charge of mounting the .vmdk files from user-land. The time invested was worthwhile as I found some interesting things like a BSOD bug in the driver vstor2.
With that information I made a post-exploitation module for Meterpreter called vmdk_mount. The module will check if VMware is installed. In that case it will try to find the device driver name from the registry and it will launch the vixDiskMountServer.exe VMware binary (needed for the mounting process). Finally it will build the input buffer from the user parameters to generate the appropriate IRP via DeviceIoControl. The core function to send this buffer is shown below:
The parameters for configuring the module are:
- DRIVE: the drive letter on which to mount the .vmdk file. If this letter is already taken the module will inform you and no action will be performed.
- DEL_LCK: boolean to indicate if you want to delete the lock file created once the drive is mounted. When vixDiskMountServer.exe mounts the drive VMware creates a .vmdk.lck folder with a .lck file inside. This file will be responsible for VMware complaining when the user try to run the virtual machine while its file system is busy. By setting this option to True once the mount point is setup the associated lck file will be deleted.
- READ_MODE: by default the file system will be mount as only-read. This is the recommended way indeed. Even VMware warns you that the write mode is really dangerous: “You should only open a disk file in writable mode if you know for sure that no snapshots or clones are linked from the file. This options should be used with extreme care. If you make changes to a disk file that others are linked from, all those snapshots and clones will be invalidated and no longer usable“. That said, use this option with extreme care.
- VMDK_PATH: the .vmdk file. Check the config file (.vmx) to choose the appropriate hard drive file.
Let’s see an example with a Windows 10 64 bits (Version 1607) and VMware® Workstation 12 Pro (12.5.5). The following configuration will mount the file “Windows 7 x64.vmdk” in Z: Note that in this example the Z drive is already taken (as well as C: and D:). The module is aware of this and will inform you. After re-selecting the T letter the module runs smoothly:
Now you can browse and download files from the new machine:
If you consider that the write mode is safe you can do very interesting things apart from stealing information. For instance, you can install a persistent mechanism by writing certain payload in the startup folder of certain user so that when he login the payload runs. The following video shows this p0c:
Note that in the video when the Windows Virtual Machine starts it finds the file system dirty so it runs a check disk (possibly this is because I never unmount the file system).
- It is necessary that the binary vixDiskMountServer.exe is running while interacting with the file system. If a running instance of this binary exists prior to launching the module (for example, because the user has the VMware map utility running), the module will not run. In that case you can kill that process from Meterpreter. Remember this too if you successfully run vmdk_mount and exit from the Meterpreter sessión. In this case the process vixDiskMountServer.exe will still be running.
- When the virtual machine is powered-on a .vmx.lck file is created. So, this is a good way to know if you should wait to run the module.