(self, target: str)
| 337 | open_ports.append({"port": port, "scheme": scheme, |
| 338 | "url": f"{scheme}://{host}:{port}"}) |
| 339 | |
| 340 | threads = [threading.Thread(target=probe, args=(p,), daemon=True) |
| 341 | for p in COMMON_WEB_PORTS] |
| 342 | for t in threads: |
| 343 | t.start() |
| 344 | for t in threads: |
| 345 | t.join(timeout=6) |
| 346 | open_ports.sort(key=lambda p: p["port"]) |
| 347 | |
| 348 | result.findings = [ |
| 349 | _make_finding( |
| 350 | "port_scan", host, VulnSeverity.INFO, |
| 351 | title=f"Open port {p['port']}/tcp ({p['scheme'].upper()})", |
| 352 | description=f"{p['url']} is reachable and speaks {p['scheme']}.", |
| 353 | port=p["port"], matched_at=p["url"], |
| 354 | ) for p in open_ports |
| 355 | ] |
| 356 | result.artifacts = {"host": host, "ports": open_ports, |
| 357 | "scanned": list(COMMON_WEB_PORTS)} |
| 358 | # 'ok' when we found something; 'partial' when the sweep ran but nothing |
| 359 | # was open (still a valid, useful answer). |
| 360 | result.status = "ok" if open_ports else "partial" |
| 361 | result.duration_seconds = round(time.monotonic() - started, 2) |
| 362 | return result |
| 363 | |
| 364 | def _run_tls_audit(self, target: str) -> ReconResult: |
| 365 | result = ReconResult(recon_type=ReconType.TLS_AUDIT, target=target) |
| 366 | started = time.monotonic() |
| 367 | try: |
| 368 | from sslyze import ( |
| 369 | ServerNetworkLocation, |
| 370 | Scanner, |
| 371 | ServerScanRequest, |
| 372 | ScanCommand, |
| 373 | ) |
| 374 | except ImportError as exc: |
| 375 | result.status = "error" |
| 376 | result.error_message = f"sslyze not installed: {exc}" |
| 377 | result.duration_seconds = time.monotonic() - started |
| 378 | return result |
| 379 | |
| 380 | host, port = _split_host_port(target, default_port=443) |
| 381 | try: |
| 382 | location = ServerNetworkLocation(hostname=host, port=port) |
| 383 | request = ServerScanRequest( |
| 384 | server_location=location, |
| 385 | scan_commands={ |
| 386 | ScanCommand.CERTIFICATE_INFO, |
| 387 | ScanCommand.SSL_2_0_CIPHER_SUITES, |
| 388 | ScanCommand.SSL_3_0_CIPHER_SUITES, |
| 389 | ScanCommand.TLS_1_0_CIPHER_SUITES, |
| 390 | ScanCommand.TLS_1_1_CIPHER_SUITES, |
| 391 | ScanCommand.TLS_1_2_CIPHER_SUITES, |
| 392 | ScanCommand.TLS_1_3_CIPHER_SUITES, |
| 393 | ScanCommand.HEARTBLEED, |
| 394 | ScanCommand.ROBOT, |
| 395 | ScanCommand.OPENSSL_CCS_INJECTION, |
| 396 | ScanCommand.HTTP_HEADERS, |
nothing calls this directly
no test coverage detected