This month’s virtual machine detection trick involves detecting the presence of the Hyper-V RAW network protocol. This protocol is a special type of winsock protocol that is utilized by many of the guest features, allowing the guest and hypervisor to communicate directly. Importantly, this protocol driver is always present on guest systems even if the guest services are disabled or removed. The protocol can be detected via WMI or the registry.
WMI detection
The WMI class Win32_NetworkProtocol
will have an entry named “Hyper-V RAW” on any machine where Hyper-V is installed as a feature, including both hosts and guests.
Registry Detection
The registry-based detection approach is to enumerate the subkeys of the following registry path:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries
Each subkey contains a ProtocolName
value. Systems with Hyper-V installed will have an entry whose protocol name is “Hyper-V RAW”.
Another approach is to instead search the PackedCatalogItem
values inside the subkeys. These are binary packed descriptors for protocols. Inside, the string “Hyper-V RAW” can be found, encoded in UTF-16.
If you want to get particularly fancy, you could avoid heuristics that look for VM-related strings by instead looking for a protocol with a minimum and maximum address size of 36, and with only the Guarantees Delivery, Guarantees Sequencing, and Supports Graceful Closing flags set.
Use in the wild
The trick itself is as simple as that. Things got interesting, however, when I went to check if anyone had documented this trick before. A search for the “Hyper-V RAW” string with various keywords like detection, malware, etc. returned no such articles on the matter, but instead uncovered a pair of malware samples that had been submitted to a sandbox:
The first result is for an Emotet dropper, and the second is for a Shade (Troldesh) dropper. It would be particularly interesting if both malware families had utilized the same unique trick within just a month or two of each other, right as Shade was winding down and Emotet was scaling up.
Some digging through the reports showed that the string “Hyper-V RAW” was found in the process memory of dropped executables from both submissions.
After far too much reverse engineering, though, I was able to show that neither of the samples actually used this as a detection trick.
The Emotet dropper produced a file with the following hash:
5650da013b1258df9e3b8e4364b857dbbd064c25
This file utilizes wininet.dll
in order to make HTTP requests. The InternetOpenW
API call initializes winsock, which iterates through the protocol catalog registry keys. We can see this in the list of captured registry operations:
Key | Address | Caller |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000001 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000002 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000003 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000004 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000005 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000006 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000007 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000008 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000009 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000010 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000011 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000012 | 0x31766 | InternetOpenW |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000013 | 0x31766 | InternetOpenW |
The enumeration of these keys is coming from the InternetOpenW
call, not application code. Searching for any of the registry key names and the Hyper-V RAW string produced no results elsewhere in the report. This indicates that there’s no actual detection going on here, and the in-memory string is simply an artifact left over from winsock’s own enumeration.
The Shade/Troldesh sample is a slightly less straightforward case. Again, the dropper produces a malicious executable and executes it, and that process somehow ends up with the Hyper-V RAW string in memory. The relevant registry operations are as follows:
Key | Address | Caller |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000001 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000002 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000003 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000004 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000005 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000006 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000007 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000008 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000009 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000010 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000011 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000012 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SYSTEM\ControlSet001\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000013 | 0x772C2FBA | RtlUserThreadStart |
The fact that these come from RtlUserThreadStart
might seem to indicate that this is part of user code. However, it is not uncommon for stack unwinding analysis to show RtlUserThreadStart
as a false positive for the caller name. The address of 0x772C2FBA
is helpful, though, since the main module is unlikely to have been loaded at such a high address, nor are RWX memory allocations from VirtualAlloc
usually seen in that address range. The high address is likely to be associated with an API call into a Windows DLL.
Looking further back in the registry activity history confirms these suspicions:
Key | Address | Caller |
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ | 0x413402 | RegOpenKeyExW |
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\ | 0x41AB2B | RegOpenKeyExW |
HKLM\SOFTWARE\WOW6432Node\System32\Configuration\ | 0x41AB2B | RegOpenKeyExW |
HKLM\Software\WOW6432Node\Policies\Microsoft\Windows NT\Rpc | 0x449146 | NetStatisticsGet |
HKLM\SOFTWARE\WOW6432Node\Microsoft\Cryptography\Defaults\Provider Types\Type 001 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SOFTWARE\WOW6432Node\Microsoft\Cryptography\Defaults\Provider\Microsoft Strong Cryptographic Provider | 0x772C2FBA | RtlUserThreadStart |
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ | 0x413402 | RegOpenKeyExW |
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\ | 0x41AB2B | RegOpenKeyExW |
HKLM\SOFTWARE\WOW6432Node\System32\Configuration\ | 0x41AB2B | RegOpenKeyExW |
HKLM\Software\WOW6432Node\Policies\Microsoft\Windows NT\Rpc | 0x449146 | NetStatisticsGet |
HKLM\SOFTWARE\WOW6432Node\Microsoft\Cryptography\Defaults\Provider Types\Type 001 | 0x772C2FBA | RtlUserThreadStart |
HKLM\SOFTWARE\WOW6432Node\Microsoft\Cryptography\Defaults\Provider\Microsoft Strong Cryptographic Provider | 0x772C2FBA | RtlUserThreadStart |
The application’s main module, loaded with a base address of 0x400000
, makes a number of calls to RegOpenKeyExW
, in relation to persistence and detection of software on the system. It then calls NetStatisticsGet
in netapi32.dll
. This causes winsock to be initialized asynchronously, in a new thread created by RtlUserThreadStart
, leading to the protocol catalog registry keys being enumerated.
In both cases the sandbox analysis’ VM detection heuristics produced false positives, due to winsock accessing the protocol catalog registry keys during initialisation, causing the strings to be loaded into the process memory. This likely only gets picked up in sandboxes that analyse the entire process memory rather than just the standard heap.
Links to the sandbox reports are below. Please be aware that the full analysis pages are extremely large and may slow down your browser.
- Emotet: executive summary / full analysis
- Shade: executive summary / full analysis
If sandbox authors wish to detect this trick, they should look to identify that the enumeration of the protocol catalog registry keys is coming directly from application code, and not via a call stack that includes an API in a library such as winsock, wininet, or netapi32.
About this series
In this series we’re documenting a novel and as-yet undocumented VM detection trick once per month, throughout all of 2021. These detection tricks are focused on 64-bit Windows 10 or Windows Server 2019 guests, targeting a variety of VM platforms.
Previous articles in this series: