Files
fn_registry/python/functions/cybersecurity/nmap_scan.md
T
egutierrez 935008ec3f feat(recon): grupo de reconocimiento de red + servicios + fingerprint web
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>
2026-06-14 15:12:07 +02:00

8.2 KiB

name, kind, lang, domain, version, purity, signature, description, tags, params, output, uses_functions, uses_types, returns, returns_optional, error_type, imports, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags params output uses_functions uses_types returns returns_optional error_type imports tested tests test_file_path file_path
nmap_scan function py cybersecurity 1.1.0 impure def nmap_scan(target: str, profile: str = 'quick', ports: str | None = None, extra_args: list[str] | None = None, out_dir: str | None = None, timeout_s: int = 1800, confirm: bool = False, allowlist: list[str] | None = None) -> dict Wrapper de `nmap` por perfiles para reconocimiento de red. Ejecuta nmap como subprocess forzando salida XML (-oX), la parsea con ElementTree y devuelve puertos abiertos y hosts vivos de forma estructurada. Funcion estrella de recon: corre en primer plano (quick, top1000, service) y segundo plano para scans largos (full-tcp, vuln, udp-top). NO lanza: devuelve dict status ok/error. Sin sudo por defecto (connect-scan TCP).
recon
nmap
portscan
cybersecurity
name desc
target Host, IP o rango CIDR a escanear (ej. 'scanme.nmap.org', '192.168.1.10', o '192.168.1.0/24' con el perfil discovery). Vacio devuelve status error.
name desc
profile Clave de PROFILES que determina los flags de nmap. quick=(-T4 -F) top 100 puertos rapido; top1000=(-T4) los 1000 puertos default; full-tcp=(-p- -T4) los 65535 TCP, LARGO; service=(-sV -sC -T4) deteccion de version + scripts default; udp-top=(-sU --top-ports 100 -T4) UDP top 100, LARGO y suele requerir sudo; vuln=(-sV --script vuln -T4) scripts de vulnerabilidades, LARGO; discovery=(-sn) ping sweep / host discovery de una subred; aggressive=(-A -T4) OS+version+script+traceroute (el -O interno puede pedir sudo); os=(-O) OS detection, REQUIERE sudo/root. Perfil invalido devuelve status error listando los validos.
name desc
ports Especificacion de puertos para -p (ej. '22,80,443' o '1-1000'). Si se pasa, anade '-p <ports>' al comando. None deja los puertos que defina el perfil.
name desc
extra_args Lista de flags adicionales de nmap a anadir tal cual al comando (ej. ['--open', '-Pn']). None no anade nada.
name desc
out_dir Directorio donde guardar el XML. Si se pasa, se crea y el XML se guarda como nmap-<profile>-<target>-<timestamp>.xml (util para scans largos en background y conservar el resultado). None usa un archivo temporal.
name desc
timeout_s Segundos maximos de ejecucion del subprocess. Default 1800 (30 min). Para scans largos (full-tcp, vuln, udp-top) subir este valor; superarlo devuelve status error con mensaje claro.
name desc
confirm Confirmacion explicita para escanear un target publico o desconocido. Default False: si el target no es claramente privado/local (10.x, 192.168.x, 127.x, localhost, *.local/.lan/.internal/.home/.corp) y no esta en allowlist, el escaneo se rechaza con status error y needs_confirm=True (proteccion anti-escaneo no autorizado). Pasar True solo con autorizacion. No hace DNS lookup (sin red).
name desc
allowlist Lista de targets autorizados. Un target pasa el guard sin confirm si coincide exactamente con una entrada o termina en ella (ej. ['scanme.nmap.org'] o ['example.com']). None o lista vacia no autoriza nada.
dict. ok: {status:'ok', target, profile, command (cmd ejecutado), open_ports:[{port:int,proto,state,service,product,version}] (solo open/open|filtered), hosts_up:[ips] (host discovery), host_status, xml_path (siempre presente), raw (stdout de nmap, siempre presente), elapsed_s:float, started (ISO)}. error: {status:'error', error:str}. Si el guard rechaza el target (publico/desconocido sin confirm ni allowlist) el error tambien incluye needs_confirm:True. Nunca lanza excepciones.
false error_py_core
true
test_parse_xml_extrae_puertos_abiertos_y_hosts_up
test_guard_publico_sin_confirm_rechaza_y_no_ejecuta
test_guard_privado_procede_y_parsea
test_guard_confirm_true_sobre_publico_procede
test_guard_allowlist_procede
test_perfil_invalido_devuelve_error
test_target_vacio_devuelve_error
test_target_is_private_clasifica
python/functions/cybersecurity/nmap_scan_test.py python/functions/cybersecurity/nmap_scan.py

Ejemplo

import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from cybersecurity import nmap_scan

# 1) Scan rapido en primer plano contra el host oficial de pruebas de nmap
#    (scanme.nmap.org es legal escanear).
res = nmap_scan("scanme.nmap.org", profile="quick", timeout_s=120)
if res["status"] == "ok":
    for p in res["open_ports"]:
        print(p["port"], p["proto"], p["service"], p["product"], p["version"])
else:
    print("error:", res["error"])

# 2) Scan LARGO de los 65535 puertos TCP guardando el XML en out_dir.
#    Lanzar en segundo plano (background) por la duracion; el XML queda en disco.
res = nmap_scan(
    "scanme.nmap.org",
    profile="full-tcp",
    out_dir="/tmp/nmap-runs",
    timeout_s=7200,  # 2h: full-tcp puede tardar minutos a horas
    allowlist=["scanme.nmap.org"],  # autorizado -> pasa el guard sin confirm
)
print(res["status"], res.get("xml_path"))

# 3) Guard de seguridad: un target publico SIN confirm ni allowlist se rechaza.
res = nmap_scan("8.8.8.8")          # publico, sin confirm
print(res["status"], res.get("needs_confirm"))  # "error" True

# Para escanear un publico autorizado: confirm=True (o anadirlo a allowlist).
res = nmap_scan("8.8.8.8", confirm=True)
# Un target privado/local NO requiere confirm:
res = nmap_scan("192.168.1.10")     # procede directamente

Cuando usarla

Usala para el reconocimiento de puertos y servicios de un host: mapear la superficie de ataque antes de un pentest autorizado, descubrir que servicios y versiones expone una IP, o barrer una subred con profile="discovery" para ver que hosts estan vivos. Es la funcion estrella de recon del registry.

Para scans largos (full-tcp, vuln, udp-top) lanza la llamada en SEGUNDO PLANO: tardan de minutos a horas. Pasa out_dir para conservar el XML en disco y sube timeout_s (p.ej. 7200) para que no aborte por timeout.

Gotchas

  • GUARD anti-escaneo no autorizado: por defecto (confirm=False) la funcion RECHAZA con status error + needs_confirm=True cualquier target que no sea claramente privado/local (rangos privados, loopback, link-local, localhost, *.local/.lan/.internal/.home/.corp). Para escanear un target publico o un hostname desconocido tienes que pasar confirm=True o incluirlo en allowlist (match exacto o por sufijo). El guard NO hace DNS lookup (sin red, KISS): un hostname publico se considera "indecidible" y cae al lado seguro (requiere confirm). Esto NO sustituye tu responsabilidad legal — solo evita disparos accidentales contra infra ajena.
  • LEGAL: solo escanea hosts que sean tuyos o para los que tengas autorizacion explicita. scanme.nmap.org es el host oficial de pruebas de nmap, legal escanear; cualquier otro objetivo de terceros sin permiso puede ser delito.
  • Privilegios: los perfiles os (-O), udp-top (-sU) y parte de aggressive (-O interno) requieren sudo/root. Sin privilegios nmap cae a connect-scan TCP (-sT) y esos modos fallan o quedan incompletos — esta funcion no usa sudo.
  • Duracion: full-tcp (65535 puertos), vuln (scripts NSE) y udp-top (UDP es lento) tardan minutos a horas. Sube timeout_s y/o lanza en background con out_dir; superar timeout_s devuelve status error.
  • Deteccion: firewalls / IDS / WAF pueden detectar y bloquear el escaneo (sobre todo aggressive, vuln y -T4). El resultado puede venir filtrado o incompleto si el objetivo defiende activamente.
  • discovery (-sn) espera notacion de host o subred en CIDR (ej. "192.168.1.0/24"); puebla hosts_up, no open_ports.
  • No lanza excepciones: siempre revisa res["status"] antes de leer open_ports/hosts_up. raw y xml_path solo estan garantizados en ok.

Capability growth log

  • v1.1.0 (2026-06-14) — guard confirm/allowlist anti-escaneo-no-autorizado: targets publicos/desconocidos se rechazan (status error + needs_confirm) salvo confirm=True o estar en allowlist; privados/local proceden sin confirm. Sin DNS lookup. Anadidos tests (8 casos: parseo XML, guard publico/privado/confirm/ allowlist, perfil invalido, target vacio, clasificacion _target_is_private).