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>
5.8 KiB
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. |
|
|
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 |
|
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.orges el host oficial de pruebas de nmap (legal escanear). timeout_sbajo en redes lentas o con alta latencia puede marcar puertos realmente ABIERTOS comofiltered(la conexion no completa a tiempo). Subetimeout_ssi dudas de los resultados; bajalo para escanear rangos grandes mas rapido a costa de falsos filtered.workersmuy 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 siempreres["status"]antes de leeropen/results.