Files
fn_registry/python/functions/cybersecurity/scan_tcp_ports.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

5.8 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
scan_tcp_ports function py cybersecurity 1.0.0 impure def scan_tcp_ports(host: str, ports: str | list[int] = 'common', timeout_s: float = 1.0, workers: int = 100) -> dict Connect-scan TCP concurrente de un host sobre una lista o rango de puertos usando SOLO stdlib (socket + ThreadPoolExecutor). NO requiere nmap ni sudo: es un connect-scan simple (full handshake) que clasifica cada puerto en open/closed/filtered y los corre en paralelo con threads. Complementa a nmap_scan para escaneo rapido en Python puro; NO detecta version de servicio. Acepta ports como lista de ints, preset 'common', rango '1-1024' o CSV '22,80,443'. NO lanza: devuelve dict status ok/error con campo raw legible para evidencia OSINT.
recon
cybersecurity
port-scan
tcp
network
name desc
host Hostname o IP objetivo a escanear (ej. 'scanme.nmap.org', '127.0.0.1', '192.168.1.10'). Se resuelve a IP con socket.gethostbyname; si no resuelve devuelve status error. Vacio devuelve status error.
name desc
ports Especificacion de puertos. Cuatro formas: lista de ints [22,80,443]; string preset 'common' (~30 puertos comunes: 21,22,23,25,53,80,110,135,139,143,443,445,993,995,3306,3389,5432,5900,6379,8080,8443,27017... default); string rango '1-1024'; string CSV '22,80,443' (admite rangos mezclados '22,80,8000-8010'). Se normaliza a lista ordenada de ints unicos en 1..65535. Spec invalida devuelve status error.
name desc
timeout_s Timeout por conexion TCP en segundos (float). Default 1.0. Valor bajo en redes lentas puede marcar puertos realmente abiertos como filtered.
name desc
workers Numero de hilos concurrentes del ThreadPoolExecutor. Default 100. Se acota internamente a >=1 y al numero de puertos a escanear. Valores muy altos pueden saturar descriptores de archivo o la red local.
dict de estado. ok: {status:'ok', host, ip (resuelta), ports_scanned:int, open:[int] (ordenada), closed_count:int, filtered_count:int, results:[{port:int, state:'open'|'closed'|'filtered'}] (ordenado por puerto), raw:str (bloque PORT/STATE legible con open+filtered, omite closed)}. error (host no resuelve, spec invalida, host vacio): {status:'error', error:str, host}. Nunca lanza excepciones.
false error_py_core
true
test_parse_ports_common
test_parse_ports_rango
test_parse_ports_csv
test_parse_ports_lista
test_scan_localhost_puerto_abierto
test_scan_host_no_resuelve_error
test_scan_host_vacio_error
test_scan_spec_invalida_error
python/functions/cybersecurity/scan_tcp_ports_test.py python/functions/cybersecurity/scan_tcp_ports.py

Ejemplo

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

# 1) Puertos comunes contra el host oficial de pruebas de nmap (legal escanear).
res = scan_tcp_ports("scanme.nmap.org", ports="common", timeout_s=1.0)
if res["status"] == "ok":
    print(res["ip"], "abiertos:", res["open"])   # ej. 45.33.32.156 abiertos: [22, 80]
    print(res["raw"])                             # bloque PORT/STATE para el vault
else:
    print("error:", res["error"])

# 2) Rango de puertos concreto en localhost.
res = scan_tcp_ports("127.0.0.1", ports="1-1024", timeout_s=0.3, workers=200)
print(res["open"])

# 3) Lista explicita de puertos.
res = scan_tcp_ports("192.168.1.10", ports=[22, 80, 443, 8080])

Invocacion directa por el registry:

# Via MCP (preferido):
#   mcp__registry__fn_run id="scan_tcp_ports_py_cybersecurity" args=["scanme.nmap.org"]
# Via CLI:
./fn run scan_tcp_ports scanme.nmap.org

Cuando usarla

Usala cuando quieras saber rapidamente que puertos TCP estan abiertos en UN host sin depender de nmap ni de sudo: escaneo en Python puro, scriptable y headless. Ideal en entornos donde no puedes instalar nmap o quieres un sondeo ligero de la superficie expuesta (un puñado de puertos o un rango pequeño) antes de pasar a herramientas mas pesadas.

A diferencia de nmap_scan_py_cybersecurity: este NO da version ni nombre del servicio, solo el estado del puerto (open/closed/filtered). Si necesitas deteccion de version (-sV), scripts NSE, OS detection, UDP o barrido de subred, usa nmap_scan. Para un check rapido "que puertos responden" en 1 host, esta es mas directa.

Gotchas

  • Funcion impura: abre conexiones TCP reales (full three-way handshake). Es un connect-scan, por lo que NO es sigiloso: queda en los logs del objetivo y es facilmente detectable por IDS/firewalls. Sin sudo no hace SYN-scan (half-open).
  • LEGAL: escanear puertos de hosts de terceros sin autorizacion puede ser delito. Escanea solo objetivos propios o con permiso explicito. scanme.nmap.org es el host oficial de pruebas de nmap (legal escanear).
  • timeout_s bajo en redes lentas o con alta latencia puede marcar puertos realmente ABIERTOS como filtered (la conexion no completa a tiempo). Sube timeout_s si dudas de los resultados; bajalo para escanear rangos grandes mas rapido a costa de falsos filtered.
  • workers muy alto (miles) puede agotar descriptores de archivo del proceso o saturar la red local / el objetivo. Se acota internamente al numero de puertos, pero un rango grande con workers altos sigue siendo agresivo.
  • Distincion de estados: open = connect exito; closed = RST / connection refused (host vivo, puerto cerrado); filtered = timeout / inalcanzable (probable firewall que descarta el paquete). Un host detras de firewall drop-all puede devolver TODO filtered aunque tenga servicios.
  • Solo IPv4: usa socket.gethostbyname (resuelve a A record). Para IPv6 usar otra ruta. No lanza: revisa siempre res["status"] antes de leer open/results.