A lot of BYOVD writeups get told from the research bench, driver internals first, incident second. We want to walk through this one the way it landed on our side: as an alert, then a driver load attempt we didn’t let finish, then the investigation that followed. This is the Gentlemen ransomware engagement CyOps encountered, and the driver at the center of it, PoisonX. Full IOCs included below.
Where it Started
The operators already had hands-on-keyboard access by the time PoisonX showed up. They’d gotten in over RDP, which by itself isn’t unusual, RDP is still one of the most common footholds we see. What told us this wasn’t a routine post-compromise session was what they staged next: multiple variants of the same driver, dropped straight into the compromised user’s Downloads folder, followed by a new Windows service built to load it.
That sequence is a pattern we’re seeing more often. A .sys file landing in a user-writable path, paired with a freshly created service pointing at it, is not something legitimate software does. It’s someone trying to get a driver into the kernel the same way an admin would install one, using the normal Windows path, just without the normal reasons.
Why PoisonX?
PoisonX works as an attack tool for the same reason a lot of vulnerable drivers do: it’s signed by the Microsoft Windows Hardware Compatibility Publisher, so it sails through driver signature enforcement without tripping anything. Once it’s loaded, it exposes a device interface any user-mode process can talk to through DeviceIoControl. When we reverse-engineered the samples, the chain was straightforward: requests hit the driver’s IRP_MJ_DEVICE_CONTROL dispatch routine, an IOCTL handler processes the caller-supplied input with basically no validation, and that input reaches a ring-0 kill routine that opens a target process with broad access and terminates it directly via ZwTerminateProcess.
Sitting on the response side, that’s the detail that matters most. A kernel-mode process-kill primitive, reachable from user mode, behind a driver Windows already trusts. That’s exactly the capability an operator needs before touching a security agent they can’t otherwise kill.
What We Stopped
We caught and blocked the driver load before the service ever got PoisonX running in the kernel. That’s the part we want to flag to other defenders as the real takeaway: none of PoisonX’s capability exists until the load succeeds. Block the load, and the kill routine, the defense impairment, the quiet window before ransomware deployment, none of it materializes.
Because the load never completed, our telemetry never went dark. That let us do the rest of the job the way you want to: correlate the attempted driver load against everything else happening on that endpoint, confirm this was heading toward ransomware deployment rather than treat it as an isolated event, and isolate the box before the operators could pivot to another approach.
This wasn’t the first time we’d seen this exact shape of intrusion. Across other engagements we’ve worked, the specific driver changes, GoFly, CcProtect, and UnknownKiller have all shown up in the same role, but the workflow is identical every time: get hands-on-keyboard access, stage a signed vulnerable driver, stand up a service to load it, then move on defense impairment once kernel access lands. Defenders should stop thinking of the driver itself as the indicator, and focus on the workflow instead.
Indicators of Compromise
These are the IOCs we pulled from this engagement. If you run threat hunting or manage blocklists, get these in now.
Files
| File Path | SHA256 |
| C:\Users\{User}\Downloads\PoisonX3.sys | 4948e89b532804590490aaae41f4b582a89592c931e557b6ddfff0b8d6ee8cf5 |
| C:\Users\{User}\Downloads\PoisonX4.sys | 83DB6A37D9EC9923CA2AA677B4F4D8B67C8B2468046D21136A57FFE92EBA6CAC |
| C:\Users\{User}\Downloads\PoisonX10.sys | D58DF93524EAD1A1F939438EF63B5A9E42AACEC7463ED29878293382996640CE |
| C:\Windows\System32\CcProtect.sys | 5f0cfe8357bb52b45068ddbac053e32bc38e6cb5e086746f5402657b0a5cfb1c |
| C:\Windows\System32\eb.sys | 97bd65e98cdc4e93d49edd4ea905d43a61244df0fd3323e6649330de3b1be091 |
| C:\Windows\System32\ly64.sys | 2fdfdd13a0c548bb68c9d5aa8599a9265d4659da3e237fe7a42ac6ac06b9a06a |
Registry
| Key | Subkey | Value |
| HKLM\SYSTEM\CurrentControlSet\Services | PoisonX | Any values |
MITRE ATT&CK Mapping
| Technique | Description |
| T1021.001 | Remote Services: Remote Desktop Protocol |
| T1543.003 | Create or Modify System Process: Windows Service |
| T1562.001 | Impair Defenses: Disable or Modify Security Tools |
| T1068 | Exploitation for Privilege Escalation |
Advice for Threat Hunting and Proactive Defense
- Alert on new kernel driver loads from user-writable paths, especially Downloads, Temp, and AppData. That’s where we saw PoisonX staged
- Treat a new service pointing at a .sys file outside the normal driver store as high-priority, not just unusual. That pairing is what tipped us off
- Don’t lean on code-signing as a trust signal by itself. A valid Microsoft signature just means the driver is signed, not that it’s safe to load, and that’s the whole reason PoisonX works
- Watch for gaps or drop-offs in your own telemetry and agent heartbeat. That loss of visibility is itself an indicator, not just an availability hiccup
- Get the hashes and the registry key below into your hunting queries now, and treat the workflow, not just the driver name, as the thing to detect
A Deeper Technical Breakdown
This is the response-side view. Our Cynet Research team put together a fuller writeup that goes into the Windows driver model, the IRP/IOCTL/dispatcher mechanics that make BYOVD possible in the first place, and a full reverse-engineering breakdown of PoisonX’s internals. Read the full reach here:
Signed, Trusted, Weaponized: Inside the BYOVD Playbook Powering Modern Ransomware