72 lines
2.4 KiB
Python
72 lines
2.4 KiB
Python
"""Each tool normalizer is exercised against its committed fixture."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from recon_triage.schema import Severity
|
|
from recon_triage.tools import dnsx, httpx, naabu, nmap, nuclei, subfinder
|
|
|
|
FIXTURES = Path(__file__).parent / "fixtures"
|
|
|
|
|
|
def _read(name: str) -> str:
|
|
return (FIXTURES / name).read_text()
|
|
|
|
|
|
def test_subfinder_normalize():
|
|
hosts = subfinder.normalize(_read("subfinder.jsonl"))
|
|
assert "api.example.com" in hosts
|
|
assert "external.notmine.com" in hosts # scope filtering happens later, not here
|
|
assert len(hosts) == len(set(hosts)) # de-duped
|
|
|
|
|
|
def test_dnsx_normalize():
|
|
recs = dnsx.normalize(_read("dnsx.jsonl"))
|
|
by_host = {r.host: r for r in recs}
|
|
assert by_host["api.example.com"].ips == ["93.184.216.34"]
|
|
assert by_host["admin.example.com"].cname == ["internal.example.com"]
|
|
|
|
|
|
def test_naabu_normalize():
|
|
hits = naabu.normalize(_read("naabu.jsonl"))
|
|
ports = {(h.host, h.port) for h in hits}
|
|
assert ("api.example.com", 443) in ports
|
|
assert ("api.example.com", 22) in ports
|
|
assert all(isinstance(h.port, int) for h in hits)
|
|
|
|
|
|
def test_nmap_normalize_captures_product_version():
|
|
hosts = nmap.normalize(_read("nmap.xml"))
|
|
by_ip = {h.ip: h for h in hosts}
|
|
api = by_ip["93.184.216.34"]
|
|
svc443 = next(p.service for p in api.ports if p.number == 443)
|
|
assert svc443.product == "Apache httpd"
|
|
assert svc443.version == "2.4.49"
|
|
assert svc443.cpe == "cpe:/a:apache:http_server:2.4.49"
|
|
# multiple hosts and multiple ports handled (list coercion)
|
|
assert len(hosts) == 3
|
|
|
|
|
|
def test_nmap_handles_empty():
|
|
assert nmap.normalize("") == []
|
|
assert nmap.normalize("not xml at all") == []
|
|
|
|
|
|
def test_httpx_normalize():
|
|
probes = httpx.normalize(_read("httpx.jsonl"))
|
|
api = next(p for p in probes if p.host == "api.example.com")
|
|
assert api.info.status == 200
|
|
assert api.info.title == "API Gateway"
|
|
assert api.info.webserver == "Apache/2.4.49"
|
|
assert api.info.tls is not None
|
|
assert api.port == 443
|
|
|
|
|
|
def test_nuclei_normalize_severity():
|
|
findings = nuclei.normalize(_read("nuclei.jsonl"))
|
|
by_id = {f.template_id: f for f in findings}
|
|
assert by_id["tomcat-manager-exposed"].severity == Severity.HIGH.value
|
|
assert by_id["apache-detect"].severity == Severity.INFO.value
|
|
assert by_id["tomcat-manager-exposed"].reference # references preserved
|