Fix pySigma RE2 compatibility in fresh installations
This commit is contained in:
1 parent
ff8dc9ee7a
commit
ae5a1a1e54
6 files changed
+56
-5
No files matched your search
@@ -31,6 +31,25 @@ netscaler-triage .\logs.7z
|
||||
|
||||
Installation may require internet access. Analysis runs offline.
|
||||
|
||||
### Update an existing installation
|
||||
|
||||
Activate the same virtual environment used to run the tool, then run from the
|
||||
repository directory:
|
||||
|
||||
```sh
|
||||
git pull
|
||||
python -m pip install --upgrade .
|
||||
netscaler-triage rules
|
||||
```
|
||||
|
||||
For an environment managed by uv, use `uv sync --locked` after `git pull`.
|
||||
Version 1.0.1 fixes installation failures reporting `invalid perl operator: (?=`
|
||||
or `SigmaRegularExpressionError` when loading the bundled rules. pySigma 2 changed
|
||||
its default validation engine to RE2, which rejects lookaheads. The package now
|
||||
requires compatible pySigma 1.x; detection patterns and timed matching are
|
||||
unchanged. Reinstalling with the command above also downgrades an incompatible
|
||||
pySigma installation. Rerun any scan that stopped with this error.
|
||||
|
||||
## Everyday use
|
||||
|
||||
```sh
|
||||
|
||||
@@ -162,3 +162,18 @@ source mapping and validation results remain outside the public release.
|
||||
A subsequent presentation correction exposes original-file SHA-256 matches in
|
||||
SUMMARY.txt even without an event match. Three focused presentation tests passed,
|
||||
including this separate hash-only case; Ruff, formatting and strict mypy passed.
|
||||
|
||||
DEPENDENCY COMPATIBILITY FIX — 2026-10-05
|
||||
|
||||
Version 1.0.0 was installed in an isolated environment with pySigma 2.0.0.
|
||||
The bundled-rule validation reproduced the reported RE2 rejection of lookahead
|
||||
syntax. Version 1.0.1 constrains pySigma to >=1.5.1,<2, keeping the existing
|
||||
detection patterns and timeout-protected matching unchanged.
|
||||
|
||||
Reinstalling the corrected package in that same environment automatically
|
||||
replaced pySigma 2.0.0 with 1.5.1. All 47 bundled Sigma rules validated, with
|
||||
246 explicit active indicators. All 138 tests passed against the installed
|
||||
package with Python warnings treated as errors. A new regression checks the
|
||||
reported lookahead pattern against raw and decoded text, including negative
|
||||
cases. Ruff lint, formatting and strict mypy across source and tests passed.
|
||||
This verification did not rerun the complete private forensic datasets.
|
||||
+3
-2
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "netscaler-triage"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
description = "Offline NetScaler evidence analysis with inspectable decoding and provenance"
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
@@ -17,7 +17,8 @@ dependencies = [
|
||||
"rich>=14.1",
|
||||
"rich-argparse>=1.7",
|
||||
"pyzipper>=0.3.6",
|
||||
"pysigma>=1.5.1",
|
||||
# pySigma 2 defaults to RE2, which rejects the supported lookahead rules.
|
||||
"pysigma>=1.5.1,<2",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
"""Offline analysis; no discovered payload is ever executed."""
|
||||
|
||||
__version__ = "1.0.0"
|
||||
__version__ = "1.0.1"
|
||||
@@ -13,6 +13,22 @@ def rule(detection: str, service: str = "") -> str:
|
||||
|
||||
|
||||
class SigmaTests(unittest.TestCase):
|
||||
def test_lookahead_rule_on_raw_and_decoded_text(self) -> None:
|
||||
matcher = SigmaMatcher.from_yaml(
|
||||
rule(
|
||||
" s:\n"
|
||||
" raw|re: '(?im)^(?=.*(?:pitboss|NSPPE))"
|
||||
"(?=.*(?:base64|PD9))(?=.*(?:2N|httpaccess))'\n"
|
||||
" condition: s\n"
|
||||
)
|
||||
)
|
||||
sample = "pitboss NSPPE base64 httpaccess"
|
||||
self.assertTrue(matcher.search({"raw": sample}))
|
||||
hits = matcher.search_with_details({"raw": "encoded record"}, [sample])
|
||||
self.assertEqual(hits[0]["basis"], ["decoded:0"])
|
||||
for benign in ("pitboss NSPPE", "base64 httpaccess", "NSPPE base64"):
|
||||
self.assertFalse(matcher.search({"raw": benign}))
|
||||
|
||||
def test_catalog_not_repeated_in_hit(self) -> None:
|
||||
text = rule(" s: [abc]\n condition: s\n")
|
||||
text += "indicators:\n - type: ipv4\n value: 192.0.2.1\n status: reference_only\n"
|
||||
|
||||
@@ -546,7 +546,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "netscaler-triage"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "py7zr" },
|
||||
@@ -569,7 +569,7 @@ dev = [
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "py7zr", specifier = ">=1.0" },
|
||||
{ name = "pysigma", specifier = ">=1.5.1" },
|
||||
{ name = "pysigma", specifier = ">=1.5.1,<2" },
|
||||
{ name = "pyzipper", specifier = ">=0.3.6" },
|
||||
{ name = "regex", specifier = ">=2025.11" },
|
||||
{ name = "rich", specifier = ">=14.1" },
|
||||
|
||||
Reference in new issue
Block a user