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>
207 lines
9.3 KiB
Python
207 lines
9.3 KiB
Python
"""Mapeo puro de número de puerto a servicio IANA well-known.
|
|
|
|
Tabla estática embebida que asocia (puerto, protocolo) con el servicio que la
|
|
convención IANA / nmap-services espera típicamente en ese puerto, más una
|
|
descripción corta. Sin red, sin I/O: dado un puerto abierto detectado por un
|
|
scanner, esta función dice qué servicio se ESPERA ahí por convención, no lo
|
|
verifica en vivo.
|
|
"""
|
|
|
|
# (port, proto) -> (service, description)
|
|
WELL_KNOWN: dict[tuple[int, str], tuple[str, str]] = {
|
|
(20, "tcp"): ("ftp-data", "FTP Data Transfer"),
|
|
(21, "tcp"): ("ftp", "File Transfer Protocol (control)"),
|
|
(22, "tcp"): ("ssh", "Secure Shell"),
|
|
(23, "tcp"): ("telnet", "Telnet"),
|
|
(25, "tcp"): ("smtp", "Simple Mail Transfer Protocol"),
|
|
(37, "tcp"): ("time", "Time Protocol"),
|
|
(43, "tcp"): ("whois", "WHOIS Directory Service"),
|
|
(53, "tcp"): ("dns", "Domain Name System (zone transfer)"),
|
|
(53, "udp"): ("dns", "Domain Name System"),
|
|
(67, "udp"): ("dhcp", "DHCP Server (BOOTP)"),
|
|
(68, "udp"): ("dhcp", "DHCP Client (BOOTP)"),
|
|
(69, "udp"): ("tftp", "Trivial File Transfer Protocol"),
|
|
(79, "tcp"): ("finger", "Finger Protocol"),
|
|
(80, "tcp"): ("http", "Hypertext Transfer Protocol"),
|
|
(88, "tcp"): ("kerberos", "Kerberos Authentication"),
|
|
(110, "tcp"): ("pop3", "Post Office Protocol v3"),
|
|
(111, "tcp"): ("rpcbind", "ONC RPC / Portmapper"),
|
|
(111, "udp"): ("rpcbind", "ONC RPC / Portmapper"),
|
|
(113, "tcp"): ("ident", "Ident / Auth Service"),
|
|
(119, "tcp"): ("nntp", "Network News Transfer Protocol"),
|
|
(123, "udp"): ("ntp", "Network Time Protocol"),
|
|
(135, "tcp"): ("msrpc", "Microsoft RPC Endpoint Mapper"),
|
|
(137, "udp"): ("netbios-ns", "NetBIOS Name Service"),
|
|
(138, "udp"): ("netbios-dgm", "NetBIOS Datagram Service"),
|
|
(139, "tcp"): ("netbios-ssn", "NetBIOS Session Service"),
|
|
(143, "tcp"): ("imap", "Internet Message Access Protocol"),
|
|
(161, "udp"): ("snmp", "Simple Network Management Protocol"),
|
|
(162, "udp"): ("snmptrap", "SNMP Trap"),
|
|
(177, "udp"): ("xdmcp", "X Display Manager Control Protocol"),
|
|
(179, "tcp"): ("bgp", "Border Gateway Protocol"),
|
|
(389, "tcp"): ("ldap", "Lightweight Directory Access Protocol"),
|
|
(427, "tcp"): ("svrloc", "Service Location Protocol"),
|
|
(443, "tcp"): ("https", "HTTP over TLS/SSL"),
|
|
(445, "tcp"): ("smb", "SMB / Microsoft Directory Services"),
|
|
(464, "tcp"): ("kpasswd", "Kerberos Password Change"),
|
|
(465, "tcp"): ("smtps", "SMTP over TLS/SSL"),
|
|
(500, "udp"): ("isakmp", "ISAKMP / IKE (IPsec)"),
|
|
(512, "tcp"): ("exec", "Remote Process Execution (rexec)"),
|
|
(513, "tcp"): ("login", "Remote Login (rlogin)"),
|
|
(514, "tcp"): ("shell", "Remote Shell (rsh)"),
|
|
(514, "udp"): ("syslog", "Syslog"),
|
|
(515, "tcp"): ("printer", "Line Printer Daemon (LPD)"),
|
|
(520, "udp"): ("rip", "Routing Information Protocol"),
|
|
(523, "tcp"): ("ibm-db2", "IBM DB2"),
|
|
(548, "tcp"): ("afp", "Apple Filing Protocol"),
|
|
(554, "tcp"): ("rtsp", "Real Time Streaming Protocol"),
|
|
(587, "tcp"): ("submission", "SMTP Mail Submission"),
|
|
(623, "udp"): ("ipmi", "IPMI / RMCP"),
|
|
(631, "tcp"): ("ipp", "Internet Printing Protocol"),
|
|
(636, "tcp"): ("ldaps", "LDAP over TLS/SSL"),
|
|
(873, "tcp"): ("rsync", "rsync File Synchronization"),
|
|
(902, "tcp"): ("vmware", "VMware ESXi / Authentication"),
|
|
(989, "tcp"): ("ftps-data", "FTP Data over TLS/SSL"),
|
|
(990, "tcp"): ("ftps", "FTP over TLS/SSL"),
|
|
(993, "tcp"): ("imaps", "IMAP over TLS/SSL"),
|
|
(995, "tcp"): ("pop3s", "POP3 over TLS/SSL"),
|
|
(1080, "tcp"): ("socks", "SOCKS Proxy"),
|
|
(1194, "udp"): ("openvpn", "OpenVPN"),
|
|
(1352, "tcp"): ("lotusnotes", "IBM Lotus Notes / Domino"),
|
|
(1433, "tcp"): ("mssql", "Microsoft SQL Server"),
|
|
(1434, "udp"): ("mssql-m", "Microsoft SQL Monitor"),
|
|
(1521, "tcp"): ("oracle", "Oracle Database Listener"),
|
|
(1723, "tcp"): ("pptp", "Point-to-Point Tunneling Protocol"),
|
|
(1883, "tcp"): ("mqtt", "MQTT Message Broker"),
|
|
(2049, "tcp"): ("nfs", "Network File System"),
|
|
(2082, "tcp"): ("cpanel", "cPanel"),
|
|
(2083, "tcp"): ("cpanel-ssl", "cPanel over TLS/SSL"),
|
|
(2181, "tcp"): ("zookeeper", "Apache ZooKeeper"),
|
|
(2375, "tcp"): ("docker", "Docker API (unencrypted)"),
|
|
(2376, "tcp"): ("docker-ssl", "Docker API over TLS"),
|
|
(2483, "tcp"): ("oracle-db", "Oracle DB (insecure)"),
|
|
(2484, "tcp"): ("oracle-db-ssl", "Oracle DB over TLS/SSL"),
|
|
(3000, "tcp"): ("dev-http", "Development HTTP / Grafana"),
|
|
(3128, "tcp"): ("squid", "Squid HTTP Proxy"),
|
|
(3268, "tcp"): ("globalcat", "LDAP Global Catalog"),
|
|
(3306, "tcp"): ("mysql", "MySQL / MariaDB"),
|
|
(3389, "tcp"): ("rdp", "Remote Desktop Protocol"),
|
|
(3690, "tcp"): ("svn", "Subversion"),
|
|
(4369, "tcp"): ("epmd", "Erlang Port Mapper Daemon"),
|
|
(4444, "tcp"): ("metasploit", "Metasploit Default Listener"),
|
|
(4505, "tcp"): ("saltstack", "SaltStack Publish"),
|
|
(4506, "tcp"): ("saltstack", "SaltStack Request"),
|
|
(5000, "tcp"): ("upnp", "UPnP / Flask Dev Server"),
|
|
(5060, "udp"): ("sip", "Session Initiation Protocol"),
|
|
(5061, "tcp"): ("sips", "SIP over TLS"),
|
|
(5432, "tcp"): ("postgresql", "PostgreSQL Database"),
|
|
(5601, "tcp"): ("kibana", "Kibana"),
|
|
(5672, "tcp"): ("amqp", "Advanced Message Queuing (RabbitMQ)"),
|
|
(5900, "tcp"): ("vnc", "Virtual Network Computing"),
|
|
(5984, "tcp"): ("couchdb", "Apache CouchDB"),
|
|
(5985, "tcp"): ("winrm", "Windows Remote Management (HTTP)"),
|
|
(5986, "tcp"): ("winrm-ssl", "Windows Remote Management (HTTPS)"),
|
|
(6379, "tcp"): ("redis", "Redis Key-Value Store"),
|
|
(6443, "tcp"): ("kubernetes", "Kubernetes API Server"),
|
|
(6660, "tcp"): ("irc", "Internet Relay Chat"),
|
|
(6667, "tcp"): ("irc", "Internet Relay Chat"),
|
|
(7001, "tcp"): ("weblogic", "Oracle WebLogic"),
|
|
(8000, "tcp"): ("http-alt", "HTTP Alternate / Dev Server"),
|
|
(8008, "tcp"): ("http-alt", "HTTP Alternate"),
|
|
(8080, "tcp"): ("http-proxy", "HTTP Proxy / Alternate"),
|
|
(8086, "tcp"): ("influxdb", "InfluxDB"),
|
|
(8088, "tcp"): ("http-alt", "HTTP Alternate / Hadoop"),
|
|
(8443, "tcp"): ("https-alt", "HTTPS Alternate"),
|
|
(8500, "tcp"): ("consul", "HashiCorp Consul"),
|
|
(8888, "tcp"): ("http-alt", "HTTP Alternate / Jupyter"),
|
|
(9000, "tcp"): ("http-alt", "HTTP Alternate / PHP-FPM / SonarQube"),
|
|
(9042, "tcp"): ("cassandra", "Apache Cassandra (CQL)"),
|
|
(9092, "tcp"): ("kafka", "Apache Kafka Broker"),
|
|
(9200, "tcp"): ("elasticsearch", "Elasticsearch HTTP"),
|
|
(9300, "tcp"): ("elasticsearch", "Elasticsearch Transport"),
|
|
(9418, "tcp"): ("git", "Git Protocol"),
|
|
(9999, "tcp"): ("http-alt", "HTTP Alternate / Admin"),
|
|
(10000, "tcp"): ("webmin", "Webmin Admin Panel"),
|
|
(11211, "tcp"): ("memcached", "Memcached"),
|
|
(15672, "tcp"): ("rabbitmq-mgmt", "RabbitMQ Management UI"),
|
|
(27017, "tcp"): ("mongodb", "MongoDB Database"),
|
|
(27018, "tcp"): ("mongodb", "MongoDB Shard"),
|
|
(50000, "tcp"): ("sap", "SAP / DB2 DRDA"),
|
|
}
|
|
|
|
|
|
def identify_port_service(port: int, proto: str = "tcp") -> dict:
|
|
"""Identifica el servicio IANA well-known esperado en un puerto.
|
|
|
|
Función pura: consulta una tabla estática embebida, sin red ni I/O. Indica
|
|
qué servicio se ESPERA por convención en ese puerto, no verifica que sea el
|
|
que realmente corre allí.
|
|
|
|
Args:
|
|
port: número de puerto (0-65535).
|
|
proto: protocolo, "tcp" o "udp" (default "tcp"). Se normaliza a minúsculas.
|
|
|
|
Returns:
|
|
dict con claves:
|
|
- port (int): el puerto consultado.
|
|
- proto (str): el protocolo normalizado.
|
|
- service (str): nombre del servicio; "unknown" si no está en la
|
|
tabla; "invalid" si el puerto está fuera de rango o el protocolo
|
|
no es tcp/udp.
|
|
- description (str): descripción corta; "" cuando no se conoce.
|
|
- known (bool): True solo si hay match en la tabla.
|
|
|
|
Ejemplos de retorno:
|
|
identify_port_service(22)
|
|
-> {"port": 22, "proto": "tcp", "service": "ssh",
|
|
"description": "Secure Shell", "known": True}
|
|
identify_port_service(99999)
|
|
-> {"port": 99999, "proto": "tcp", "service": "invalid",
|
|
"description": "", "known": False}
|
|
"""
|
|
proto_norm = str(proto).strip().lower()
|
|
|
|
if not isinstance(port, int) or isinstance(port, bool):
|
|
return {
|
|
"port": port,
|
|
"proto": proto_norm,
|
|
"service": "invalid",
|
|
"description": "",
|
|
"known": False,
|
|
}
|
|
|
|
if port < 0 or port > 65535 or proto_norm not in ("tcp", "udp"):
|
|
return {
|
|
"port": port,
|
|
"proto": proto_norm,
|
|
"service": "invalid",
|
|
"description": "",
|
|
"known": False,
|
|
}
|
|
|
|
match = WELL_KNOWN.get((port, proto_norm))
|
|
if match is None:
|
|
return {
|
|
"port": port,
|
|
"proto": proto_norm,
|
|
"service": "unknown",
|
|
"description": "",
|
|
"known": False,
|
|
}
|
|
|
|
service, description = match
|
|
return {
|
|
"port": port,
|
|
"proto": proto_norm,
|
|
"service": service,
|
|
"description": description,
|
|
"known": True,
|
|
}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import json
|
|
|
|
for p, pr in [(22, "tcp"), (443, "tcp"), (53, "udp"), (3306, "tcp"), (99999, "tcp")]:
|
|
print(json.dumps(identify_port_service(p, pr)))
|