935008ec3f
Añade el capability group `recon` (dominio cybersecurity + pipelines, Python),
con la política de archivado OSINT y página madre docs/capabilities/recon.md.
Lookups y sondeo (wrappers de CLI):
- whois_lookup, rdap_lookup, dns_records, ping_host, traceroute_host, nmap_scan
- save_scan_to_osint (sink común) + recon_osint (pipeline one-shot scan+archivado)
Escaneo de puertos/servicios nativo (stdlib, sin nmap ni sudo):
- scan_tcp_ports: connect-scan TCP concurrente (open/closed/filtered)
- grab_service_banner: banner grab + identificación de servicio/versión real
- identify_port_service: puro, puerto -> servicio IANA esperado (~120 puertos)
- scan_port_services: pipeline one-shot (scan -> identify + banner por puerto abierto)
Fingerprint de tecnología web (estilo Wappalyzer), patrón pura/impura:
- fetch_http_fingerprint: GET stdlib, recoge headers/html/cookies (solo nombres)
- detect_web_tech: puro, matchea ~50 firmas regex -> tecnologías por categoría
- fingerprint_web_stack: pipeline one-shot url -> tecnologías
Todas devuelven dict {status} sin lanzar. Tests: 43 verdes, sin red externa.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
"""Tests para whois_lookup (CLI `whois`, estilo dict sin excepciones)."""
|
|
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.dirname(__file__))
|
|
|
|
from whois_lookup import parse_whois_raw, whois_lookup
|
|
|
|
SAMPLE = """\
|
|
Domain Name: GOOGLE.COM
|
|
Registrar: MarkMonitor Inc.
|
|
Registrant Country: US
|
|
Creation Date: 1997-09-15T04:00:00Z
|
|
Registry Expiry Date: 2028-09-14T04:00:00Z
|
|
Updated Date: 2019-09-09T15:39:04Z
|
|
Name Server: NS1.GOOGLE.COM
|
|
Name Server: NS2.GOOGLE.COM
|
|
"""
|
|
|
|
|
|
def test_parsea_campos_comunes():
|
|
"""Extrae registrar, pais, fechas y nameservers de un sample whois."""
|
|
parsed = parse_whois_raw(SAMPLE, "google.com")
|
|
|
|
assert parsed["status"] == "ok"
|
|
assert parsed["target"] == "google.com"
|
|
assert parsed["registrar"] == "MarkMonitor Inc."
|
|
assert parsed["registrant_country"] == "US"
|
|
assert parsed["creation_date"] == "1997-09-15T04:00:00Z"
|
|
assert parsed["expiry_date"] == "2028-09-14T04:00:00Z"
|
|
assert parsed["updated_date"] == "2019-09-09T15:39:04Z"
|
|
assert parsed["name_servers"] == ["ns1.google.com", "ns2.google.com"]
|
|
assert parsed["raw"] == SAMPLE
|
|
|
|
|
|
def test_campos_ausentes_quedan_none():
|
|
"""Un raw minimo deja los campos opcionales en None / lista vacia."""
|
|
parsed = parse_whois_raw("Domain Name: x.com\n", "x.com")
|
|
|
|
assert parsed["status"] == "ok"
|
|
assert parsed["registrar"] is None
|
|
assert parsed["creation_date"] is None
|
|
assert parsed["expiry_date"] is None
|
|
assert parsed["name_servers"] == []
|
|
|
|
|
|
def test_raw_siempre_presente():
|
|
"""El campo raw refleja siempre el texto de entrada tal cual."""
|
|
raw = "Random: noise\n"
|
|
parsed = parse_whois_raw(raw, "noise.test")
|
|
assert parsed["raw"] == raw
|
|
|
|
|
|
def test_target_vacio_devuelve_error():
|
|
"""Un target vacio devuelve status error sin lanzar."""
|
|
result = whois_lookup("")
|
|
assert result["status"] == "error"
|
|
assert "vacio" in result["error"]
|