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:
@@ -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:
|
||||
|
||||
@@ -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 ─────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user