Skip to content

Commit c1a10df

Browse files
committed
webarchive probe detector
1 parent fa300ea commit c1a10df

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

src/detectors/mod.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ impl DetectorRegistry {
121121
self.register(SsrfMetadataDetector);
122122
self.register(ExfiltrationChainDetector);
123123
self.register(SecretLeakageDetector);
124+
self.register(WebArchiveProbeDetector);
124125
}
125126

126127
pub fn detect_log_anomalies(&self, entries: &[LogEntry]) -> Vec<LogAnomaly> {
@@ -203,6 +204,7 @@ struct SensitiveFileAccessDetector;
203204
struct SsrfMetadataDetector;
204205
struct ExfiltrationChainDetector;
205206
struct SecretLeakageDetector;
207+
struct WebArchiveProbeDetector;
206208

207209
impl LogDetector for SqlInjectionProbeDetector {
208210
fn id(&self) -> &'static str {
@@ -640,6 +642,50 @@ impl LogDetector for SecretLeakageDetector {
640642
}
641643
}
642644

645+
impl LogDetector for WebArchiveProbeDetector {
646+
fn id(&self) -> &'static str {
647+
"web.archive-probe"
648+
}
649+
650+
fn family(&self) -> DetectorFamily {
651+
DetectorFamily::Web
652+
}
653+
654+
fn detect(&self, entries: &[LogEntry]) -> Vec<DetectorFinding> {
655+
let matches = matching_entries(
656+
entries,
657+
&[
658+
".zip",
659+
".tar.gz",
660+
".tgz",
661+
".sql",
662+
".7z",
663+
".rar",
664+
".tar.bz2",
665+
".tar.xz",
666+
".dump",
667+
".bak",
668+
],
669+
);
670+
671+
if matches.len() < 3 {
672+
return Vec::new();
673+
}
674+
675+
vec![DetectorFinding {
676+
detector_id: self.id().to_string(),
677+
family: self.family(),
678+
description: format!(
679+
"Suspicious archive/backup file probing detected in {} HTTP requests",
680+
matches.len()
681+
),
682+
severity: threshold_severity(matches.len(), 3, 8),
683+
confidence: 82,
684+
sample_line: matches[0].line.clone(),
685+
}]
686+
}
687+
}
688+
643689
fn matching_entries<'a>(entries: &'a [LogEntry], patterns: &[&str]) -> Vec<&'a LogEntry> {
644690
entries
645691
.iter()

src/sniff/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ pub struct SniffPassResult {
442442

443443
fn should_auto_ban(anomaly: &analyzer::LogAnomaly) -> bool {
444444
if let Some(detector_id) = anomaly.detector_id.as_deref() {
445-
if matches!(detector_id, "web.login-bruteforce" | "web.path-traversal") {
445+
if matches!(detector_id, "web.login-bruteforce" | "web.path-traversal" | "web.archive-probe") {
446446
return true;
447447
}
448448
}

0 commit comments

Comments
 (0)