150 lines
5.1 KiB
Rust
150 lines
5.1 KiB
Rust
// ============================================================================
|
|
// WARLOCK'S STAVE: Polymorphic IPC Evasion Detection
|
|
// ============================================================================
|
|
//
|
|
// Audits processes for IPC channel switching patterns that indicate
|
|
// evasion — e.g., a process dropping its standard IPC connection and
|
|
// simultaneously creating an unnamed pipe to bypass monitoring.
|
|
|
|
use std::collections::HashMap;
|
|
use std::sync::Mutex;
|
|
use lazy_static::lazy_static;
|
|
|
|
use crate::firmware::HardwareFirmwareAnalyzer;
|
|
|
|
/// Category of an evasion or anomaly event, used by the UI to
|
|
/// select display formatting and severity coloring.
|
|
#[derive(Debug, Clone)]
|
|
pub enum TelemetryEventCategory {
|
|
IpcEvasionDetected,
|
|
FirmwareAnomaly,
|
|
HiddenChannelDiscovered,
|
|
EntropySpike,
|
|
PermissionTransition,
|
|
}
|
|
|
|
/// A single telemetry event produced by the platform auditors.
|
|
#[derive(Debug, Clone)]
|
|
pub struct AdvancedTelemetryEvent {
|
|
pub category: TelemetryEventCategory,
|
|
pub message: String,
|
|
pub pid: u32,
|
|
pub severity: u8, // 0=info .. 4=critical
|
|
}
|
|
|
|
/// Per-process IPC behavioral tracking record.
|
|
#[derive(Debug, Clone)]
|
|
pub struct IpcBehaviorRecord {
|
|
pub pid: u32,
|
|
pub process_name: String,
|
|
pub dbus_active: bool,
|
|
pub unix_socket_count: u32,
|
|
pub unnamed_pipe_count: u32,
|
|
pub tcp_connection_count: u32,
|
|
pub fallback_violation_triggered: bool,
|
|
pub entropy_snapshots: Vec<u8>,
|
|
}
|
|
|
|
// Global IPC state matrix. The UI reads this via `IPC_STATE_MATRIX.lock()`.
|
|
// NOTE: rustdoc does not generate documentation for items produced by macro
|
|
// invocations, so this is a regular comment rather than a doc comment.
|
|
lazy_static! {
|
|
pub static ref IPC_STATE_MATRIX: Mutex<HashMap<u32, IpcBehaviorRecord>> =
|
|
Mutex::new(HashMap::new());
|
|
}
|
|
|
|
/// Calculates byte-distribution Shannon entropy for a buffer.
|
|
/// Returns a value in 0..=100 (scaled from bits-per-byte).
|
|
pub fn calculate_shannon_entropy(buffer: &[u8]) -> u8 {
|
|
if buffer.is_empty() {
|
|
return 0;
|
|
}
|
|
let mut freq = [0u64; 256];
|
|
for &byte in buffer {
|
|
freq[byte as usize] += 1;
|
|
}
|
|
let len = buffer.len() as f64;
|
|
let mut entropy = 0.0f64;
|
|
for &count in &freq {
|
|
if count > 0 {
|
|
let p = count as f64 / len;
|
|
entropy -= p * p.log2();
|
|
}
|
|
}
|
|
(entropy / 8.0 * 100.0).round().min(100.0) as u8
|
|
}
|
|
|
|
/// Audits /proc/self/maps for anonymous RWX memory regions
|
|
/// (indicator of shellcode injection or JIT-spray attacks).
|
|
pub fn audit_cache_abuse() -> Vec<AdvancedTelemetryEvent> {
|
|
let mut events = Vec::new();
|
|
if let Ok(maps) = std::fs::read_to_string("/proc/self/maps") {
|
|
for line in maps.lines() {
|
|
let parts: Vec<&str> = line.split_whitespace().collect();
|
|
if parts.len() < 2 {
|
|
continue;
|
|
}
|
|
let perms = parts[1];
|
|
if perms.contains('w') && perms.contains('x') {
|
|
let is_anon = parts.len() < 6;
|
|
if is_anon {
|
|
events.push(AdvancedTelemetryEvent {
|
|
category: TelemetryEventCategory::PermissionTransition,
|
|
message: format!(
|
|
"Anonymous RWX memory region: {}",
|
|
parts[0]
|
|
),
|
|
pid: std::process::id(),
|
|
severity: 4,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
events
|
|
}
|
|
|
|
/// Scans /dev/shm for IPC channels not associated with any known
|
|
/// system service — potential hidden communication channels.
|
|
pub fn scan_hidden_ipc_channels() -> Vec<AdvancedTelemetryEvent> {
|
|
let mut events = Vec::new();
|
|
if let Ok(entries) = std::fs::read_dir("/dev/shm") {
|
|
for entry in entries.flatten() {
|
|
let name = entry.file_name().to_string_lossy().to_string();
|
|
if name.len() > 16 && name.chars().all(|c| c.is_alphanumeric()) {
|
|
events.push(AdvancedTelemetryEvent {
|
|
category: TelemetryEventCategory::HiddenChannelDiscovered,
|
|
message: format!("Suspicious shared-memory segment: /dev/shm/{}", name),
|
|
pid: 0,
|
|
severity: 2,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
events
|
|
}
|
|
|
|
/// The primary auditor combining firmware, IPC evasion, and
|
|
/// hidden channel detection into a single full-spectrum pass.
|
|
pub struct AdvancedPlatformAuditor;
|
|
|
|
impl AdvancedPlatformAuditor {
|
|
/// Returns firmware-related alerts.
|
|
pub fn audit_firmware() -> Vec<AdvancedTelemetryEvent> {
|
|
HardwareFirmwareAnalyzer::audit_uefi_nvram()
|
|
}
|
|
|
|
/// Returns cache/permission abuse alerts from /proc/self/maps.
|
|
pub fn audit_cache_abuse() -> Vec<AdvancedTelemetryEvent> {
|
|
audit_cache_abuse()
|
|
}
|
|
|
|
/// Performs a full-spectrum platform audit.
|
|
pub fn full_audit() -> Vec<AdvancedTelemetryEvent> {
|
|
let mut all_events = Vec::new();
|
|
all_events.extend(Self::audit_firmware());
|
|
all_events.extend(audit_cache_abuse());
|
|
all_events.extend(scan_hidden_ipc_channels());
|
|
all_events
|
|
}
|
|
} |