Skip to content

Commit

Permalink
Merge pull request #1400 from Yamato-Security/1397-sigma-v2-exists-mo…
Browse files Browse the repository at this point in the history
…difier-support

added sigma v2 exists modifier support
  • Loading branch information
YamatoSecurity authored Aug 16, 2024
2 parents be52cf5 + 8a73c57 commit 5bce02d
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-Japanese.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* `i`: (insensitive) 大文字小文字を区別しないマッチングを無効にする。
* `m`: (multi-line) 複数行にまたがってマッチする。`^` /`$` は行頭/行末にマッチする。
* `s`: (single-line) ドット文字 (`.`) は改行文字を含むすべての文字にマッチする。
- Sigma V2の`|exists`モディファイアに対応した。 (#1400) (@hitenkoku)

**改善:**

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* `i`: (insensitive) disable case-sensitive matching.
* `m`: (multi-line) match across multiple lines. `^` /`$` match the start/end of line.
* `s`: (single-line) the dot character (`.`) matches all characters, including the newline character.
- Support for the Sigma V2 `|exists` modifier. (#1400) (@hitenkoku)

**Enhancements:**

Expand Down
89 changes: 86 additions & 3 deletions src/detections/rule/matchers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,9 +578,9 @@ impl LeafMatcher for DefaultMatcher {
fn is_match(&self, event_value: Option<&String>, recinfo: &EvtxRecordInfo) -> bool {
let pipe: &PipeElement = self.pipes.first().unwrap_or(&PipeElement::Wildcard);
let match_result = match pipe {
PipeElement::EqualsField(_) | PipeElement::Endswithfield(_) => {
Some(pipe.is_eqfield_match(event_value, recinfo))
}
PipeElement::Exists(..)
| PipeElement::EqualsField(_)
| PipeElement::Endswithfield(_) => Some(pipe.is_eqfield_match(event_value, recinfo)),
PipeElement::Cidr(ip_result) => match ip_result {
Ok(matcher_ip) => {
let val = String::default();
Expand Down Expand Up @@ -686,6 +686,7 @@ enum PipeElement {
ReMultiLine,
ReSingleLine,
Wildcard,
Exists(String, String),
EqualsField(String),
Endswithfield(String),
Base64offset,
Expand All @@ -702,6 +703,10 @@ impl PipeElement {
"endswith" => Option::Some(PipeElement::Endswith),
"contains" => Option::Some(PipeElement::Contains),
"re" => Option::Some(PipeElement::Re),
"exists" => Option::Some(PipeElement::Exists(
key_list[0].split('|').collect::<Vec<&str>>()[0].to_string(),
pattern.to_string(),
)),
"reignorecase" => Option::Some(PipeElement::ReIgnoreCase),
"resingleline" => Option::Some(PipeElement::ReSingleLine),
"remultiline" => Option::Some(PipeElement::ReMultiLine),
Expand Down Expand Up @@ -735,6 +740,9 @@ impl PipeElement {

fn is_eqfield_match(&self, event_value: Option<&String>, recinfo: &EvtxRecordInfo) -> bool {
match self {
PipeElement::Exists(eq_key, val) => {
val.to_lowercase() == recinfo.get_value(eq_key).is_some().to_string()
}
PipeElement::EqualsField(eq_key) => {
let eq_value = recinfo.get_value(eq_key);
// Evtxのレコードに存在しないeventkeyを指定された場合はfalseにする
Expand Down Expand Up @@ -3275,6 +3283,31 @@ mod tests {
);
}

#[test]
fn test_exists_true() {
let rule_str = r#"
enabled: true
detection:
selection1:
Channel|exists: true
condition: selection1
"#;

let record_json_str = r#"
{
"Event": {
"System": {
"EventID": 1,
"Channel": "Microsoft-Windows-Sysmon/Operational"
},
"EventData": {
"CurrentDirectory": "C:\\Windows\\system32\\"
}
}
}"#;
check_select(rule_str, record_json_str, true);
}

#[test]
fn test_re_caseinsensitive_detect() {
let rule_str = r#"
Expand All @@ -3293,6 +3326,31 @@ mod tests {
check_select(rule_str, record_json_str, true);
}

#[test]
fn test_exists_null_true() {
let rule_str = r#"
enabled: true
detection:
selection1:
Channel|exists: true
condition: selection1
"#;

let record_json_str = r#"
{
"Event": {
"System": {
"EventID": 1,
"Channel": ""
},
"EventData": {
"CurrentDirectory": "C:\\Windows\\system32\\"
}
}
}"#;
check_select(rule_str, record_json_str, true);
}

#[test]
fn test_re_multiline_detect() {
let rule_str = r#"
Expand All @@ -3311,6 +3369,31 @@ mod tests {
check_select(rule_str, record_json_str, true);
}

#[test]
fn test_exists_false() {
let rule_str = r#"
enabled: true
detection:
selection1:
Dummy|exists: false
condition: selection1
"#;

let record_json_str = r#"
{
"Event": {
"System": {
"EventID": 1,
"Channel": ""
},
"EventData": {
"CurrentDirectory": "C:\\Windows\\system32\\"
}
}
}"#;
check_select(rule_str, record_json_str, true);
}

#[test]
fn test_re_singleline_detect() {
let rule_str = r#"
Expand Down

0 comments on commit 5bce02d

Please sign in to comment.