Ir al contenido

Aplicaciones

Cada aplicación se ejecuta como 4 contenedores Docker con balanceo de carga detrás de grupos upstream de nginx, accesibles a través del proxy inverso nginx en la VM. Las sesiones adhesivas garantizan que las aplicaciones con estado (Juice Shop, DVWA, VAmPI, CSD Demo) enruten de manera consistente. Todas las aplicaciones son intencionalmente vulnerables y están diseñadas para pruebas de seguridad.

Reemplace <ORIGIN> con http://<PUBLIC_IP> en todos los ejemplos a continuación. Después de desplegar mediante Terraform, obtenga la IP con terraform output -raw public_ip.

RutaAplicaciónMétodo HTTPRespuesta esperada
/Página de inicioGET200 HTML con enlaces a todas las aplicaciones
/healthVerificación de saludGET200 JSON {"status":"healthy","component":"origin-server",...}
/juice-shop/Juice ShopGET200 HTML (Angular SPA, ~75 KB)
/juice-shop/rest/products/search?q=Juice Shop APIGET200 JSON {"status":"success","data":[...]} (36 productos)
/dvwa/DVWAGET302 redirección a /dvwa/login.php
/dvwa/login.phpInicio de sesión DVWAGET200 HTML formulario de inicio de sesión
/dvwa/setup.phpConfiguración DVWAGET200 HTML (inicialización de base de datos en primer uso)
/vampi/VAmPIGET200 HTML (documentación de API)
/vampi/users/v1VAmPI APIGET200 JSON {"users":[...]}
/vampi/users/v1/registerVAmPI APIPOST200 JSON {"status":"success",...}
/vampi/users/v1/loginVAmPI APIPOST200 JSON {"auth_token":"...","status":"success"}
/httpbin/gethttpbinGET200 JSON con detalles de la solicitud
/httpbin/posthttpbinPOST200 JSON con los datos enviados
/httpbin/headershttpbinGET200 JSON {"headers":{...}}
/httpbin/status/:codehttpbinGETDevuelve el código de estado HTTP especificado
/whoami/whoamiGET200 texto plano con hostname, IP y todas las cabeceras
/csd-demo/CSD DemoGET200 HTML formulario de pago con panel de ataque
/csd-demo/dashboardVista del atacante CSDGET200 HTML mostrando datos exfiltrados
/csd-demo/healthSalud de CSDGET200 JSON {"status":"healthy","component":"csd-demo",...}
/csd-demo/exfil/logRegistro de exfiltración CSDGET200 JSON array de datos capturados
/dvga/DVGA GraphiQLGET200 HTML (GraphiQL IDE)
/dvga/graphqlDVGA GraphQL APIPOST200 JSON respuesta GraphQL
/restaurant/RESTaurantGET200 (redirige a la documentación)
/restaurant/docsRESTaurant SwaggerGET200 HTML (FastAPI Swagger UI)
/restaurant/openapi.jsonRESTaurant OpenAPIGET200 JSON especificación OpenAPI
http://<PUBLIC_IP>:8888crAPIGET200 HTML (SPA)
http://<PUBLIC_IP>:8888/identity/api/auth/signupRegistro crAPIPOST200 JSON
http://<PUBLIC_IP>:8888/identity/api/auth/loginInicio de sesión crAPIPOST200 JSON {"token":"..."}
Ruta/juice-shop/
Imagenbkimminich/juice-shop:latest
Instancias4 (puertos 3001-3004), adhesiva mediante hash $cookie_token, caché de proxy (TTL de 60 s)
Recursos2 CPU / 1 GiB RAM por instancia
FrameworkNode.js / Angular
Proyectoowasp.org/www-project-juice-shop

OWASP Juice Shop es la aplicación web vulnerable más moderna y con mantenimiento activo. Cubre el OWASP Top 10 completo con más de 100 desafíos en una aplicación de comercio electrónico realista.

EscenarioCategoríaVector de ataque
Bypass de inicio de sesión por inyección SQLFirewall de aplicaciones web (WAF)' OR 1=1-- en el campo de correo del inicio de sesión
XSS reflejadoFirewall de aplicaciones web (WAF), Defensa del lado del clienteInyección de script mediante parámetro de búsqueda
XSS basado en DOMDefensa del lado del clientePayload en el fragmento de URL
Autenticación deficienteFirewall de aplicaciones web (WAF)Fuerza bruta en inicio de sesión, manipulación de JWT
Abuso de APISeguridad de APIAcceso no autorizado a endpoints /api/
Exposición de datos sensiblesSeguridad de APIAcceso a datos de usuario sin autorización
CSRFFirewall de aplicaciones web (WAF)Falsificación de solicitudes entre sitios en cambios de perfil
Ventana de terminal
curl -s "http://<PUBLIC_IP>/juice-shop/" -o /dev/null -w "%{http_code}"
Ruta/dvwa/
ImagenPersonalizada dvwa-fpm:latest (php-fpm + nginx, construida desde ghcr.io/digininja/dvwa:latest)
Instancias4 (puertos 8101-8104), adhesiva mediante hash $cookie_PHPSESSID
Recursos0.5 CPU / 256 MiB RAM por instancia
Base de datosMariaDB 10.11 compartida (contenedor dvwa-db, 1 CPU / 768 MiB)
FrameworkPHP 8 / php-fpm / MariaDB
Credencialesadmin / password

DVWA es el estándar de la industria para pruebas de WAF. Tiene niveles de seguridad ajustables (Bajo, Medio, Alto, Imposible) que añaden progresivamente validación de entrada y codificación de salida.

EscenarioCategoríaNivel de seguridad
Inyección SQLFirewall de aplicaciones web (WAF)Bajo: ' OR 1=1# trivial, Alto: SQLi ciego
Inyección de comandosFirewall de aplicaciones web (WAF)Bajo: ; ls, Alto: caracteres filtrados
Inclusión de archivosFirewall de aplicaciones web (WAF)Bajo: traversal de ruta directo, Alto: saneado
XSS (Reflejado)Firewall de aplicaciones web (WAF), Defensa del lado del clienteBajo: <script> básico, Alto: bypass codificado
XSS (Almacenado)Firewall de aplicaciones web (WAF), Defensa del lado del clienteBajo: script persistente en libro de visitas
Carga de archivosFirewall de aplicaciones web (WAF)Bajo: carga de shell PHP, Alto: filtrado de extensiones
Fuerza brutaDefensa Bot estándarIntentos de inicio de sesión automatizados

Configure el nivel de seguridad en /dvwa/security.php después de iniciar sesión:

  • Bajo — Sin validación de entrada. Todos los ataques funcionan. Ideal para demostraciones de firmas de WAF.
  • Medio — Filtrado básico. Algunos ataques requieren codificación o técnicas de bypass.
  • Alto — Filtrado robusto. Solo técnicas avanzadas tienen éxito. Útil para mostrar las limitaciones del WAF.
  • Imposible — Implementación completamente segura. Demuestra una codificación defensiva adecuada.

DVWA requiere una configuración de base de datos única después del primer despliegue:

  1. Navegue a http://<PUBLIC_IP>/dvwa/setup.php
  2. Haga clic en Create / Reset Database
  3. Inicie sesión con admin / password
Ruta/vampi/
Imagenerev0s/vampi:latest con punto de entrada gunicorn (4 workers)
Instancias4 (puertos 5101-5104), adhesiva mediante ip_hash (SQLite por instancia)
Recursos0.5 CPU / 512 MiB RAM por instancia
FrameworkPython / Flask / gunicorn
Proyectogithub.com/erev0s/VAmPI

VAmPI está diseñado específicamente para probar el OWASP API Security Top 10. Proporciona una API REST realista con vulnerabilidades deliberadas. Cada instancia ejecuta gunicorn con 4 workers y su propia base de datos SQLite. La sesión adhesiva ip_hash garantiza que el registro e inicio de sesión desde la misma IP del cliente siempre lleguen a la misma instancia.

EscenarioOWASP API Top 10Método
Autorización de nivel de objeto deficiente (BOLA)API1Acceder a datos de otros usuarios manipulando IDs
Autenticación deficienteAPI2Manejo débil de tokens, sin límite de tasa
Exposición excesiva de datosAPI3La API devuelve más datos de los que el cliente necesita
Asignación masivaAPI6Modificar campos de administrador mediante parámetros inesperados
Inyección SQLAPI8Inyección a través de parámetros de API
Gestión inadecuada de activosAPI9Endpoints de API no documentados
Ventana de terminal
# Registrar un nuevo usuario
curl -X POST "http://<PUBLIC_IP>/vampi/users/v1/register" \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"test123","email":"test@test.com"}'
# Iniciar sesión
curl -X POST "http://<PUBLIC_IP>/vampi/users/v1/login" \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"test123"}'
# Listar usuarios (exposición excesiva de datos)
curl "http://<PUBLIC_IP>/vampi/users/v1"
Ruta/httpbin/
Imagenkennethreitz/httpbin:latest con anulación de CMD de gunicorn (-w 4 -k gevent --timeout 30)
Instancias4 (puertos 8201-8204), round-robin (sin estado)
Recursos0.5 CPU / 256 MiB RAM por instancia
FrameworkPython / Flask / gunicorn + gevent
Proyectohttpbin.org

httpbin es un servicio simple de solicitud/respuesta HTTP útil para demostraciones básicas de API, pruebas de cabeceras de solicitud y verificación del comportamiento del proxy.

EndpointPropósito
/httpbin/getDevuelve datos de la solicitud GET (cabeceras, argumentos, origen)
/httpbin/postDevuelve datos de la solicitud POST (cuerpo, formulario, JSON)
/httpbin/headersDevuelve las cabeceras de la solicitud
/httpbin/ipDevuelve la IP de origen
/httpbin/user-agentDevuelve la cabecera User-Agent
/httpbin/status/:codeDevuelve el código de estado HTTP especificado
/httpbin/delay/:secondsRetrasa la respuesta N segundos
/httpbin/anythingDevuelve todo lo que se pase en la solicitud
Ventana de terminal
# Verificar qué cabeceras ve el origen (útil para verificar la inyección de cabeceras de F5 XC)
curl -s "http://<PUBLIC_IP>/httpbin/headers" | jq .
# Probar un código de estado HTTP específico
curl -s -o /dev/null -w "%{http_code}" "http://<PUBLIC_IP>/httpbin/status/403"
Ruta/whoami/
Imagentraefik/whoami:latest
Instancias4 (puertos 8082-8085), round-robin (sin estado)
Recursos0.25 CPU / 64 MiB RAM por instancia
FrameworkGo
Proyectogithub.com/traefik/whoami

whoami es el servidor de eco de solicitudes ligero de Traefik. Muestra cada detalle de la solicitud HTTP entrante tal como la ve el origen: hostname, direcciones IP, todas las cabeceras, método y URL. Esta es la herramienta de diagnóstico más importante al verificar que F5 XC está inyectando las cabeceras correctas.

Caso de usoQué buscar
Verificar la inyección de cabeceras de F5 XCCabeceras X-Forwarded-For, True-Client-IP, X-Volterra-*
Confirmar la visibilidad de la IP del clienteX-Real-IP vs RemoteAddr
Depurar falsos positivos del WAFComparar cabeceras de solicitud antes/después de F5 XC
Validar el etiquetado de defensa botCabeceras X-Volterra-Bot-Type, X-Volterra-Bot-Verified
Verificar la terminación TLSX-Forwarded-Proto muestra https cuando TLS termina en F5 XC
Ventana de terminal
# Solicitud básica -- ver lo que recibe el origen
curl "http://<PUBLIC_IP>/whoami/"
# Simular solicitud a través de F5 XC (con cabeceras inyectadas)
curl "http://<PUBLIC_IP>/whoami/" \
-H "X-Forwarded-For: 203.0.113.50" \
-H "True-Client-IP: 203.0.113.50" \
-H "X-Forwarded-Proto: https"

Ejemplo de salida:

Hostname: 534c5084e169
IP: 127.0.0.1
RemoteAddr: 172.17.0.1:55118
GET / HTTP/1.1
Host: 20.12.78.159
User-Agent: curl/8.5.0
Accept: */*
True-Client-Ip: 203.0.113.50
X-Forwarded-For: 203.0.113.50, 10.0.0.1
X-Forwarded-Proto: https
X-Real-Ip: 104.219.105.84
Ruta/dvga/
Imagendolevf/dvga:latest
Instancias4 (puertos 5201-5204), adhesiva mediante ip_hash (SQLite por instancia)
Recursos0.5 CPU / 256 MiB RAM por instancia
FrameworkPython / Flask / GraphQL
Proyectogithub.com/dolevf/Damn-Vulnerable-GraphQL-Application

DVGA está diseñado específicamente para probar vulnerabilidades propias de GraphQL. Proporciona un IDE GraphiQL en /dvga/ para la exploración interactiva de consultas y un endpoint de API GraphQL en /dvga/graphql. Cada instancia usa su propia base de datos SQLite, por lo que las sesiones adhesivas ip_hash garantizan un estado consistente.

EscenarioCategoríaVector de ataque
Inyección GraphQLSeguridad de APIConsultas maliciosas mediante interpolación de cadenas
Denegación de servicioSeguridad de APIConsultas profundamente anidadas, consultas en lote, agotamiento de recursos
Bypass de autorizaciónSeguridad de APIAcceso a datos no autorizados a través de GraphQL
Divulgación de informaciónSeguridad de APIConsultas de introspección que revelan detalles del esquema
Ataque de agrupaciónSeguridad de APIMúltiples operaciones en una sola solicitud
Ventana de terminal
# Interfaz GraphiQL (IDE interactivo)
curl -sf "http://<PUBLIC_IP>/dvga/" -o /dev/null -w "%{http_code}"
# Consulta de introspección -- enumerar el esquema completo
curl -s "http://<PUBLIC_IP>/dvga/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"{ __schema { types { name fields { name } } } }"}'
# Listar pastes (consulta de ejemplo)
curl -s "http://<PUBLIC_IP>/dvga/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"{ pastes { title content } }"}'
# Crear un paste (mutación)
curl -s "http://<PUBLIC_IP>/dvga/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"mutation { createPaste(title:\"test\", content:\"hello\", public:true) { paste { title } } }"}'

RESTaurant (Damn Vulnerable RESTaurant API Game)

Sección titulada «RESTaurant (Damn Vulnerable RESTaurant API Game)»
Ruta/restaurant/
ImagenCompilación personalizada desde theowni/Damn-Vulnerable-RESTaurant-API-Game
Instancias4 (puertos 8301-8304), round-robin (PostgreSQL compartido)
Recursos0.5 CPU / 256 MiB RAM por instancia
Base de datosPostgreSQL 15.4 compartido (contenedor restaurant-db, 0.5 CPU / 512 MiB)
FrameworkPython / FastAPI / PostgreSQL
Credencialesadmin / password (PostgreSQL)
Proyectogithub.com/theowni/Damn-Vulnerable-RESTaurant-API-Game

RESTaurant es una API REST vulnerable gamificada que cubre el OWASP API Security Top 10 2023. Utiliza FastAPI con documentación automática de Swagger UI en /restaurant/docs. Las 4 instancias comparten una única base de datos PostgreSQL, por lo que el balanceo de carga round-robin funciona sin sesiones adhesivas.

EscenarioOWASP API Top 10 2023Método
Autorización de nivel de objeto deficiente (BOLA)API1Acceder a los pedidos de otros usuarios manipulando IDs
Autenticación deficienteAPI2Manejo débil de tokens, relleno de credenciales
Autorización deficiente a nivel de propiedad de objetoAPI3Asignación masiva en campos del perfil de usuario
Consumo de recursos sin restricciónAPI4Sin límite de tasa en los endpoints
Autorización de nivel de función deficiente (BFLA)API5Acceder a endpoints de administrador como usuario regular
Falsificación de solicitudes del lado del servidor (SSRF)API7Manipular solicitudes de URL del lado del servidor
Configuración incorrecta de seguridadAPI8Mensajes de error detallados, credenciales predeterminadas
Ventana de terminal
# Swagger UI
curl -sf "http://<PUBLIC_IP>/restaurant/docs" -o /dev/null -w "%{http_code}"
# Especificación OpenAPI
curl -s "http://<PUBLIC_IP>/restaurant/openapi.json" | jq .info
# BOLA -- acceder al pedido de otro usuario (después de autenticación)
curl -s "http://<PUBLIC_IP>/restaurant/orders/1" \
-H "Authorization: Bearer <token>"
# BFLA -- intentar acción de administrador como usuario regular
curl -s -X POST "http://<PUBLIC_IP>/restaurant/admin/users" \
-H "Authorization: Bearer <user_token>" \
-H "Content-Type: application/json"
Puerto8888 (dedicado — sin prefijo de ruta)
Imágenescrapi/crapi-web, crapi/crapi-identity, crapi/crapi-community, crapi/crapi-workshop, PostgreSQL, MongoDB, MailHog
Instancias7 microservicios (una instancia cada uno)
Recursos~3.0 CPU / ~2.0 GiB RAM en total
FrameworkReact SPA + microservicios Java/Go/Python
Proyectogithub.com/OWASP/crAPI

crAPI es el proyecto insignia de OWASP para pruebas de seguridad de API. Se ejecuta como 7 microservicios en un puerto dedicado (8888) porque el React SPA codifica de forma fija sus rutas de API y no puede servirse detrás de un prefijo de ruta. El NSG permite el tráfico entrante en el puerto 8888.

MailHog captura todos los correos electrónicos enviados por crAPI (verificación de cuenta, restablecimiento de contraseña). Acceda a MailHog mediante túnel SSH en el puerto 18025.

CategoríaVulnerabilidades
BOLA (Autorización de nivel de objeto deficiente)Acceder a vehículos, pedidos e informes de otros usuarios
BFLA (Autorización de nivel de función deficiente)Escalar a administrador, acceder a endpoints restringidos
Asignación masivaModificar campos protegidos (rol, saldo) mediante API
SSRF (Falsificación de solicitudes del lado del servidor)Manipular la obtención de URL del lado del servidor
Manipulación de JWTFalsificar o modificar tokens JWT para escalada de privilegios
Inyección NoSQLInyectar consultas en endpoints respaldados por MongoDB
Exposición excesiva de datosLa API devuelve datos sensibles del usuario
Ventana de terminal
# Verificar que crAPI está en funcionamiento
curl -sf "http://<PUBLIC_IP>:8888" -o /dev/null -w "%{http_code}"
# Registrar un nuevo usuario
curl -s -X POST "http://<PUBLIC_IP>:8888/identity/api/auth/signup" \
-H "Content-Type: application/json" \
-d '{"name":"Test User","email":"test@example.com","number":"1234567890","password":"Test1234!"}'
# Iniciar sesión
curl -s -X POST "http://<PUBLIC_IP>:8888/identity/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"Test1234!"}'
# Acceder a MailHog (mediante túnel SSH para verificación de correo)
# ssh -L 18025:localhost:18025 azureuser@<PUBLIC_IP>
# Luego abra http://localhost:18025 en su navegador
Port 8888 -> crapi-web (React SPA + nginx)
-> crapi-identity (Java, user auth, JWT)
-> crapi-community (Go, forums, posts)
-> crapi-workshop (Python, vehicle service)
-> crapi-postgres (PostgreSQL)
-> crapi-mongo (MongoDB)
-> crapi-mailhog (email capture, port 18025)
Caso de uso de demostraciónAplicación principalAplicación secundaria
WAF — Inyección SQLDVWAJuice Shop
WAF — XSSDVWAJuice Shop
WAF — Inyección de comandosDVWA
Seguridad de API — BOLAVAmPI
Seguridad de API — Bypass de autenticaciónVAmPIJuice Shop
Seguridad de API — Exposición de datosVAmPIhttpbin
Defensa Bot — Fuerza brutaDVWAJuice Shop
Defensa Bot — ScrapingJuice Shop
Defensa del lado del cliente — XSS basado en DOMJuice Shop
Defensa del lado del cliente — XSS almacenadoDVWAJuice Shop
Defensa del lado del cliente — Skimmer de tarjetasCSD Demo
Defensa del lado del cliente — FormjackerCSD Demo
Defensa del lado del cliente — KeyloggerCSD Demo
Defensa del lado del cliente — CriptomineroCSD Demo
Defensa del lado del cliente — Secuestro de DOMCSD Demo
Seguridad de API — Inyección GraphQLDVGA
Seguridad de API — DoS en GraphQLDVGA
Seguridad de API — OWASP API Top 10 2023RESTaurantcrAPI
Seguridad de API — BFLARESTaurantcrAPI
Seguridad de API — Asignación masivacrAPIRESTaurant
Seguridad de API — SSRFcrAPIRESTaurant
Seguridad de API — Manipulación de JWTcrAPI
Seguridad de API — Inyección NoSQLcrAPI
Pruebas básicas de conectividadhttpbin
Diagnóstico de solicitudeswhoamihttpbin
Verificación de inyección de cabeceraswhoami