67 lines
2.5 KiB
Rust
67 lines
2.5 KiB
Rust
// ============================================================================
|
|
// WARLOCK'S STAVE: Linux eBPF Kernel Tracing Engine
|
|
// ============================================================================
|
|
//
|
|
// Provides kernel-level event tracing via eBPF kprobe programs.
|
|
// Requires: aya 0.11.0, clang for eBPF bytecode compilation,
|
|
// and elevated permissions (CAP_BPF or root).
|
|
|
|
#[cfg(target_os = "linux")]
|
|
use aya::{Bpf, programs::KProbe, maps::perf::AsyncPerfEventArray};
|
|
#[cfg(target_os = "linux")]
|
|
use bytes::BytesMut;
|
|
|
|
/// Kernel-level event structure populated by eBPF probe programs.
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug)]
|
|
pub struct KernelTraceEvent {
|
|
pub pid: u32,
|
|
pub vlan_id: u16,
|
|
pub network_namespace: u32,
|
|
}
|
|
|
|
pub struct LinuxEbpfEngine;
|
|
|
|
impl LinuxEbpfEngine {
|
|
/// Spawns eBPF kprobe on sys_enter_connect to intercept outbound
|
|
/// network connections. Requires a pre-compiled eBPF object at
|
|
/// `ebpf_bin/stave_probe.o` (built by `build.sh`).
|
|
#[cfg(target_os = "linux")]
|
|
pub fn spawn_kernel_hooks() -> Result<(), Box<dyn std::error::Error>> {
|
|
let mut bpf = Bpf::load(include_bytes!("../../ebpf_bin/stave_probe.o"))?;
|
|
let program: &mut KProbe =
|
|
bpf.program_mut("sys_enter_connect").unwrap().try_into()?;
|
|
program.load()?;
|
|
program.attach("sys_connect", 0)?;
|
|
|
|
let mut perf_array =
|
|
AsyncPerfEventArray::try_from(bpf.map_mut("STAVE_EVENTS").unwrap())?;
|
|
std::thread::spawn(move || {
|
|
let runtime = tokio::runtime::Runtime::new().unwrap();
|
|
runtime.block_on(async {
|
|
let mut buffers = vec![BytesMut::with_capacity(1024); 4];
|
|
loop {
|
|
if let Ok(events) = perf_array.read_events(&mut buffers).await {
|
|
for i in 0..events.read {
|
|
let event = unsafe {
|
|
*(buffers[i].as_ptr() as *const KernelTraceEvent)
|
|
};
|
|
println!(
|
|
"[KERNEL ALERT] Intercepted Outbound Connect! \
|
|
PID: {} | NS: {}",
|
|
event.pid, event.network_namespace
|
|
);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
Ok(())
|
|
}
|
|
|
|
/// No-op on non-Linux platforms.
|
|
#[cfg(not(target_os = "linux"))]
|
|
pub fn spawn_kernel_hooks() -> Result<(), Box<dyn std::error::Error>> {
|
|
Ok(())
|
|
}
|
|
} |