add eBPF kernel tracing for Linux process monitoring
This commit is contained in:
969
ghost-core/src/ebpf.rs
Normal file
969
ghost-core/src/ebpf.rs
Normal file
@@ -0,0 +1,969 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{SystemTime, Duration};
|
||||
use crate::{ProcessInfo, MemoryRegion, DetectionResult, ThreatLevel};
|
||||
|
||||
/// Linux eBPF-based Process Injection Detection
|
||||
/// Provides kernel-level tracing and detection capabilities on Linux systems
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct EbpfDetector {
|
||||
program_manager: EbpfProgramManager,
|
||||
event_processor: EbpfEventProcessor,
|
||||
filter_manager: EbpfFilterManager,
|
||||
ring_buffer: Arc<Mutex<EbpfRingBuffer>>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct EbpfProgramManager {
|
||||
loaded_programs: HashMap<String, LoadedProgram>,
|
||||
program_definitions: Vec<EbpfProgramDefinition>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LoadedProgram {
|
||||
pub program_id: u32,
|
||||
pub program_type: EbpfProgramType,
|
||||
pub attach_point: String,
|
||||
pub fd: i32,
|
||||
pub loaded_at: SystemTime,
|
||||
pub event_count: u64,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum EbpfProgramType {
|
||||
Kprobe,
|
||||
Kretprobe,
|
||||
Tracepoint,
|
||||
Uprobe,
|
||||
Uretprobe,
|
||||
PerfEvent,
|
||||
SocketFilter,
|
||||
SchedCls,
|
||||
SchedAct,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EbpfProgramDefinition {
|
||||
pub name: String,
|
||||
pub program_type: EbpfProgramType,
|
||||
pub attach_points: Vec<String>,
|
||||
pub bytecode: Vec<u8>,
|
||||
pub description: String,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct EbpfEventProcessor {
|
||||
event_handlers: HashMap<EventType, Box<dyn EventHandler>>,
|
||||
detection_rules: Vec<EbpfDetectionRule>,
|
||||
process_tracker: ProcessTracker,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub enum EventType {
|
||||
ProcessCreate,
|
||||
ProcessExit,
|
||||
MemoryMap,
|
||||
MemoryUnmap,
|
||||
MemoryProtect,
|
||||
FileOpen,
|
||||
FileClose,
|
||||
NetworkConnect,
|
||||
NetworkAccept,
|
||||
SyscallEntry,
|
||||
SyscallExit,
|
||||
ThreadCreate,
|
||||
ThreadExit,
|
||||
ProcessInjection,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub trait EventHandler: Send + Sync {
|
||||
fn handle_event(&mut self, event: &EbpfEvent) -> Option<DetectionEvent>;
|
||||
fn get_event_type(&self) -> EventType;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EbpfEvent {
|
||||
pub timestamp: u64,
|
||||
pub pid: u32,
|
||||
pub tid: u32,
|
||||
pub event_type: EventType,
|
||||
pub data: EbpfEventData,
|
||||
pub cpu: u32,
|
||||
pub comm: String,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum EbpfEventData {
|
||||
ProcessCreate(ProcessCreateData),
|
||||
ProcessExit(ProcessExitData),
|
||||
MemoryMap(MemoryMapData),
|
||||
MemoryProtect(MemoryProtectData),
|
||||
FileAccess(FileAccessData),
|
||||
NetworkActivity(NetworkActivityData),
|
||||
Syscall(SyscallData),
|
||||
ProcessInjection(ProcessInjectionData),
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ProcessCreateData {
|
||||
pub parent_pid: u32,
|
||||
pub filename: String,
|
||||
pub argv: Vec<String>,
|
||||
pub envp: Vec<String>,
|
||||
pub uid: u32,
|
||||
pub gid: u32,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ProcessExitData {
|
||||
pub exit_code: i32,
|
||||
pub exit_signal: i32,
|
||||
pub runtime_ms: u64,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MemoryMapData {
|
||||
pub address: u64,
|
||||
pub length: u64,
|
||||
pub protection: u32,
|
||||
pub flags: u32,
|
||||
pub fd: i32,
|
||||
pub offset: u64,
|
||||
pub filename: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MemoryProtectData {
|
||||
pub address: u64,
|
||||
pub length: u64,
|
||||
pub old_protection: u32,
|
||||
pub new_protection: u32,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FileAccessData {
|
||||
pub filename: String,
|
||||
pub flags: u32,
|
||||
pub mode: u32,
|
||||
pub fd: i32,
|
||||
pub operation: FileOperation,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FileOperation {
|
||||
Open,
|
||||
Close,
|
||||
Read,
|
||||
Write,
|
||||
Seek,
|
||||
Truncate,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NetworkActivityData {
|
||||
pub local_addr: String,
|
||||
pub local_port: u16,
|
||||
pub remote_addr: String,
|
||||
pub remote_port: u16,
|
||||
pub protocol: NetworkProtocol,
|
||||
pub operation: NetworkOperation,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum NetworkProtocol {
|
||||
TCP,
|
||||
UDP,
|
||||
ICMP,
|
||||
RAW,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum NetworkOperation {
|
||||
Connect,
|
||||
Accept,
|
||||
Send,
|
||||
Receive,
|
||||
Close,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SyscallData {
|
||||
pub syscall_number: u64,
|
||||
pub syscall_name: String,
|
||||
pub args: Vec<u64>,
|
||||
pub return_value: i64,
|
||||
pub duration_ns: u64,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ProcessInjectionData {
|
||||
pub target_pid: u32,
|
||||
pub injection_type: InjectionType,
|
||||
pub memory_address: u64,
|
||||
pub memory_size: u64,
|
||||
pub source_process: u32,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum InjectionType {
|
||||
PtraceInject,
|
||||
ProcMemInject,
|
||||
SharedLibraryInject,
|
||||
ElfInjection,
|
||||
ShellcodeInject,
|
||||
CodeCaveInject,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DetectionEvent {
|
||||
pub timestamp: SystemTime,
|
||||
pub event_id: String,
|
||||
pub detection_type: DetectionType,
|
||||
pub confidence: f32,
|
||||
pub severity: EventSeverity,
|
||||
pub process_info: ProcessInfo,
|
||||
pub indicators: Vec<String>,
|
||||
pub raw_events: Vec<EbpfEvent>,
|
||||
pub context: DetectionContext,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DetectionType {
|
||||
ProcessHollowing,
|
||||
DllInjection,
|
||||
ShellcodeInjection,
|
||||
PtraceInjection,
|
||||
ProcessDoppelganging,
|
||||
AtomBombing,
|
||||
ProcessGhosting,
|
||||
ManualDllLoading,
|
||||
ReflectiveDllLoading,
|
||||
ProcessOverwriting,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum EventSeverity {
|
||||
Info,
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
Critical,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DetectionContext {
|
||||
pub mitre_technique: String,
|
||||
pub attack_chain: Vec<String>,
|
||||
pub affected_processes: Vec<u32>,
|
||||
pub network_connections: Vec<String>,
|
||||
pub file_modifications: Vec<String>,
|
||||
pub privilege_escalations: Vec<String>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct EbpfDetectionRule {
|
||||
pub rule_id: String,
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub conditions: Vec<DetectionCondition>,
|
||||
pub confidence_weight: f32,
|
||||
pub severity: EventSeverity,
|
||||
pub mitre_technique: String,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DetectionCondition {
|
||||
EventSequence {
|
||||
events: Vec<EventType>,
|
||||
time_window: Duration,
|
||||
same_process: bool,
|
||||
},
|
||||
MemoryPattern {
|
||||
pattern: MemoryPatternType,
|
||||
threshold: f32,
|
||||
},
|
||||
ProcessBehavior {
|
||||
behavior: ProcessBehaviorType,
|
||||
threshold: u32,
|
||||
},
|
||||
FileSystemActivity {
|
||||
pattern: FileSystemPattern,
|
||||
suspicious_paths: Vec<String>,
|
||||
},
|
||||
NetworkActivity {
|
||||
pattern: NetworkPattern,
|
||||
suspicious_destinations: Vec<String>,
|
||||
},
|
||||
SyscallPattern {
|
||||
syscalls: Vec<String>,
|
||||
frequency_threshold: u32,
|
||||
time_window: Duration,
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MemoryPatternType {
|
||||
RWXAllocation,
|
||||
ExecutableMapping,
|
||||
SuspiciousProtectionChange,
|
||||
LargeAllocation,
|
||||
PatternMatching(Vec<u8>),
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ProcessBehaviorType {
|
||||
RapidProcessCreation,
|
||||
UnusualParentChild,
|
||||
PrivilegeEscalation,
|
||||
ProcessMasquerading,
|
||||
HollowedProcess,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FileSystemPattern {
|
||||
TemporaryFileCreation,
|
||||
ExecutableModification,
|
||||
SystemFileAccess,
|
||||
HiddenFileCreation,
|
||||
ConfigurationModification,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum NetworkPattern {
|
||||
UnusualOutboundConnection,
|
||||
CommandControlCommunication,
|
||||
DataExfiltration,
|
||||
LateralMovement,
|
||||
TunneledTraffic,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct ProcessTracker {
|
||||
processes: HashMap<u32, TrackedProcess>,
|
||||
process_tree: HashMap<u32, Vec<u32>>,
|
||||
injection_timeline: Vec<InjectionEvent>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TrackedProcess {
|
||||
pub pid: u32,
|
||||
pub ppid: u32,
|
||||
pub command: String,
|
||||
pub start_time: SystemTime,
|
||||
pub memory_maps: Vec<MemoryMapData>,
|
||||
pub file_operations: Vec<FileAccessData>,
|
||||
pub network_connections: Vec<NetworkActivityData>,
|
||||
pub syscall_history: Vec<SyscallData>,
|
||||
pub injection_indicators: Vec<InjectionIndicator>,
|
||||
pub suspicious_score: f32,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InjectionEvent {
|
||||
pub timestamp: SystemTime,
|
||||
pub source_pid: u32,
|
||||
pub target_pid: u32,
|
||||
pub injection_type: InjectionType,
|
||||
pub indicators: Vec<String>,
|
||||
pub confidence: f32,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InjectionIndicator {
|
||||
pub indicator_type: IndicatorType,
|
||||
pub description: String,
|
||||
pub confidence: f32,
|
||||
pub timestamp: SystemTime,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum IndicatorType {
|
||||
SuspiciousMemoryOperation,
|
||||
UnusualSyscallSequence,
|
||||
ProcessTreeAnomaly,
|
||||
FileSystemModification,
|
||||
NetworkCommunication,
|
||||
PrivilegeOperation,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct EbpfFilterManager {
|
||||
active_filters: HashMap<String, EbpfFilter>,
|
||||
filter_statistics: HashMap<String, FilterStats>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EbpfFilter {
|
||||
pub filter_id: String,
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub event_types: Vec<EventType>,
|
||||
pub conditions: Vec<FilterCondition>,
|
||||
pub action: FilterAction,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FilterCondition {
|
||||
ProcessName(String),
|
||||
ProcessId(u32),
|
||||
UserId(u32),
|
||||
EventFrequency { max_events: u32, time_window: Duration },
|
||||
MemoryThreshold(u64),
|
||||
FilePattern(String),
|
||||
NetworkDestination(String),
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FilterAction {
|
||||
Allow,
|
||||
Block,
|
||||
Monitor,
|
||||
Alert,
|
||||
Quarantine,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FilterStats {
|
||||
pub events_processed: u64,
|
||||
pub events_filtered: u64,
|
||||
pub last_update: SystemTime,
|
||||
pub performance_impact: f32,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct EbpfRingBuffer {
|
||||
buffer: Vec<EbpfEvent>,
|
||||
read_index: usize,
|
||||
write_index: usize,
|
||||
capacity: usize,
|
||||
lost_events: u64,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl EbpfDetector {
|
||||
pub fn new() -> Result<Self, EbpfError> {
|
||||
let program_manager = EbpfProgramManager::new()?;
|
||||
let event_processor = EbpfEventProcessor::new();
|
||||
let filter_manager = EbpfFilterManager::new();
|
||||
let ring_buffer = Arc::new(Mutex::new(EbpfRingBuffer::new(1024 * 1024))); // 1MB buffer
|
||||
|
||||
Ok(Self {
|
||||
program_manager,
|
||||
event_processor,
|
||||
filter_manager,
|
||||
ring_buffer,
|
||||
})
|
||||
}
|
||||
|
||||
/// Initialize eBPF programs for process injection detection
|
||||
pub fn initialize(&mut self) -> Result<(), EbpfError> {
|
||||
// Load core detection programs
|
||||
self.load_process_monitoring_programs()?;
|
||||
self.load_memory_monitoring_programs()?;
|
||||
self.load_injection_detection_programs()?;
|
||||
self.load_syscall_monitoring_programs()?;
|
||||
|
||||
// Set up event processing
|
||||
self.setup_event_handlers()?;
|
||||
|
||||
// Configure default filters
|
||||
self.setup_default_filters()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Load eBPF programs for process monitoring
|
||||
fn load_process_monitoring_programs(&mut self) -> Result<(), EbpfError> {
|
||||
// Process creation monitoring
|
||||
let process_create_program = EbpfProgramDefinition {
|
||||
name: "process_create_monitor".to_string(),
|
||||
program_type: EbpfProgramType::Tracepoint,
|
||||
attach_points: vec!["sched:sched_process_fork".to_string()],
|
||||
bytecode: self.compile_process_create_program()?,
|
||||
description: "Monitor process creation events".to_string(),
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
self.program_manager.load_program(process_create_program)?;
|
||||
|
||||
// Process exit monitoring
|
||||
let process_exit_program = EbpfProgramDefinition {
|
||||
name: "process_exit_monitor".to_string(),
|
||||
program_type: EbpfProgramType::Tracepoint,
|
||||
attach_points: vec!["sched:sched_process_exit".to_string()],
|
||||
bytecode: self.compile_process_exit_program()?,
|
||||
description: "Monitor process exit events".to_string(),
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
self.program_manager.load_program(process_exit_program)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Load eBPF programs for memory monitoring
|
||||
fn load_memory_monitoring_programs(&mut self) -> Result<(), EbpfError> {
|
||||
// Memory mapping monitoring
|
||||
let mmap_program = EbpfProgramDefinition {
|
||||
name: "memory_map_monitor".to_string(),
|
||||
program_type: EbpfProgramType::Kprobe,
|
||||
attach_points: vec!["sys_mmap".to_string(), "sys_mmap2".to_string()],
|
||||
bytecode: self.compile_mmap_program()?,
|
||||
description: "Monitor memory mapping operations".to_string(),
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
self.program_manager.load_program(mmap_program)?;
|
||||
|
||||
// Memory protection monitoring
|
||||
let mprotect_program = EbpfProgramDefinition {
|
||||
name: "memory_protect_monitor".to_string(),
|
||||
program_type: EbpfProgramType::Kprobe,
|
||||
attach_points: vec!["sys_mprotect".to_string()],
|
||||
bytecode: self.compile_mprotect_program()?,
|
||||
description: "Monitor memory protection changes".to_string(),
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
self.program_manager.load_program(mprotect_program)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Load eBPF programs for injection detection
|
||||
fn load_injection_detection_programs(&mut self) -> Result<(), EbpfError> {
|
||||
// Ptrace monitoring for injection detection
|
||||
let ptrace_program = EbpfProgramDefinition {
|
||||
name: "ptrace_injection_monitor".to_string(),
|
||||
program_type: EbpfProgramType::Kprobe,
|
||||
attach_points: vec!["sys_ptrace".to_string()],
|
||||
bytecode: self.compile_ptrace_program()?,
|
||||
description: "Monitor ptrace operations for injection".to_string(),
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
self.program_manager.load_program(ptrace_program)?;
|
||||
|
||||
// Process memory access monitoring
|
||||
let proc_mem_program = EbpfProgramDefinition {
|
||||
name: "proc_mem_monitor".to_string(),
|
||||
program_type: EbpfProgramType::Kprobe,
|
||||
attach_points: vec!["vfs_read".to_string(), "vfs_write".to_string()],
|
||||
bytecode: self.compile_proc_mem_program()?,
|
||||
description: "Monitor /proc/[pid]/mem access".to_string(),
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
self.program_manager.load_program(proc_mem_program)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Load eBPF programs for syscall monitoring
|
||||
fn load_syscall_monitoring_programs(&mut self) -> Result<(), EbpfError> {
|
||||
// General syscall monitoring
|
||||
let syscall_program = EbpfProgramDefinition {
|
||||
name: "syscall_monitor".to_string(),
|
||||
program_type: EbpfProgramType::Tracepoint,
|
||||
attach_points: vec![
|
||||
"raw_syscalls:sys_enter".to_string(),
|
||||
"raw_syscalls:sys_exit".to_string(),
|
||||
],
|
||||
bytecode: self.compile_syscall_program()?,
|
||||
description: "Monitor suspicious syscall patterns".to_string(),
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
self.program_manager.load_program(syscall_program)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set up event handlers for different event types
|
||||
fn setup_event_handlers(&mut self) -> Result<(), EbpfError> {
|
||||
self.event_processor.register_handler(
|
||||
EventType::ProcessCreate,
|
||||
Box::new(ProcessCreateHandler::new()),
|
||||
);
|
||||
|
||||
self.event_processor.register_handler(
|
||||
EventType::MemoryMap,
|
||||
Box::new(MemoryMapHandler::new()),
|
||||
);
|
||||
|
||||
self.event_processor.register_handler(
|
||||
EventType::MemoryProtect,
|
||||
Box::new(MemoryProtectHandler::new()),
|
||||
);
|
||||
|
||||
self.event_processor.register_handler(
|
||||
EventType::ProcessInjection,
|
||||
Box::new(InjectionHandler::new()),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Configure default filters to reduce noise
|
||||
fn setup_default_filters(&mut self) -> Result<(), EbpfError> {
|
||||
// Filter out common system processes
|
||||
let system_filter = EbpfFilter {
|
||||
filter_id: "system_processes".to_string(),
|
||||
name: "System Process Filter".to_string(),
|
||||
description: "Filter out common system processes".to_string(),
|
||||
event_types: vec![EventType::ProcessCreate, EventType::MemoryMap],
|
||||
conditions: vec![
|
||||
FilterCondition::ProcessName("kthreadd".to_string()),
|
||||
FilterCondition::ProcessName("ksoftirqd".to_string()),
|
||||
FilterCondition::ProcessName("migration".to_string()),
|
||||
],
|
||||
action: FilterAction::Allow,
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
self.filter_manager.add_filter(system_filter);
|
||||
|
||||
// High-frequency event throttling
|
||||
let frequency_filter = EbpfFilter {
|
||||
filter_id: "frequency_limit".to_string(),
|
||||
name: "Event Frequency Limiter".to_string(),
|
||||
description: "Limit high-frequency events".to_string(),
|
||||
event_types: vec![EventType::SyscallEntry, EventType::SyscallExit],
|
||||
conditions: vec![FilterCondition::EventFrequency {
|
||||
max_events: 1000,
|
||||
time_window: Duration::from_secs(1),
|
||||
}],
|
||||
action: FilterAction::Monitor,
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
self.filter_manager.add_filter(frequency_filter);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Process events from the ring buffer
|
||||
pub fn process_events(&mut self) -> Result<Vec<DetectionEvent>, EbpfError> {
|
||||
let mut detection_events = Vec::new();
|
||||
|
||||
let events = {
|
||||
let mut buffer = self.ring_buffer.lock().unwrap();
|
||||
buffer.drain_events()
|
||||
};
|
||||
|
||||
for event in events {
|
||||
// Apply filters
|
||||
if self.filter_manager.should_process(&event) {
|
||||
// Process event through detection rules
|
||||
if let Some(detection) = self.event_processor.process_event(event) {
|
||||
detection_events.push(detection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(detection_events)
|
||||
}
|
||||
|
||||
/// Compile eBPF bytecode for process creation monitoring
|
||||
fn compile_process_create_program(&self) -> Result<Vec<u8>, EbpfError> {
|
||||
// In a real implementation, this would compile eBPF C code
|
||||
// For now, return placeholder bytecode
|
||||
Ok(vec![0; 512]) // Placeholder
|
||||
}
|
||||
|
||||
/// Compile eBPF bytecode for process exit monitoring
|
||||
fn compile_process_exit_program(&self) -> Result<Vec<u8>, EbpfError> {
|
||||
Ok(vec![0; 512]) // Placeholder
|
||||
}
|
||||
|
||||
/// Compile eBPF bytecode for memory mapping monitoring
|
||||
fn compile_mmap_program(&self) -> Result<Vec<u8>, EbpfError> {
|
||||
Ok(vec![0; 1024]) // Placeholder
|
||||
}
|
||||
|
||||
/// Compile eBPF bytecode for memory protection monitoring
|
||||
fn compile_mprotect_program(&self) -> Result<Vec<u8>, EbpfError> {
|
||||
Ok(vec![0; 1024]) // Placeholder
|
||||
}
|
||||
|
||||
/// Compile eBPF bytecode for ptrace monitoring
|
||||
fn compile_ptrace_program(&self) -> Result<Vec<u8>, EbpfError> {
|
||||
Ok(vec![0; 1024]) // Placeholder
|
||||
}
|
||||
|
||||
/// Compile eBPF bytecode for /proc/mem monitoring
|
||||
fn compile_proc_mem_program(&self) -> Result<Vec<u8>, EbpfError> {
|
||||
Ok(vec![0; 1024]) // Placeholder
|
||||
}
|
||||
|
||||
/// Compile eBPF bytecode for syscall monitoring
|
||||
fn compile_syscall_program(&self) -> Result<Vec<u8>, EbpfError> {
|
||||
Ok(vec![0; 2048]) // Placeholder
|
||||
}
|
||||
|
||||
/// Get detection statistics
|
||||
pub fn get_statistics(&self) -> EbpfStatistics {
|
||||
EbpfStatistics {
|
||||
loaded_programs: self.program_manager.loaded_programs.len(),
|
||||
total_events_processed: 0, // Would be tracked in real implementation
|
||||
detections_generated: 0, // Would be tracked in real implementation
|
||||
filter_efficiency: 0.0, // Would be calculated in real implementation
|
||||
performance_impact: 0.0, // Would be measured in real implementation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EbpfStatistics {
|
||||
pub loaded_programs: usize,
|
||||
pub total_events_processed: u64,
|
||||
pub detections_generated: u64,
|
||||
pub filter_efficiency: f32,
|
||||
pub performance_impact: f32,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum EbpfError {
|
||||
#[error("Failed to load eBPF program: {0}")]
|
||||
ProgramLoadError(String),
|
||||
#[error("Failed to attach eBPF program: {0}")]
|
||||
AttachError(String),
|
||||
#[error("Event processing error: {0}")]
|
||||
EventProcessingError(String),
|
||||
#[error("Compilation error: {0}")]
|
||||
CompilationError(String),
|
||||
#[error("Permission denied: {0}")]
|
||||
PermissionError(String),
|
||||
#[error("Kernel version not supported: {0}")]
|
||||
KernelVersionError(String),
|
||||
}
|
||||
|
||||
// Placeholder implementations for handlers
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct ProcessCreateHandler;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl ProcessCreateHandler {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl EventHandler for ProcessCreateHandler {
|
||||
fn handle_event(&mut self, event: &EbpfEvent) -> Option<DetectionEvent> {
|
||||
// Process creation event handling logic
|
||||
None
|
||||
}
|
||||
|
||||
fn get_event_type(&self) -> EventType {
|
||||
EventType::ProcessCreate
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct MemoryMapHandler;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl MemoryMapHandler {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl EventHandler for MemoryMapHandler {
|
||||
fn handle_event(&mut self, event: &EbpfEvent) -> Option<DetectionEvent> {
|
||||
// Memory mapping event handling logic
|
||||
None
|
||||
}
|
||||
|
||||
fn get_event_type(&self) -> EventType {
|
||||
EventType::MemoryMap
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct MemoryProtectHandler;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl MemoryProtectHandler {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl EventHandler for MemoryProtectHandler {
|
||||
fn handle_event(&mut self, event: &EbpfEvent) -> Option<DetectionEvent> {
|
||||
// Memory protection change event handling logic
|
||||
None
|
||||
}
|
||||
|
||||
fn get_event_type(&self) -> EventType {
|
||||
EventType::MemoryProtect
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct InjectionHandler;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl InjectionHandler {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl EventHandler for InjectionHandler {
|
||||
fn handle_event(&mut self, event: &EbpfEvent) -> Option<DetectionEvent> {
|
||||
// Process injection event handling logic
|
||||
None
|
||||
}
|
||||
|
||||
fn get_event_type(&self) -> EventType {
|
||||
EventType::ProcessInjection
|
||||
}
|
||||
}
|
||||
|
||||
// Placeholder implementations for managers
|
||||
#[cfg(target_os = "linux")]
|
||||
impl EbpfProgramManager {
|
||||
pub fn new() -> Result<Self, EbpfError> {
|
||||
Ok(Self {
|
||||
loaded_programs: HashMap::new(),
|
||||
program_definitions: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn load_program(&mut self, program: EbpfProgramDefinition) -> Result<(), EbpfError> {
|
||||
// eBPF program loading logic
|
||||
println!("Loading eBPF program: {}", program.name);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl EbpfEventProcessor {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
event_handlers: HashMap::new(),
|
||||
detection_rules: Vec::new(),
|
||||
process_tracker: ProcessTracker::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register_handler(&mut self, event_type: EventType, handler: Box<dyn EventHandler>) {
|
||||
self.event_handlers.insert(event_type, handler);
|
||||
}
|
||||
|
||||
pub fn process_event(&mut self, event: EbpfEvent) -> Option<DetectionEvent> {
|
||||
// Event processing logic
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl ProcessTracker {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
processes: HashMap::new(),
|
||||
process_tree: HashMap::new(),
|
||||
injection_timeline: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl EbpfFilterManager {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
active_filters: HashMap::new(),
|
||||
filter_statistics: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_filter(&mut self, filter: EbpfFilter) {
|
||||
self.active_filters.insert(filter.filter_id.clone(), filter);
|
||||
}
|
||||
|
||||
pub fn should_process(&self, event: &EbpfEvent) -> bool {
|
||||
// Filter evaluation logic
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl EbpfRingBuffer {
|
||||
pub fn new(capacity: usize) -> Self {
|
||||
Self {
|
||||
buffer: Vec::with_capacity(capacity),
|
||||
read_index: 0,
|
||||
write_index: 0,
|
||||
capacity,
|
||||
lost_events: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn drain_events(&mut self) -> Vec<EbpfEvent> {
|
||||
// Drain events from ring buffer
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
// For non-Linux systems, provide a stub implementation
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub struct EbpfDetector;
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
impl EbpfDetector {
|
||||
pub fn new() -> Result<Self, &'static str> {
|
||||
Err("eBPF detection is only supported on Linux")
|
||||
}
|
||||
|
||||
pub fn initialize(&mut self) -> Result<(), &'static str> {
|
||||
Err("eBPF detection is only supported on Linux")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user