
Casos de uso de pesquisa BYOVD com metodologia de descoberta de drivers vulneráveis e engenharia reversa. (CVE-2025-52915, CVE-2025-1055, CVE-2026-3609, CVE-2026-8501).
BYOVD é uma coleção de PoCs que demonstram como drivers vulneráveis podem ser explorados para desativar soluções de AV/EDR.
A coleção inclui tanto drivers não documentados quanto aqueles com cobertura existente em LOLDDrivers ou nas regras de bloqueio de drivers recomendadas pela Microsoft.
Desde sua descoberta inicial, o driver TfSysMon foi adicionado ao LOLDrivers e abusado por grupos de ransomware usando a ferramenta EDRKillShifter, conforme relatado pela Sophos e ESET
A técnica BYOVD ganhou popularidade recentemente na segurança ofensiva, especialmente com o lançamento de ferramentas como o Terminator da SpyBoy (vendido por US$ 3.000) e o projeto ZeroMemoryEx Blackout. Essas ferramentas exploram drivers vulneráveis para desativar agentes de AV/EDR, facilitando ataques adicionais ao reduzir a detecção.
Este repositório contém vários PoCs desenvolvidos para fins educacionais, ajudando pesquisadores a entender como esses drivers podem ser abusados para encerrar processos.
O projeto é organizado como um workspace Rust Cargo. A maioria dos PoCs compartilha uma biblioteca comum (byovd-lib) que lida com o código repetitivo: ciclo de vida do serviço do driver, despacho de IOCTL, monitoramento de processos, ajuste de privilégios e limpeza. Cada killer é um binário enxuto (~50-100 linhas) que apenas define sua configuração específica do driver. K7Terminator, Astra64-Killer, Ktapi-Killer e Xhunter1-Killer são independentes — eles têm suas próprias declarações [workspace] e são compilados diretamente de seus próprios diretórios, não por meio do workspace raiz.```
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
Cada diretório `*-Killer/` contém seu próprio `Cargo.toml`, `src/main.rs` (a implementação do `DriverConfig` + CLI), `README.md` (hashes do driver + uso) e o arquivo `.sys` correspondente que o binário carrega em tempo de execução.
## 🔧 Compilação
**Pré-requisitos:** Toolchain Rust e Visual Studio Build Tools com o 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
Binários são gerados em target/release/. Copie o arquivo de driver .sys correspondente para o mesmo diretório do executável antes de executar.
byovd-lib é a biblioteca compartilhada na qual todos os PoCs (exceto o K7Terminator) são construídos. Ela expõe duas APIs complementares — uma declarativa de alto nível para o fluxo padrão de "instalar driver, matar ao ver, limpar", e uma imperativa de baixo nível para killers que precisam de um fluxo personalizado (anexar a um driver já carregado, distribuir para múltiplos PIDs, buffers IOCTL estruturados, lógica de repetição personalizada, etc.). Ambas podem ser misturadas no mesmo binário.
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 de alto nível: trait `DriverConfig` + `run()`
É isto que os killers incluídos utilizam. Implemente o trait, chame `byovd_lib::run()` e está pronto.```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,
}