Saltar al contenido principal

Recon web profesional

Lanzar nmap para mapear una aplicación web es como hacer cirugía con un radar de tráfico. Nmap descubre que el puerto 443 está abierto — eso ya lo sabes, hay una web. Para mapear la superficie real de un monolito corporativo, tienes que comportarte exactamente como un usuario legítimo.
Esta página cubre el reconocimiento profesional sin levantar alertas: recon pasivo, fingerprinting silencioso, type confusion, JA3 y evasión de Client Hints. La metodología completa con árbol de decisión está en /metodologia.

Por qué Nmap no sirve aquí

El servidor está detrás de un WAF, un CDN y un API Gateway. Lo que Nmap toca es el primer escudo, no el cerebro.

Capa 0 — Recon pasivo absoluto (cero contacto)

No envías un solo paquete al servidor del cliente. Toda la información ya está pública.

Wayback Machine

Histórico de URLs del dominio. Endpoints obsoletos que los desarrolladores olvidaron borrar y que ya no pasan por las reglas del WAF actual.
🎯 Joyas que aparecen aquí:
  • /api/v1/auth (versión antigua sin rate limit)
  • /old/admin/login.php (panel viejo no migrado)
  • .env, .git/config, backup.sql (subidas accidentales)

Certificate Transparency

Todo certificado emitido se publica en logs públicos. Los SANs son una mina de subdominios.
🎯 Lo que aparece aquí:
  • staging.empresa.com, dev.empresa.com, qa.empresa.com
  • vpn.empresa.com, mail.empresa.com
  • Subdominios internos filtrados por error (internal-api.empresa.com)

Google / Shodan / Censys dorking

GitHub: secretos abandonados

Es el primer lugar donde mira un atacante moderno.
Joyas históricas: developers borran un commit con un secreto y asumen que está limpio. Pero el commit sigue en el historial hasta que se reescribe la rama. git log --all --full-history -p -- archivo.env lo revela.

Capa 1 — Análisis del frontend (DevTools, no escáner)

Tus conocimientos de desarrollo marcan la diferencia. El trabajo sucio lo hace el navegador, no un escáner que el WAF detectaría.

Source maps de React/Angular/Vue

Si el equipo de desarrollo subió los *.map a producción (lo hacen el 30 % del tiempo), tienes el código fuente original sin minificar.

JS bundles: buscar endpoints, tokens, comentarios

Aunque no haya source maps, los bundles minificados contienen las rutas de API hardcodeadas, tokens de prueba olvidados, comentarios y feature flags.
🎯 Lo que aparece aquí:
  • Endpoints internos: /api/v2/internal/users, /admin/debug
  • Feature flags activos: enable_legacy_auth: true
  • Tokens de Stripe/Mailgun/Sendgrid en modo dev olvidados
  • Comentarios con TODOs y advertencias

robots.txt, sitemap.xml, .well-known

Son los regalos de la casa. Casi siempre revelan rutas internas.

Capa 2 — Navegación proxificada (Burp pasivo)

Configura Burp Suite o OWASP ZAP como intermediario y navega manualmente. Crea cuenta, usa la app, rellena formularios con datos coherentes. 🎯 El objetivo en esta fase NO es atacar. Es:
  • Mapear el árbol de directorios real (lo que descubrió el navegador es una fracción).
  • Capturar todos los endpoints y verbos HTTP usados.
  • Diseccionar tokens de sesión (JWT, cookies).
  • Identificar parámetros susceptibles (IDs numéricos, paths, redirects).
Al WAF esto le parece tráfico 100 % legítimo, porque literalmente lo es.

Configuración mínima de Burp para sigilo


Capa 3 — Fingerprint del backend (sin disparar WAF)

Tras la navegación pasiva, ya conoces tokens, endpoints y estructura. Hora de identificar el lenguaje y framework del backend.

Las extensiones están muertas

Ninguna aplicación corporativa moderna expone el tipo de archivo en la URL. Olvídate de buscar .php o .aspx — el routing limpio te muestra /api/v1/auth y nada más.

Fingerprint por cookies de sesión

Los lenguajes tienen nombres por defecto. Si el equipo no las renombró (lo habitual), tienes la huella sin enviar nada.

Fingerprint por headers

Fingerprint por anatomía del error (la técnica reina)

Si las cabeceras están borradas y las cookies ofuscadas, fuerza un error controlado. No buscas inyectar nada — buscas que el parser del backend tropiece.

Type Confusion

La API espera un string. Le mandas otro tipo.
🎯 Cómo lee el resultado:

Manipulación de verbos HTTP

🎯 Lo que escupe el backend según verbo no soportado:
  • 405 Method Not Allowed con cuerpo JSON {"error":"..."} → framework moderno bien configurado.
  • 405 con HTML de error → puede ser Apache/Tomcat default page.
  • 500 con stack trace → el framework no espera ese verbo y vomita.

Corrupción estructural

JSON con coma extra, llave faltante, codificación distinta.

Capa 4 — Lo que mira el WAF moderno (y cómo evadirlo)

El WAF no sólo mira tu IP. Te identifica por capas múltiples sincronizadas. Cambiar una sola te delata.

El mito del bloqueo por IP

Imagina que cambias de IP con VPN tras el primer bloqueo. El WAF te bloquea instantáneamente otra vez. ¿Por qué?
  1. Cookie de sesión idéntica — El WAF rastrea al usuario, no sólo la red.
  2. Huella JA3 idéntica — Tu Python/curl tiene una firma TLS única. Cambiar de IP no cambia esto.
  3. Patrón de ataque distribuido — 50 IPs distintas con la misma firma JA3 = ataque coordinado, prioridad máxima.

JA3/JA4: la huella criptográfica del cliente

El saludo TLS (Client Hello) incluye la lista de algoritmos y extensiones soportadas. Cada cliente tiene una firma única.
🛡️ Soluciones (ofensivas):

Client Hints (sec-ch-ua-*)

Los navegadores Chromium envían un bloque de cabeceras sec-ch-ua-* describiendo marca y plataforma. Si tu User-Agent dice Chrome 120 pero no envías estas, el WAF detecta la asimetría.

Orden estructural de las cabeceras

Los navegadores reales ensamblan las peticiones HTTP siguiendo un orden rígido. Las librerías (Python requests, Go net/http) las ordenan alfabéticamente o aleatoriamente. 🛡️ Solución: usar herramientas que respeten el orden (tls-client, curl-impersonate, navegadores reales).

Geo-bloqueo y ASN

Si el cliente sólo permite IPs españolas, no basta cambiar de región AWS:
Pero los WAFs avanzados también miran el ASN: 🛡️ Solución profesional: proxies residenciales legales (Bright Data, Oxylabs). Tu tráfico sale de routers reales de ciudadanos en España.

Biometría pasiva en el navegador

La página de login carga JavaScript (reCAPTCHA v3, Cloudflare Turnstile, DataDome) que graba en tiempo real:
  • Trayectoria del ratón (humano = curvas logarítmicas imprecisas).
  • Dinámica de tecleo (humano = ms irregulares entre keydown y keyup).
  • Eventos de hardware (pulsaciones reales de teclas, no inyección directa al DOM).
Tu script inyecta password = "123456" en el DOM en 0 ms, sin generar eventos de teclado. El JS detecta el fantasma. 🛡️ Solución:
  • Navegador real con playwright-stealth o undetected-chromedriver.
  • Simulación de movimiento del ratón con curvas de Bézier.
  • page.type() con delays realistas en lugar de page.evaluate(() => input.value = ...).

Capa 5 — Cuando el muro es liso (no escupe nada)

Cuando ningún error revela tecnología, el equipo de desarrollo es competente. Cambia el plano de ataque — no insistas con fingerprint.

Ataques por timing

El tiempo de respuesta es un chivato que ningún manejador global de excepciones puede ocultar.

Arqueología de endpoints

Versiones antiguas no migradas:

Mass Assignment (la mina de oro)

Sin saber tecnología, prueba inyectar campos extra en JSON legítimo:
Si el response devuelve 200 OK, comprueba después en /profile si la cuenta tiene los nuevos atributos.

IDOR sistemático

Cualquier endpoint que tome un ID:
Si más de uno devuelve 200, IDOR confirmado.

Cómo blindar tu propio backend ante este recon

Si te toca defender en lugar de auditar:

1. Manejador global de excepciones

Nunca dejes que el framework escupa el stack trace.

2. Borrar headers reveladores

3. Renombrar cookies de sesión

4. Rate limiting agresivo en endpoints de fingerprint


Recursos relacionados