Skip to content

Commit

Permalink
Add SigmahqInvalidHashKvValidator
Browse files Browse the repository at this point in the history
  • Loading branch information
frack113 committed Aug 23, 2024
1 parent 4549212 commit 3c959f8
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 1 deletion.
53 changes: 52 additions & 1 deletion sigma/validators/sigmahq/field.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pathlib import Path
from dataclasses import dataclass
from typing import ClassVar, Dict, List
from typing import ClassVar, Dict, List, Tuple
import re

from sigma.rule import SigmaRule, SigmaLogSource
from sigma.types import SigmaString
Expand Down Expand Up @@ -240,3 +241,53 @@ def validate_detection_item(
return []
else:
return []


@dataclass
class SigmahqInvalidHashKvIssue(SigmaValidationIssue):
description: ClassVar[str] = (
"A Sysmon Hash search must be valid Hash_Type=Hash_Value"
)
severity: ClassVar[SigmaValidationIssueSeverity] = SigmaValidationIssueSeverity.HIGH
value: str


class SigmahqInvalidHashKvValidator(SigmaDetectionItemValidator):
"""Check field Sysmon Hash Key-Value search is valid."""

hash_field: Tuple[str] = ("Hashes", "Hash")
hash_key: Tuple[str] = ("MD5", "SHA1", "SHA256", "IMPHASH")

def validate_detection_item(
self, detection_item: SigmaDetectionItem
) -> List[SigmaValidationIssue]:

errors = []
if detection_item.field is not None and detection_item.field in self.hash_field:
for v in detection_item.value:
if isinstance(v, SigmaString):
# v.original is empty when use |contains
for s_value in v.s:
if isinstance(s_value, str):
try:
hash_name, hash_data = s_value.split("=")
if hash_name in self.hash_key:
match hash_name:
case "MD5":
hash_regex = r"^[a-fA-F0-9]{32}$"
case "SHA1":
hash_regex = r"^[a-fA-F0-9]{40}$"
case "SHA256":
hash_regex = r"^[a-fA-F0-9]{64}$"
case "IMPHASH":
hash_regex = r"^[a-fA-F0-9]{32}$"
if re.search(hash_regex, hash_data) is None:
errors.append(hash_data)
else:
errors.append(hash_name)
except ValueError:
errors.append(s_value)
else:
errors.append(v)

return [SigmahqInvalidHashKvIssue(self.rule, v) for v in errors]
96 changes: 96 additions & 0 deletions tests/test_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
SigmahqSpaceFieldNameValidator,
SigmahqFieldUserIssue,
SigmahqFieldUserValidator,
SigmahqInvalidHashKvIssue,
SigmahqInvalidHashKvValidator,
)


Expand Down Expand Up @@ -401,3 +403,97 @@ def test_validator_SigmahqFieldUserValidator():
assert validator.validate(rule) == [
SigmahqFieldUserIssue(rule, "UserName", "AUTORITE NT")
]


def test_validator_SigmahqInvalidHashKvValidator_invalidhashname():
validator = SigmahqInvalidHashKvValidator()
rule = SigmaRule.from_yaml(
"""
title: Sysmon Hash Validation
status: test
logsource:
category: process_creation
product: windows
detection:
sel:
Hashes|contains:
- 'MD5=4fae81eb7018069e75a087c38af783df'
- 'SHA512=123456'
condition: sel
"""
)
assert validator.validate(rule) == [SigmahqInvalidHashKvIssue(rule, "SHA512")]


def test_validator_SigmahqInvalidHashKvValidator_invalidhashdata():
validator = SigmahqInvalidHashKvValidator()
rule = SigmaRule.from_yaml(
"""
title: Sysmon Hash Validation
status: test
logsource:
category: process_creation
product: windows
detection:
sel:
Hashes|contains:
- 'MD5=4fae81eb7018069e75a087c38af783df'
- 'SHA256=123456'
condition: sel
"""
)
assert validator.validate(rule) == [SigmahqInvalidHashKvIssue(rule, "123456")]


def test_validator_SigmahqInvalidHashKvValidator_invalidtypo():
validator = SigmahqInvalidHashKvValidator()
rule = SigmaRule.from_yaml(
"""
title: Sysmon Hash Validation
status: test
logsource:
category: process_creation
product: windows
detection:
sel:
Hashes|contains: 'azerty'
condition: sel
"""
)
assert validator.validate(rule) == [SigmahqInvalidHashKvIssue(rule, "azerty")]


def test_validator_SigmahqInvalidHashKvValidator_invalidtype():
validator = SigmahqInvalidHashKvValidator()
rule = SigmaRule.from_yaml(
"""
title: Sysmon Hash Validation
status: test
logsource:
category: process_creation
product: windows
detection:
sel:
Hashes: 1234
condition: sel
"""
)
assert validator.validate(rule) == [SigmahqInvalidHashKvIssue(rule, 1234)]


def test_validator_SigmahqInvalidHashKvValidator_valid():
validator = SigmahqInvalidHashKvValidator()
rule = SigmaRule.from_yaml(
"""
title: Sysmon Hash Validation
status: test
logsource:
category: process_creation
product: windows
detection:
sel:
Hashes|contains: 'MD5=4fae81eb7018069e75a087c38af783df'
condition: sel
"""
)
assert validator.validate(rule) == []

0 comments on commit 3c959f8

Please sign in to comment.