mod common;
use common::{rsigma, temp_file};
use predicates::prelude::*;
const RULE: &str = r#"
title: Whoami
id: r-whoami
logsource:
category: process_creation
product: windows
detection:
selection:
CommandLine|contains: whoami
condition: selection
level: high
"#;
const SCHEMA_CONFIG: &str = r#"
routing:
on_unknown: warn
bindings:
- schema: ecs
pipelines: [ecs_windows]
"#;
#[test]
fn routes_ecs_event_through_bound_pipeline() {
let rule = temp_file(".yml", RULE);
let schema = temp_file(".yml", SCHEMA_CONFIG);
rsigma()
.args([
"engine",
"eval",
"-r",
rule.path().to_str().unwrap(),
"--schema-routing",
"--schema-config",
schema.path().to_str().unwrap(),
"-e",
r#"{"ecs.version":"8.0.0","process.command_line":"cmd /c whoami"}"#,
"--output-format",
"json",
])
.assert()
.success()
.stdout(predicate::str::contains("\"rule_id\":\"r-whoami\""));
}
#[test]
fn ecs_event_without_routing_does_not_match() {
let rule = temp_file(".yml", RULE);
rsigma()
.args([
"engine",
"eval",
"-r",
rule.path().to_str().unwrap(),
"-e",
r#"{"ecs.version":"8.0.0","process.command_line":"cmd /c whoami"}"#,
"--output-format",
"json",
])
.assert()
.success()
.stdout(predicate::str::contains("rule_id").not());
}
const CORR_RULES: &str = r#"
title: Whoami
id: r-whoami
logsource:
category: process_creation
product: windows
detection:
selection:
CommandLine|contains: whoami
condition: selection
level: high
---
title: Repeated whoami by user
correlation:
type: event_count
rules:
- r-whoami
group-by:
- User
timespan: 1h
condition:
gte: 2
level: high
"#;
#[test]
fn cross_schema_correlation_groups_same_user() {
let rule = temp_file(".yml", CORR_RULES);
let schema = temp_file(".yml", SCHEMA_CONFIG);
let stdin = concat!(
r#"{"ecs.version":"8.0.0","process.command_line":"cmd /c whoami","user.name":"alice"}"#,
"\n",
r#"{"CommandLine":"cmd /c whoami","User":"alice"}"#,
"\n",
);
rsigma()
.args([
"engine",
"eval",
"-r",
rule.path().to_str().unwrap(),
"--schema-routing",
"--schema-config",
schema.path().to_str().unwrap(),
"--output-format",
"ndjson",
])
.write_stdin(stdin)
.assert()
.success()
.stdout(predicate::str::contains("Repeated whoami by user"));
}