Challenge 38: BYOVD — Remove Kernel Callbacks
Challenge 38: BYOVD — Remove Kernel Callbacks
| Difficulty: Hard | Category: BYOVD / Kernel Attacks | Target: Kernel Callbacks |
Objective
Use a vulnerable driver with arbitrary kernel read/write primitives to enumerate and remove the MostShittyEDR driver’s kernel callbacks — blinding it without killing the process.
Background
The MostShittyEDR kernel driver registers three types of callbacks:
- PsSetCreateProcessNotifyRoutineEx — sees every process start/stop
- PsSetCreateThreadNotifyRoutine — sees every thread creation
- ObRegisterCallbacks — strips LSASS handle permissions
These callbacks are stored in kernel arrays (e.g., PspCreateProcessNotifyRoutine — an array of EX_CALLBACK_ROUTINE_BLOCK pointers). A BYOVD tool with kernel read/write can walk these arrays, find the EDR’s callback entries, and zero them out — silently disabling monitoring.
Tools like EDRSandblast and CheekyBlinder implement this technique. See BYOVD & IOCTL EDR Killer for how IOCTL-based R/W primitives enable this. Common vulnerable drivers for kernel R/W:
- RTCore64.sys (MSI Afterburner) — IOCTLs for arbitrary physical/virtual memory R/W
- DBUtil_2_3.sys (Dell) — similar R/W primitives
- GDRV.sys (Gigabyte) — arbitrary R/W via
MmMapIoSpace
Weakness Exploited
- The EDR driver’s callbacks are not protected — they’re standard kernel pointers with no integrity check
- No callback guard mechanism — the driver doesn’t periodically verify its callbacks are still registered
- The driver has a well-known device name (
\\.\MostShittyEDR) making it trivial to identify which driver module to target - The callbacks live in kernel memory at known offsets from exported symbols (
PsSetCreateProcessNotifyRoutine→PspCreateProcessNotifyRoutine)
Hints
- Find the kernel base address via
NtQuerySystemInformation(SystemModuleInformation) - Locate
PspCreateProcessNotifyRoutineusing offsets from public PDB symbols - The callback array holds up to 64 entries — walk it and find the one pointing into the EDR’s driver module
- To identify the EDR’s module range, use
NtQuerySystemInformation(SystemModuleInformation)to findMostShittyEDR.sysbase+size - Zero the callback’s
Functionpointer with the vulnerable driver’s write IOCTL - For ObRegisterCallbacks: find the
OB_CALLBACK_ENTRYlinked list and unlink the EDR’s entry
Success Criteria
- Process creation events stop flowing to the EDR agent (it sits idle)
- The EDR agent process is still running — it just receives no more events
- Thread creation and LSASS protection callbacks are also removed
- No bluescreen (carefully validate addresses before writing)
MostShittyEDR