Pafish: How to Test your Sandbox Against Virtualization Detection
Editor’s Note: This post was updated on February 6, 2018.
Editor’s Note: This post was on October 16, 2019.
VM Detection – Passing the Pafish Test
Paranoid Fish (pafish) is a tool for detecting malware analysis environments, replicating what malware will do in the wild to detect if it is being analyzed. It comes with a number of generic and specific checks to reveal the presence of certain security products. This allows developers and users of such analysis tools to identify and -if possible- mitigate their weaknesses in terms of detectability. Unfortunately, mitigation is not always possible as some detection mechanisms will look for inevitable side-effects of the applied monitoring technology. For example, if your analysis tool relies on hooking function calls (for example), it is relatively trivial to detect the resulting memory modification and probably not possible to mitigate against that.
It’s important to note that virtual machine detection itself is no longer that relevant for malware authors as it had been in the past, and its relevance may vanish completely within the next few years as virtualization becomes a pervasive part of enterprise production environments. However, there still exists a lot of legacy malware that refuses to operate correctly when being executed inside a VM. For modern complex cyber threats, it is more relevant to hide the specific artifacts of the security solution itself, because this is what actually differentiates the analysis environment from a real victim machine. Depending on the underlying technology it still can become hard -or even impossible- to reach this goal: the more the monitoring component intervenes in the analysis environment, the more complex it becomes to completely hide its tracks. We wrote about this in blog posts on the Observer Effect and Lochard’s exchange principle.
That is one of the reasons why agentless analysis systems are so powerful. In this post and the video below, we take a brief look at Pafish’s detection methods and show why an agentless sandbox-like VMRay Analyzer is not affected by them at all.
Pafish contains basic debugger detections by utilizing the two different Windows API functions IsDebuggerPresent() and OutputDebugString(). Since most malware sandboxes don’t utilize in-machine debugging, these checks are generally not useful to detect them. Besides the pafish routines, there are more sophisticated methods to detect debuggers, either generically or specifically.
Virtual Machine Detection
Pafish utilizes different checks to detect the presence of a virtual machine and an underlying hardware hypervisor, which all are based on the properties of the CPU.
The first method utilizes the high-performance timestamp counter (TSC). To that end, the rdtsc instruction is executed twice subsequently and the difference between the two resulting timestamps is calculated. If this sequence is executed on a virtual machine and the hypervisor intercepts the rdtsc executions, the resulting time difference is much higher than on a regular system. However, if one has full control over the hypervisor itself, the attack can be easily thwarted. The CPU just has to be configured to allow guests execution of the rdtsc instruction without trapping in the hypervisor.
The second CPU-based attack is a slightly more sophisticated version of the first one. Rather than just utilizing rdtsc, pafish uses it to measure the execution time of the cpuid instruction. The trick exploits the fact that on most x86 CPUs this instruction always traps into the hypervisor. On Intel CPUs this behavior cannot be changed at all and on AMD its deactivation results in other problems and ways to detect the VM. However, modern CPUs allows precise calculation of the time needed for instructions such as vmenter, vmexit, or cpuid. This knowledge can be used to transparently hide away the clock cycles that are consumed outside of the guest machine and thus make the hypervisor impossible to be detected by that.
The third check tries to infer the existence of a hypervisor by reading the CPUs dedicated hypervisor present bit: CPUID.1:ECX.HV[bit 31]. However, when having a custom hypervisor it’s easy to simply disable that particular bit, because it is solely informational.
The final check reads out the CPU vendor string by utilizing the cpuid instruction and then compares it against the set
- Microsoft Hv
Obviously, these strings belong to the well-known hypervisors KVM, Hyper-V, VMWare and XEN. Again, if a custom hypervisor is applied, it is really easy to return valid values that resemble the same results as when running on a real system.
Generic Sandbox Detection
Generic sandbox detections test the presence of certain artifacts and side-effects which often exist in analysis environments. Pafish is equipped with 10 different generic checks for that purpose:
The first test checks whether the mouse position changes within two seconds and if no movement is detected, the system is flagged as a sandbox. This is obviously not a reliable test, because real users often do not move their mouse for two seconds or more. Nevertheless, VMRay provides sophisticated user simulation, that amongst other functions simulates real-world mouse movements and keyboard inputs and passes this test as well.
Besides that, pafish examines the configuration of various hardware resources and detects settings that are uncommon for real end user systems. For example, the size of the physical memory is checked for being less or equal than 1GB, and the hard disc size is compared against 60GB. Besides that, the number of existing CPU cores is obtained and then checked for being equal to only one. VMRay’s analysis environments can be fully customized to use typical end user system configurations. Hence, it’s really easy to overcome these kinds of detections.
One trivial -but still often seen- mistake is leaving obvious traces on the analysis machines: pafish checks if the current username is SANDBOX, VIRUS, or MALWARE, if the executable path contains SAMPLE, VIRUS, or SANDBOX, and whether any non-removable storage drive contains a file called sample.exe or malware.exe in their root-directory. The remediations to this detection are obvious and straight-forward.
Sandbox resources are scarce in relation to the vast amount of files that need to be analyzed and thus the time spent for each analysis often has to be limited to only a few minutes. Malware often exploits this limitation by stalling the execution of malicious payload for a certain amount of time. Sandboxes could counter this by patching calls to the Sleep() API, i.e., artificially speeding up the time. However, this can be easily detected by the malware by querying other timing sources and comparing the results. As one example Pafish utilizes the API GetTickCount() to that end. Only if one has full control over all internal timers within the CPU (and probably some other devices as well), one is enabled to skip forward time in a transparent a non-detectable way. Being an internal part of the hypervisor and having full control over all devices puts you into this powerful position.
QEMU is a common open-source simulator that is used within many analysis systems. The traditional usage is emulating a complete computer system, which gives full control over everything but is painfully slow. Another usage is combining it with a hardware-assisted hypervisor, such as KVM, and only use the parts that simulate hardware devices.
No matter what usage scenario is chosen, out-of-the box all simulated devices contain vendor strings and IDs that make it easy to detect the presence of QEMU. To this end, Pafish checks the values of the two registry keys:
- HARDWAREDEVICEMAPScsiScsi Port 0Scsi Bus 0Target Id 0Logical Unit Id 0Identifier
Again, if one is an integral part of the hypervisor and hence enabled to modify all parts of it freely, it’s an easy task to remove all such QEMU-related artifacts from the device names and their resulting registry settings.
Pafish further checks the CPU brand string, which is returned by cpuid. If it contains the value QEMU Virtual CPU, it is clear that a simulator is used. Also, this returned string can be easily modified if the hypervisor is under full control of the cpuid instruction’s execution.
Detecting Other Software
Similar to the previously described QEMU detections, Pafish contains more methods to identify specific software such as Sandboxie, Wine, VirtualBox, VMware, Bochs, or Cuckoo Sandbox. All of the related checks aim at specific and mostly non-removable artifacts that are caused by using particular software products. Obviously, VMRay can’t be detected by any of these methods. However, we track all of the detection attempts themselves, since their occurrence definitely increases the suspiciousness of the analyzed piece of software.
Pafish is a great tool for hardening your malware analysis environment, though this is not possible in all cases due to the un-remediable side-effects of certain technologies. While in the past virtual machine detection used to be a powerful mechanism for malware to conceal its real behavior, the effectiveness of this approach is diminishing constantly due to the ubiquitous usage of virtualization on productive systems, both server and client-side.
In contrast, malware is more often aiming at the detection of direct sandbox artifacts, such as modifications of the operating system or unusual software and hardware configuration. For decreasing the attack surface it is necessary to have as little interweaving between the sandbox system on the one hand and the utilized analysis environment on the other hand. Our agentless dynamic analysis technology is perfectly suited for this, because our hypervisor-based external monitoring means no single bit in the analysis environment is modified. You can read more in our blog post series on common sandbox evasion techniques.