Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Validators and Environnement #6

Merged
merged 7 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ jobs:
permissions:
id-token: write
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install Poetry
run: pipx install poetry
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Verify versioning
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Install Poetry
run: pipx install poetry
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: poetry
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ Create all validators specific to the requirements of the SigmaHQ rules reposito
| sigmahq_invalid_fieldname | Check field name do not exist in the logsource. |
| sigmahq_level_existence | Checks if rule has a level. |
| sigmahq_link_description | Checks if rule description use a link instead of references. |
| sigmahq_logsource_valid | Checks if rule has valid logsource. |
| sigmahq_logsource_coherent | Checks if rule has Coherent logsource. |
| sigmahq_logsource_known | Checks if rule has known logsource. |
| sigmahq_space_fieldname | Check field name have a space. |
| sigmahq_status_deprecated | Checks if rule has a status DEPRECATED. |
| sigmahq_status_existence | Checks if rule has a status. |
Expand Down
217 changes: 109 additions & 108 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pySigma-validators-sigmahq"
version = "0.5.1"
version = "0.5.2"
description = "pySigma SigmaHQ validators"
authors = ["François Hubaut <[email protected]>"]
license = "LGPL-2.1-only"
Expand Down
16 changes: 15 additions & 1 deletion sigma/validators/sigmahq/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,10 @@
{"category": None, "product": "azure", "service": "pim"},
{"category": None, "product": "azure", "service": "riskdetection"},
{"category": None, "product": "azure", "service": "signinlogs"},
{"category": None, "product": "bitbucket", "service": "audit"},
{"category": None, "product": "cisco", "service": "aaa"},
{"category": None, "product": "cisco", "service": "bgp"},
{"category": None, "product": "cisco", "service": "duo"},
{"category": None, "product": "cisco", "service": "ldp"},
{"category": None, "product": "cisco", "service": "syslog"},
{"category": None, "product": "fortios", "service": "sslvpnd"},
Expand Down Expand Up @@ -395,11 +397,14 @@
{"category": None, "product": "zeek", "service": "smb_files"},
{"category": None, "product": "zeek", "service": "x509"},
{"category": "antivirus", "product": None, "service": None},
{"category": "appliance", "product": "paloalto", "service": "globalprotect"},
{"category": "application", "product": "django", "service": None},
{"category": "application", "product": "jvm", "service": None},
{"category": "application", "product": "kubernetes", "service": "audit"},
{"category": "application", "product": "modsecurity", "service": None},
{"category": "application", "product": "nodejs", "service": None},
{"category": "application", "product": "python", "service": None},
{"category": "application", "product": "opencanary", "service": None},
{"category": "application", "product": "qualys", "service": None},
{"category": "application", "product": "rpc_firewall", "service": None},
{"category": "application", "product": "ruby_on_rails", "service": None},
Expand All @@ -420,6 +425,7 @@
{"category": "file_event", "product": "linux", "service": None},
{"category": "file_event", "product": "macos", "service": None},
{"category": "file_event", "product": "macos", "service": None},
{"category": "file_event", "product": "paloalto", "service": "globalprotect"},
{"category": "file_event", "product": "windows", "service": None},
{"category": "file_executable_detected", "product": "windows", "service": None},
{"category": "file_rename", "product": "windows", "service": None},
Expand Down Expand Up @@ -1600,7 +1606,15 @@ def __init__(self) -> None:
field.extend(["Imphash", "md5", "sha1", "sha256"])

if v["log"]["product"] == "windows":
field.extend(["EventID", "Provider_Name"])
field.extend(
[
"EventID",
"Provider_Name",
"Channel",
"Computer",
"Security_UserID",
]
)

self.sigmahq_logsource_unicast[SigmaLogSource.from_dict(v["log"])] = [
x.lower() for x in field
Expand Down
29 changes: 23 additions & 6 deletions sigma/validators/sigmahq/logsource.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,34 @@


@dataclass
class SigmahqLogsourceValidIssue(SigmaValidationIssue):
description: ClassVar[str] = "Rule has an invalid logsource"
class SigmahqLogsourceKnownIssue(SigmaValidationIssue):
description: ClassVar[str] = "Rule has an unknown logsource"
severity: ClassVar[SigmaValidationIssueSeverity] = SigmaValidationIssueSeverity.HIGH
logsource: SigmaLogSource


class SigmahqLogsourceValidValidator(SigmaRuleValidator):
"""Checks if rule has valid logsource."""
class SigmahqLogsourceKnownValidator(SigmaRuleValidator):
"""Checks if rule has known logsource."""

def validate(self, rule: SigmaRule) -> List[SigmaValidationIssue]:
if rule.logsource and not rule.logsource in config.sigmahq_logsource_list:
return [SigmahqLogsourceValidIssue(rule, rule.logsource)]
if not rule.logsource in config.sigmahq_logsource_list:
return [SigmahqLogsourceKnownIssue(rule, rule.logsource)]
else:
return []


@dataclass
class SigmahqLogsourceCoherentIssue(SigmaValidationIssue):
description: ClassVar[str] = "Rule has an incoherent logsource"
severity: ClassVar[SigmaValidationIssueSeverity] = SigmaValidationIssueSeverity.HIGH
logsource: SigmaLogSource


class SigmahqLogsourceCoherentValidator(SigmaRuleValidator):
"""Checks if rule has Coherent logsource."""

def validate(self, rule: SigmaRule) -> List[SigmaValidationIssue]:
if rule.logsource.service and not rule.logsource.product:
return [SigmahqLogsourceCoherentIssue(rule, rule.logsource)]
else:
return []
49 changes: 49 additions & 0 deletions tests/test_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest
from sigma.rule import SigmaRule
from sigma.modifiers import SigmaRegularExpression

from sigma.validators.sigmahq.field import (
SigmahqSpaceFieldnameIssue,
Expand Down Expand Up @@ -326,3 +327,51 @@ def test_validator_SigmahqFieldDuplicateValueIssue_cased():
"""
)
assert validator.validate(rule) == []


def test_validator_SigmahqFieldDuplicateValueIssue_casesensitive():
validator = SigmahqFieldDuplicateValueValidator()
rule = SigmaRule.from_yaml(
"""
title: Re Duplicate Case Sensitive
status: test
logsource:
category: process_creation
product: windows
detection:
sel:
CommandLine|re:
- 'one'
- 'One'
- 'two'
- 'three'
- 'Two'
- 'One'
condition: sel
"""
)
assert validator.validate(rule) == [
SigmahqFieldDuplicateValueIssue(
rule, "CommandLine", str(SigmaRegularExpression(regexp="One", flags=set()))
)
]


def test_validator_SigmahqFieldDuplicateValueIssue_valid():
validator = SigmahqFieldDuplicateValueValidator()
rule = SigmaRule.from_yaml(
"""
title: Cased Duplicate
status: test
logsource:
category: process_creation
product: windows
detection:
sel:
CommandLine|contains:
- 'azertyy'
- 'qwerty'
condition: sel
"""
)
assert validator.validate(rule) == []
55 changes: 48 additions & 7 deletions tests/test_logsource.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
from sigma.rule import SigmaRule, SigmaLogSource

from sigma.validators.sigmahq.logsource import (
SigmahqLogsourceValidIssue,
SigmahqLogsourceValidValidator,
SigmahqLogsourceKnownIssue,
SigmahqLogsourceKnownValidator,
SigmahqLogsourceCoherentIssue,
SigmahqLogsourceCoherentValidator,
)


def test_validator_SigmahqSpaceFieldname():
validator = SigmahqLogsourceValidValidator()
def test_validator_SigmahqLogsourceKnown():
validator = SigmahqLogsourceKnownValidator()
rule = SigmaRule.from_yaml(
"""
title: A Space Field Name
Expand All @@ -25,12 +27,12 @@ def test_validator_SigmahqSpaceFieldname():
"""
)
assert validator.validate(rule) == [
SigmahqLogsourceValidIssue(rule, SigmaLogSource(category="test"))
SigmahqLogsourceKnownIssue(rule, SigmaLogSource(category="test"))
]


def test_validator_SigmahqSpaceFieldname_valid():
validator = SigmahqLogsourceValidValidator()
def test_validator_SigmahqLogsourceKnown_valid():
validator = SigmahqLogsourceKnownValidator()
rule = SigmaRule.from_yaml(
"""
title: A Space Field Name
Expand All @@ -46,3 +48,42 @@ def test_validator_SigmahqSpaceFieldname_valid():
"""
)
assert validator.validate(rule) == []


def test_validator_SigmahqLogsourceCoherent_service_alone():
validator = SigmahqLogsourceCoherentValidator()
rule = SigmaRule.from_yaml(
"""
title: A Space Field Name
status: test
logsource:
service: test
detection:
sel:
field: path\\*something
space name: 'error'
condition: sel
"""
)
assert validator.validate(rule) == [
SigmahqLogsourceCoherentIssue(rule, SigmaLogSource(service="test"))
]


def test_validator_SigmahqLogsourceCoherent_valid():
validator = SigmahqLogsourceCoherentValidator()
rule = SigmaRule.from_yaml(
"""
title: A Space Field Name
status: test
logsource:
product: test
service: test
detection:
sel:
field: path\\*something
space name: 'error'
condition: sel
"""
)
assert validator.validate(rule) == []