"""Diagnostic probes must match in request context, not as ordinary prose.""" import base64 import json import tempfile import unittest from pathlib import Path from urllib.parse import quote from netscaler_triage.engine import scan from netscaler_triage.matching import Matcher class CommandProbeTests(unittest.TestCase): def test_raw_url_and_base64_probes_reach_engine(self) -> None: commands = ["echo CHECK123&&date&&id", "id", "echo CHECK123"] lines = [] for command in commands: payload = quote(base64.b64encode(command.encode()).decode(), safe="") lines.append( "192.0.2.1 - - [01/Oct/2026:12:00:00 +0000] " f'"GET /vpn/example.php?x={payload} HTTP/1.1" 403 0 "-" "normal"' ) lines.append( "Oct 1 12:00:00 adc APPFW (GET https://192.0.2.1/vpn/theme/x.php?0=" + quote(commands[0], safe="") + ") " ) with tempfile.TemporaryDirectory() as tmp: root = Path(tmp).resolve() logs = root / "logs" logs.mkdir() (logs / "probes.log").write_text("\n".join(lines) + "\n") scan([("ADC", logs)], root / "out", []) findings = [ json.loads(x) for x in (root / "out/findings.jsonl").read_text().splitlines() ] self.assertEqual(len(findings), len(lines)) for finding in findings: self.assertTrue( any(x["name"] == "command_injection" for x in finding["rule_details"]) ) def test_ordinary_context_does_not_trigger_probe_or_handler_rules(self) -> None: matcher = Matcher([]) for event in [ {"raw": "id", "uri": "/health?id=42"}, {"raw": "echo CHECK123", "uri": "/search?q=echo"}, {"raw": "id", "uri": "/vpn/example.php"}, {"raw": "AddType application/x-httpd-php .php"}, {"raw": "AddType application/x-httpd-php-source .phps"}, ]: with self.subTest(event=event): names = {x["name"] for x in matcher.search_sigma(event)} self.assertFalse(names & {"command_injection", "ti_php_handler"}) self.assertTrue( any( x["name"] == "ti_php_handler" for x in matcher.search_sigma({"raw": "AddType application/x-httpd-php .sig"}) ) ) if __name__ == "__main__": unittest.main()