fix: banner_regex sigs require actual banner match — prevents wrong type inference

Banner-specific signatures (e.g. AdGuard on port 3000) were incorrectly
matching when nmap returned no banner, causing wrong suggested_node_type
(e.g. 'router' for a media server). Now a signature with banner_regex is
only matched when a banner is present AND matches the regex.

Also make _PORT_TYPE_HINTS always contribute to suggest_node_type found set
(not just as elif fallback) so well-known ports like 8006 still resolve to
proxmox even when a generic sig also matched.
This commit is contained in:
Pouzor
2026-03-07 23:31:33 +01:00
parent 6e6041d871
commit 2441d72b41
2 changed files with 5 additions and 5 deletions
+2 -2
View File
@@ -21,7 +21,7 @@ def match_port(port: int, protocol: str, banner: str | None = None) -> dict[str,
for sig in _load():
if sig["port"] != port or sig["protocol"] != protocol:
continue
if sig.get("banner_regex") and banner and not re.search(sig["banner_regex"], banner, re.IGNORECASE):
if sig.get("banner_regex") and (not banner or not re.search(sig["banner_regex"], banner, re.IGNORECASE)):
continue
return sig
return None
@@ -95,7 +95,7 @@ def suggest_node_type(open_ports: list[dict[str, Any]]) -> str:
sig = match_port(port, proto)
if sig and sig.get("suggested_node_type"):
found.add(sig["suggested_node_type"])
elif port in _PORT_TYPE_HINTS:
if port in _PORT_TYPE_HINTS:
found.add(_PORT_TYPE_HINTS[port])
for t in priority:
if t in found:
+3 -3
View File
@@ -50,11 +50,11 @@ def test_match_port_with_banner_no_match_falls_through_to_next():
assert result["service_name"] == "Web UI"
def test_match_port_no_banner_matches_first_sig():
# no banner → banner check is skipped entirely, first matching sig wins
def test_match_port_no_banner_skips_banner_regex_sigs():
# no banner → banner_regex sigs are skipped, falls through to generic fallback
result = match_port(8006, "tcp", banner=None)
assert result is not None
assert result["service_name"] == "Proxmox API"
assert result["service_name"] == "Web UI"
# ── fingerprint_ports ─────────────────────────────────────────────────────────