pySigma-backend-sqlite 1.1.0__tar.gz → 1.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pysigma_backend_sqlite-1.1.0 → pysigma_backend_sqlite-1.1.2}/PKG-INFO +13 -12
- {pysigma_backend_sqlite-1.1.0 → pysigma_backend_sqlite-1.1.2}/README.md +11 -10
- {pysigma_backend_sqlite-1.1.0 → pysigma_backend_sqlite-1.1.2}/pyproject.toml +3 -2
- {pysigma_backend_sqlite-1.1.0 → pysigma_backend_sqlite-1.1.2}/sigma/backends/sqlite/sqlite.py +57 -0
- {pysigma_backend_sqlite-1.1.0 → pysigma_backend_sqlite-1.1.2}/LICENSE +0 -0
- {pysigma_backend_sqlite-1.1.0 → pysigma_backend_sqlite-1.1.2}/sigma/backends/sqlite/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pySigma-backend-sqlite
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: pySigma sqlite backend
|
|
5
5
|
License-Expression: LGPL-3.0-only
|
|
6
6
|
License-File: LICENSE
|
|
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.13
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
-
Requires-Dist: pysigma (>=1.0.2
|
|
15
|
+
Requires-Dist: pysigma (>=1.0.2,<=2.0)
|
|
16
16
|
Project-URL: Repository, https://github.com/SigmaHQ/pySigma-backend-sqlite
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
|
|
@@ -126,17 +126,18 @@ from sigma.backends.sqlite import sqlite
|
|
|
126
126
|
from sigma.pipelines.sysmon import sysmon_pipeline
|
|
127
127
|
from sigma.pipelines.windows import windows_logsource_pipeline
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
#
|
|
132
|
-
|
|
133
|
-
#
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
combined_pipeline = piperesolver.resolve(piperesolver.pipelines)
|
|
138
|
-
# Instantiate backend using the combined pipeline
|
|
129
|
+
# Combine pipelines to map both Channel and EventID:
|
|
130
|
+
# 1. sysmon_pipeline: maps category (e.g., process_creation) -> EventID (e.g., 1)
|
|
131
|
+
# and changes logsource to service=sysmon
|
|
132
|
+
# 2. windows_logsource_pipeline: maps service=sysmon -> Channel
|
|
133
|
+
#
|
|
134
|
+
# For process_creation/windows, this produces:
|
|
135
|
+
# Channel='Microsoft-Windows-Sysmon/Operational' AND EventID=1
|
|
136
|
+
combined_pipeline = sysmon_pipeline() + windows_logsource_pipeline()
|
|
139
137
|
sqlite_backend = sqlite.sqliteBackend(combined_pipeline)
|
|
138
|
+
# Set the table name for the generated SQL queries
|
|
139
|
+
sqlite_backend.table = "logs"
|
|
140
|
+
|
|
140
141
|
|
|
141
142
|
rule = SigmaCollection.from_yaml(
|
|
142
143
|
r"""
|
|
@@ -108,17 +108,18 @@ from sigma.backends.sqlite import sqlite
|
|
|
108
108
|
from sigma.pipelines.sysmon import sysmon_pipeline
|
|
109
109
|
from sigma.pipelines.windows import windows_logsource_pipeline
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
#
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
combined_pipeline = piperesolver.resolve(piperesolver.pipelines)
|
|
120
|
-
# Instantiate backend using the combined pipeline
|
|
111
|
+
# Combine pipelines to map both Channel and EventID:
|
|
112
|
+
# 1. sysmon_pipeline: maps category (e.g., process_creation) -> EventID (e.g., 1)
|
|
113
|
+
# and changes logsource to service=sysmon
|
|
114
|
+
# 2. windows_logsource_pipeline: maps service=sysmon -> Channel
|
|
115
|
+
#
|
|
116
|
+
# For process_creation/windows, this produces:
|
|
117
|
+
# Channel='Microsoft-Windows-Sysmon/Operational' AND EventID=1
|
|
118
|
+
combined_pipeline = sysmon_pipeline() + windows_logsource_pipeline()
|
|
121
119
|
sqlite_backend = sqlite.sqliteBackend(combined_pipeline)
|
|
120
|
+
# Set the table name for the generated SQL queries
|
|
121
|
+
sqlite_backend.table = "logs"
|
|
122
|
+
|
|
122
123
|
|
|
123
124
|
rule = SigmaCollection.from_yaml(
|
|
124
125
|
r"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pySigma-backend-sqlite"
|
|
3
|
-
version = "1.1.
|
|
3
|
+
version = "1.1.2"
|
|
4
4
|
description = "pySigma sqlite backend"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -15,7 +15,7 @@ packages = [
|
|
|
15
15
|
|
|
16
16
|
[tool.poetry.dependencies]
|
|
17
17
|
python = "^3.10"
|
|
18
|
-
pysigma = ">=1.0.2
|
|
18
|
+
pysigma = ">=1.0.2,<=2.0"
|
|
19
19
|
|
|
20
20
|
[tool.poetry.group.dev.dependencies]
|
|
21
21
|
black = "^24.1"
|
|
@@ -50,3 +50,4 @@ coverage = "^7.4"
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
|
{pysigma_backend_sqlite-1.1.0 → pysigma_backend_sqlite-1.1.2}/sigma/backends/sqlite/sqlite.py
RENAMED
|
@@ -623,14 +623,69 @@ class sqliteBackend(TextQueryBackend):
|
|
|
623
623
|
|
|
624
624
|
return sqlite_query
|
|
625
625
|
|
|
626
|
+
def _extract_field_values_from_rule(
|
|
627
|
+
self, rule: SigmaRule, field_name: str
|
|
628
|
+
) -> List[Any]:
|
|
629
|
+
"""
|
|
630
|
+
Extract all values for a given field name from a rule's detection section.
|
|
631
|
+
Returns a list of unique values found for the specified field.
|
|
632
|
+
"""
|
|
633
|
+
from sigma.rule import SigmaDetectionItem
|
|
634
|
+
from sigma.types import SigmaString, SigmaNumber
|
|
635
|
+
|
|
636
|
+
values = set()
|
|
637
|
+
field_name_lower = field_name.lower()
|
|
638
|
+
|
|
639
|
+
# Iterate through all detection groups (sel, filter, etc.)
|
|
640
|
+
for detection_name, detection in rule.detection.detections.items():
|
|
641
|
+
# Each detection has detection_items
|
|
642
|
+
self._extract_values_from_detection(detection, field_name_lower, values)
|
|
643
|
+
|
|
644
|
+
return sorted(list(values), key=lambda x: str(x))
|
|
645
|
+
|
|
646
|
+
def _extract_values_from_detection(
|
|
647
|
+
self, detection, field_name_lower: str, values: set
|
|
648
|
+
) -> None:
|
|
649
|
+
"""
|
|
650
|
+
Recursively extract values from a detection for a given field name.
|
|
651
|
+
"""
|
|
652
|
+
from sigma.rule import SigmaDetectionItem
|
|
653
|
+
from sigma.types import SigmaString, SigmaNumber
|
|
654
|
+
|
|
655
|
+
# Check if detection has detection_items attribute
|
|
656
|
+
if hasattr(detection, 'detection_items'):
|
|
657
|
+
for item in detection.detection_items:
|
|
658
|
+
self._extract_values_from_detection(item, field_name_lower, values)
|
|
659
|
+
|
|
660
|
+
# Check if this is a SigmaDetectionItem with field and value
|
|
661
|
+
if hasattr(detection, 'field') and hasattr(detection, 'value'):
|
|
662
|
+
# Check if the field matches (case-insensitive)
|
|
663
|
+
if detection.field and detection.field.lower() == field_name_lower:
|
|
664
|
+
# Extract the values
|
|
665
|
+
for value in detection.value:
|
|
666
|
+
# Handle different value types
|
|
667
|
+
if isinstance(value, SigmaNumber):
|
|
668
|
+
values.add(value.number)
|
|
669
|
+
elif isinstance(value, SigmaString):
|
|
670
|
+
# SigmaString - convert to plain string
|
|
671
|
+
values.add(str(value))
|
|
672
|
+
else:
|
|
673
|
+
values.add(str(value))
|
|
674
|
+
|
|
626
675
|
def finalize_query_zircolite(
|
|
627
676
|
self, rule: Union[SigmaRule, SigmaCorrelationRule], query: str, index: int, state: ConversionState
|
|
628
677
|
) -> Any:
|
|
629
678
|
# For correlation rules, use the query as-is (already formatted)
|
|
630
679
|
if isinstance(rule, SigmaCorrelationRule):
|
|
631
680
|
sqlite_query = query
|
|
681
|
+
# Correlation rules don't have detection items in the same way
|
|
682
|
+
channels = []
|
|
683
|
+
event_ids = []
|
|
632
684
|
else:
|
|
633
685
|
sqlite_query = f"SELECT * FROM logs WHERE {query}"
|
|
686
|
+
# Extract channels and event IDs from the rule's detection
|
|
687
|
+
channels = self._extract_field_values_from_rule(rule, "Channel")
|
|
688
|
+
event_ids = self._extract_field_values_from_rule(rule, "EventID")
|
|
634
689
|
|
|
635
690
|
rule_as_dict = rule.to_dict()
|
|
636
691
|
|
|
@@ -651,6 +706,8 @@ class sqliteBackend(TextQueryBackend):
|
|
|
651
706
|
"level": rule_as_dict["level"] if "level" in rule_as_dict else "",
|
|
652
707
|
"rule": [sqlite_query],
|
|
653
708
|
"filename": "",
|
|
709
|
+
"channel": channels,
|
|
710
|
+
"eventid": event_ids,
|
|
654
711
|
}
|
|
655
712
|
return zircolite_rule
|
|
656
713
|
|
|
File without changes
|
{pysigma_backend_sqlite-1.1.0 → pysigma_backend_sqlite-1.1.2}/sigma/backends/sqlite/__init__.py
RENAMED
|
File without changes
|