add configuration system with TOML support

This commit is contained in:
Adir Shitrit
2025-11-08 12:20:53 +02:00
parent 977b3e310a
commit fe3e5e3b21
3 changed files with 123 additions and 0 deletions

View File

@@ -13,6 +13,7 @@ tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
uuid = { version = "1.0", features = ["v4"] } uuid = { version = "1.0", features = ["v4"] }
toml = "0.8"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
windows = { version = "0.58", features = [ windows = { version = "0.58", features = [

120
ghost-core/src/config.rs Normal file
View File

@@ -0,0 +1,120 @@
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DetectionConfig {
pub shellcode_detection: bool,
pub hollowing_detection: bool,
pub hook_detection: bool,
pub confidence_threshold: f32,
pub skip_system_processes: bool,
pub max_memory_scan_size: usize,
pub thread_analysis_enabled: bool,
}
impl Default for DetectionConfig {
fn default() -> Self {
Self {
shellcode_detection: true,
hollowing_detection: true,
hook_detection: true,
confidence_threshold: 0.7,
skip_system_processes: true,
max_memory_scan_size: 1024 * 1024 * 100, // 100MB
thread_analysis_enabled: true,
}
}
}
impl DetectionConfig {
pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self, Box<dyn std::error::Error>> {
let content = fs::read_to_string(path)?;
let config: DetectionConfig = toml::from_str(&content)?;
Ok(config)
}
pub fn save_to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), Box<dyn std::error::Error>> {
let content = toml::to_string_pretty(self)?;
fs::write(path, content)?;
Ok(())
}
pub fn load_or_default<P: AsRef<Path>>(path: P) -> Self {
Self::load_from_file(path).unwrap_or_default()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProcessFilter {
pub whitelist: Vec<String>,
pub blacklist: Vec<String>,
pub system_processes: Vec<String>,
}
impl Default for ProcessFilter {
fn default() -> Self {
Self {
whitelist: vec![],
blacklist: vec![],
system_processes: vec![
"csrss.exe".to_string(),
"wininit.exe".to_string(),
"winlogon.exe".to_string(),
"dwm.exe".to_string(),
"explorer.exe".to_string(),
],
}
}
}
impl ProcessFilter {
pub fn should_scan(&self, process_name: &str) -> bool {
// If whitelist is not empty, only scan whitelisted processes
if !self.whitelist.is_empty() {
return self.whitelist.iter().any(|name| process_name.contains(name));
}
// Skip blacklisted processes
if self.blacklist.iter().any(|name| process_name.contains(name)) {
return false;
}
// Skip system processes if configured
if self.system_processes.iter().any(|name| process_name == name) {
return false;
}
true
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = DetectionConfig::default();
assert!(config.shellcode_detection);
assert_eq!(config.confidence_threshold, 0.7);
}
#[test]
fn test_process_filter() {
let filter = ProcessFilter::default();
assert!(!filter.should_scan("csrss.exe"));
assert!(filter.should_scan("notepad.exe"));
}
#[test]
fn test_whitelist_filter() {
let filter = ProcessFilter {
whitelist: vec!["notepad.exe".to_string()],
blacklist: vec![],
system_processes: vec![],
};
assert!(filter.should_scan("notepad.exe"));
assert!(!filter.should_scan("malware.exe"));
}
}

View File

@@ -1,4 +1,5 @@
pub mod anomaly; pub mod anomaly;
pub mod config;
pub mod detection; pub mod detection;
pub mod ebpf; pub mod ebpf;
pub mod testing; pub mod testing;
@@ -14,6 +15,7 @@ pub mod thread;
pub mod threat_intel; pub mod threat_intel;
pub use anomaly::{AnomalyDetector, AnomalyScore, ProcessFeatures}; pub use anomaly::{AnomalyDetector, AnomalyScore, ProcessFeatures};
pub use config::{DetectionConfig, ProcessFilter};
pub use detection::{DetectionEngine, DetectionResult, ThreatLevel}; pub use detection::{DetectionEngine, DetectionResult, ThreatLevel};
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub use ebpf::{EbpfDetector, EbpfEvent, EbpfError, EbpfStatistics}; pub use ebpf::{EbpfDetector, EbpfEvent, EbpfError, EbpfStatistics};