Phantom Check is a Sherlock challenge showcasing some of the common virtualization detection techniques used by attackers. Players will gain the ability to create detection rules by identifying specific WMI queries, comparing processes for virtual machine detection, and analyzing registry keys or file paths associated with virtual environments.
An attacker ran sandbox checks from PowerShell on a Windows host to decide whether they were inside a virtual machine. They started with two WMI queries, one for hardware model and manufacturer and one for thermal data, both of which behave differently on hypervisors. They then loaded a public VM-detection script that walked the services registry hive and compared running processes against known guest-tool names, and it printed which platforms it recognised. All of it, including the full text of the loaded script, survives in PowerShell script block and pipeline logs from a window of about two minutes.
.evtx files in evidence/ → parse with EvtxECmd, then read the CSV with Python. The useful events are PowerShell 4104 (script block) and 4103 (pipeline execution)Timestamp note: The activity sits on 2025-04-09 between about 09:19 and 09:21. EvtxECmd normalises times to UTC, which the log timestamps here follow.
Convert the logs to CSV first, then scan the output for virtualization keywords (Manufacturer, Model, VMware, Hyper-V, vbox). The hits cluster in 4104 and 4103 events on 2025-04-09, so that day’s script blocks are the whole story. The first block, at 09:19, calls Get-WmiObject against a class that exposes Manufacturer and Model, the standard giveaway for a guest VM.
EvtxECmd -d evidence --csv work/evtx
python3 -I scan.py work/evtx/*.csv "Manufacturer|Model|vbox|VMware|Hyper-V"
Tip: Anchor on the 4104 events first. 4103 repeats the same content as pipeline output and is noisier.
Print the 4104 blocks from that day in time order. At 09:20:11 a second WMI query reads thermal zone data. Many hypervisors do not expose thermal zones, so an empty or error result points to a VM.
python3 -I print_4104.py work/evtx/*.csv 2025-04-09
The next block in the same dump, at 09:20:53, is much larger. It defines a single function whose name matches the Nishang VM-detection script. Read the function line at the top of the block.
python3 -I print_4104.py work/evtx/*.csv 2025-04-09
From Q3 the script is in hand, so read its body. It runs Get-ChildItem over a services hive path and looks for service names tied to hypervisors and guest tools. Give the key in the same form the script writes it, with the HKLM: drive prefix.
python3 -I print_4104.py work/evtx/*.csv 2025-04-09
The VirtualBox section of the same script compares Get-Process output against two guest-tool executables. The answer is those two names, in the order the script lists them.
python3 -I print_4104.py work/evtx/*.csv 2025-04-09
The script text only says what it can detect. What it did detect is in the 4103 pipeline events, where Out-Default records each line the script printed. Search them for the This is a prefix.
python3 -I scan.py work/evtx/*.csv "This is a"
Gotcha: The script text contains
This is astrings for every platform it knows, including VirtualBox. Only the 4103 output events show which ones actually fired. I did not establish why one host triggered two platforms, which may just be how the script’s checks overlap.
| Phase | Action |
|---|---|
| Discovery | Get-WmiObject read of hardware manufacturer and model |
| Discovery | WMI thermal zone query |
| Defense Evasion | Public VM-detection script loaded into PowerShell |
| Discovery | Script enumerates the services registry hive for hypervisor services |
| Discovery | Script compares running processes against guest-tool names |
| Defense Evasion | Script prints the platforms it recognised |
| Type | Value |
|---|---|
| Function name | Check-VM |
| WMI class | Win32_ComputerSystem |
| WMI query | SELECT * FROM MSAcpi_ThermalZoneTemperature |
| Registry key | HKLM:\SYSTEM\ControlSet001\Services |
| Process names | vboxservice.exe, vboxtray.exe |
| Technique | ID | Description |
|---|---|---|
| Command and Scripting Interpreter: PowerShell | T1059.001 | Recon and detection script executed in PowerShell |
| System Information Discovery | T1082 | Model and manufacturer query through WMI |
| Virtualization/Sandbox Evasion: System Checks | T1497.001 | Check-VM, thermal zone query, VM service and process checks |
| Query Registry | T1012 | Enumeration of HKLM:\SYSTEM\ControlSet001\Services |
| Process Discovery | T1057 | Get-Process compared against VirtualBox process names |
Turn on PowerShell script block and pipeline logging. Every answer here came from 4104 and 4103 events, including the full text of a script loaded at runtime and the output it printed. Without them this would be a handful of WMI calls with no context.
Alert on sandbox-check WMI queries from PowerShell. Win32_ComputerSystem model reads alongside MSAcpi_ThermalZoneTemperature are rare in legitimate administration, and the pair is a clear VM-check pattern.
Detect known tooling by function name and strings. Check-VM, vboxservice.exe, vboxtray.exe and hypervisor service names inside a script block make cheap, durable detection content.
Treat a sandbox check as a precursor. An actor testing for a VM is deciding whether to continue, so correlate these events with whatever runs on the host next.
The attacker spent about two minutes checking whether the host was a sandbox, and script block logging captured the checks, the loaded script and its verdict. The lesson is that the checks are the detection opportunity: they happen before the payload and they are loud in PowerShell logs.