Saltar al contenido

Usando OWASP Juice Shop - Enfrentando desafíos difíciles

Índice

Este artículo es el cuarto y último de una serie sobre OWASP Juice Shop. Puedes consultar los posts anteriores sobre instalación en un entorno local, resolución de desafíos básicos y desafíos intermedios.

Introducción a desafíos difíciles

En este último artículo de la serie, enfrentaremos desafíos difíciles (★★★★★) que representan vulnerabilidades sofisticadas que requieren conocimientos difíciles de seguridad web. Estos desafíos simulan amenazas que podrías encontrar en auditorías de seguridad de aplicaciones empresariales reales.

Exploraremos tres vulnerabilidades críticas:

  • Stolen password (★★★★★).
  • Falsificación de tokens JWT sin firma (★★★★★).
  • Evasión de 2FA (★★★★★).

Estos desafíos van más allá de las técnicas básicas y requieren un entendimiento profundo de cómo funcionan las aplicaciones web modernas.

Preparación para desafíos difíciles

Herramientas necesarias

Para estos desafíos difíciles, complementaremos las herramientas del navegador con algunas herramientas adicionales simples:

  1. Herramientas básicas del navegador.
  2. Un editor de texto o IDE para manipular JSON/JWT.
  3. Calculadora online para Base64 (como base64decode.org).
  4. Generador/Decodificador JWT online (como jwt.io).

Configuración del entorno

Asegúrate de que Juice Shop esté ejecutándose correctamente y de tener acceso completo a las herramientas de desarrollo del navegador.

Desafío 1: Stolen password - Acceso con credenciales filtradas (★★★★★)

Entendiendo las filtraciones de datos

En el mundo real, las filtraciones de datos son una fuente común de credenciales comprometidas. Este desafío simula el escenario donde un atacante encuentra credenciales filtradas en Internet y las utiliza para acceder a cuentas de usuarios.

Investigando las credenciales filtradas

  1. Abre las herramientas de desarrollo y busca en el código fuente referencias a filtraciones o logs de acceso.
  2. Ve a http://localhost:3000/ftp que descubriste en desafíos anteriores.
  3. Observa si hay archivos que podrían contener logs de acceso o información sensible.

Encontrando los logs filtrados

  1. Aunque no veas directamente el archivo, intenta acceder a subdirectorios como /support/logs.
  2. El truco de este desafío está en buscar “juice shop access log” en Google. Encontrarás referencias en sitios como Stack Overflow (entre otros).
  3. Una búsqueda específica te llevará a un post de Stack Overflow que menciona logs de acceso de Juice Shop.

Búsqueda de logs

Analizando los logs filtrados

  1. Busca el enlace a PasteBin mencionado en la respuesta.
  2. Ve al enlace de PasteBin que contiene logs de acceso reales filtrados.
  3. En los logs, busca líneas que contengan “password” o “change-password”. Encontrarás algo como:

    161.194.17.103 - - [27/Jan/2019:11:18:35 +0000] "GET /rest/user/change-password?current=0Y8rMnww$*9VFYE%C2%A759-!Fg1L6t&6lB&new=sjss22%@%E2%82%AC55jaJasj!.k&repeat=sjss22%@%E2%82%AC55jaJasj!.k HTTP/1.1" 401 39
    

Logs en PasteBin

Extrayendo las credenciales

1.El parámetro current contiene la contraseña actual URL-encoded. Usa un decodificador online (url decoder): - URL: 0Y8rMnww$*9VFYE%C2%A759-!Fg1L6t&6lB - Decodificado: 0Y8rMnww$*9VFYE§59-!Fg1L6t&6lB 2. Como el cambio de contraseña falló (código 401), la contraseña original sigue siendo válida.

Identificando al propietario de la contraseña

Ahora que tienes la contraseña, necesitas encontrar a qué usuario pertenece. Tienes dos enfoques:

Método 1: Password Spraying (Fuerza bruta inteligente)

  1. Primero, obtén una lista de emails de usuarios través de la sección de administrador:

    • Inicia sesión como administrador (usando inyección SQL del post anterior).
    • Ve a http://localhost:3000/#/administration.
    • Observa la lista de usuarios registrados.
  2. Alternativamente, intenta con emails comunes o patrones típicos de Juice Shop:

Listado de usuarios

Método 2: Inyección SQL para obtener usuarios y contraseñas (Método avanzado)

Si ya dominas inyección SQL de posts anteriores, puedes usar algo parecido a:

')) UNION SELECT null,id,email,password,totpSecret,null,null,null,null FROM Users--

Este query te dará la lista completa de usuarios y sus hashes de contraseña, permitiéndote hacer coincidencias.

Realizando el ataque

  1. Puedes buscar este hash de contraseña en la lista de usuarios (obtenida mediante inyección SQL) o usar password spraying.
  2. Usa las credenciales encontradas:
  3. Como muchos desafíos, este se resolverá automáticamente al iniciar sesión exitosamente.

Login exitoso con credenciales filtradas

Lecciones de seguridad

Para desarrolladores:

  • Nunca registrar contraseñas o datos sensibles.
  • Implementar rotación de contraseñas después de incidentes.
  • Usar HTTPS para todas las comunicaciones.
  • Monitorear la web para filtraciones de datos.

Para usuarios:

  • Cambiar contraseñas si sospechas una filtración.
  • Usar contraseñas únicas para cada servicio.
  • Habilitar autenticación de dos factores.
  • Monitorizar tu presencia en filtraciones con herramientas como “Have I Been Pwned”.

Desafío 2: Unsigned JWT - Falsificar token sin firma (★★★★★)

Entendiendo JSON Web Tokens (JWT)

Los JWT son tokens de autenticación que contienen tres partes separadas por puntos:

  • Header: Define el algoritmo de firma.
  • Payload: Contiene los datos del usuario.
  • Signature: Verifica la integridad del token.

Identificando el token

  1. Inicia sesión en Juice Shop y abre las DevTools.
  2. Ve a la pestaña Network y observa las peticiones después del login.
  3. Busca el token JWT en el header Authorization: Bearer o en las cookies.

JWT Token en DevTools

Analizando el token JWT

  1. Copia el token JWT completo.
  2. Ve a jwt.io y pega el token para decodificarlo.
  3. Observa la estructura:
    • Header contiene "alg": "HS256".
    • Payload contiene el email del usuario.

JWT Decoder en jwt.io

Creando un token sin firma

Para este ataque, crearemos un token con algoritmo “none”:

  1. Modifica el header para usar algoritmo “none”:
{
  "alg": "none",
  "typ": "JWT"
}
  1. Modifica el payload para cambiar el email:
{
  "data": {
    "email": "[email protected]",
    "password": "...",
    "role": "customer",
    "isActive": true,
    "id": 99,
    "iat": 1640764800
  }
}
  1. Codifica cada parte en Base64URL usando un convertidor online o la consola:
// Función para convertir a Base64URL
function base64UrlEncode(str) {
  return btoa(str)
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=/g, '');
}

// Header
let header = '{"alg":"none","typ":"JWT"}';
let encodedHeader = base64UrlEncode(header);

// Payload 
let payload = '{"data":{"email":"[email protected]","password":"...","role":"customer","isActive":true,"id":99,"iat":1640764800}}';
let encodedPayload = base64UrlEncode(payload);

// Token sin firma (nota el punto final sin signature)
let unsignedToken = encodedHeader + '.' + encodedPayload + '.';
console.log(unsignedToken);

Creando unsigned JWT en consola

Utilizando el token falsificado

  1. Copia el token generado.
  2. En las DevTools, ve a Storage > Cookies.
  3. Modifica la cookie token con tu nuevo JWT.
  4. Luego intercepta una petición y modifica el header Authorization o crea una petición desde la consola.

Modificando cookie JWT

fetch('/rest/user/authentication-details', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer AQUI VA EL TOKEN`,
    'Content-Type': 'application/json'
  }
})
.then(response => {
  console.log('Status:', response.status);
  return response.json();
})
.then(data => {
  console.log('¡Token sin firma funcionó!', data);
})
.catch(error => console.error('Error:', error));

Forzando una solicitud que necesite autenticación

El desafío se resolverá automáticamente cuando uses con éxito el token falsificado.

Prevención de ataques JWT

Mejores prácticas:

  • Nunca aceptar tokens con "alg": "none".
  • Validar siempre la firma del token.
  • Usar claves secretas fuertes y rotarlas regularmente.
  • Implementar expiración de tokens corta.
  • Validar todos los claims del token.

Desafío 3: Two Factor Authentication - Evadir 2FA (★★★★★)

Entendiendo el 2FA en aplicaciones

La autenticación de dos factores añade una capa extra de seguridad utilizando algo que tienes (tu teléfono) además de algo que sabes (tu contraseña).

Investigando el usuario con 2FA

  1. Primero necesitamos identificar qué usuario tiene 2FA habilitado.
  2. Utiliza una inyección SQL para obtener información de usuarios (como aprendimos en posts anteriores, un endpoint vulnerable es http://localhost:3000/rest/products/search?q=).
  3. Primero para obtener la estructura de la tabla de usuarios:
')) UNION SELECT null,name,sql,null,null,null,null,null,null FROM sqlite_master WHERE type='table' AND name='Users'--

La estructura de la tabla Users

  1. Luego podemos usar los campos proveídos:
')) UNION SELECT null,id,email,password,totpSecret,null,null,null,null FROM Users--
  1. Busca en la respuesta el usuario [email protected] que tiene un campo totpSecret (el campo puede tener otro nombre) no vacío.

Usuario con 2FA identificado

Configurando tu autenticador

  1. Abre una aplicación autenticadora (Google Authenticator, Authy, andOTP, etc.).
  2. Añade una nueva cuenta manualmente (no por QR):
    • Nombre: Juice Shop Wurstbrot.
    • Clave secreta: El totpSecret que extrajiste. Algo como IFTXE3SPOEYVURT2MRYGI52TKJ4HC3KH.

Nota: Por seguridad mi autenticador no deja tomar capturas entonces no puedo mostrar cómo se hace y cómo aparece el código. Tampoco me llama la atención tomarle foto a mi teléfono, se siente raro hacer eso.

Realizando el bypass

  1. Ve a la página de login y utiliza inyección SQL para iniciar sesión como wurstbrot:

  2. Te aparecerá la pantalla de 2FA.

  3. Introduce el código de 6 dígitos que muestra tu aplicación autenticadora.

  4. Habrás pasado exitosamente el 2FA y completado el desafío.

Pantalla 2FA bypass

Pantalla 2FA completado

Lecciones de seguridad

Este desafío demuestra que:

  • El 2FA es inútil si hay vulnerabilidades que permiten extraer los secretos.
  • Los secretos TOTP deben protegerse con el mismo cuidado que las contraseñas.
  • Las inyecciones SQL pueden comprometer múltiples capas de seguridad.

Metodología para desafíos complejos

Hay desafíos de nivel 6, pero hay que seguir un enfoque sistemático igual que en desafíos de nivel 5 o menor:

  1. Identifica todos los endpoints y funcionalidades.
  2. Entiende el flujo de datos y autenticación.
  3. Busca puntos débiles en la lógica de negocio.
  4. Desarrolla y ejecuta el ataque.
  5. Confirma que el ataque fue exitoso.

Técnicas avanzadas de investigación

Análisis de código JavaScript:

// Buscar funciones interesantes en el código minificado
// Ve a Sources > main.js y busca términos como:
- "admin"
- "token" 
- "auth"
- "secret"
- "2fa"

Interceptación de tráfico avanzada:

  • Monitorea WebSockets y event streams.
  • Analiza respuestas de error para filtración de información.
  • Busca endpoints no documentados.
  • Examina headers personalizados.

Conclusiones y reflexiones finales

Lecciones clave de seguridad

Los desafíos difíciles nos enseñan que:

  1. Un ataque exitoso a menudo requiere explotar múltiples debilidades.
  2. La seguridad es tan fuerte como el eslabón más débil.
  3. La validación debe ocurrir en todos los niveles.
  4. Los tokens de seguridad requieren protección especial.

Desarrollo seguro

Para desarrolladores que quieren crear aplicaciones más seguras:

Arquitectura de seguridad:

  • Implementar defensa en profundidad.
  • Asumir que el cliente está comprometido.
  • Validar todo en el servidor.
  • Registrar y monitorizar actividades sospechosas.

Manejo de autenticación:

  • Usar bibliotecas de autenticación probadas.
  • Implementar rate limiting.
  • Proteger secretos de autenticación.
  • Validar tokens correctamente.

Gestión de datos sensibles:

  • Nunca almacenar datos sensibles en texto plano.
  • Usar consultas parametrizadas siempre.
  • Implementar controles de acceso granulares.
  • Auditar accesos a datos sensibles.

El siguiente nivel

Una vez domines estos conceptos, el siguiente paso natural sería:

  1. Herramientas profesionales: Burp Suite Pro, OWASP ZAP avanzado.
  2. Plataformas adicionales: TryHackMe, HackTheBox, PortSwigger Academy.
  3. Certificaciones: OSCP, CEH, GWEB.
  4. Bug bounty: Programas como HackerOne, Bugcrowd.

Consideraciones éticas y legales

Recordatorio importante:

  • Estas técnicas deben usarse SOLO en entornos controlados como Juice Shop.
  • Practicar en aplicaciones reales sin autorización es ilegal.
  • Considera estudiar seguridad ética y obtener certificaciones reconocidas.
  • Siempre busca permiso explícito antes de probar aplicaciones en producción.

Serie completa OWASP Juice Shop

Esta serie te ha llevado desde la instalación básica hasta vulnerabilidades avanzadas (niveles 1, 3 y 5), al momento de escribir esto en mi instalación aparecen 171 desafíos totales, menos 17 que no se pueden realizar debido a temas de Docker.

Espero que esta serie te haya proporcionado una base sólida para continuar tu viaje en el mundo de la ciberseguridad.

Lo siento si los posts te parecieron bastante secos y en forma de sermones indicando qué hacer y qué no hacer, pero es mejor estar informado.


Nota: Este contenido tiene fines educativos únicamente. El autor no se hace responsable del uso indebido de esta información. Practica siempre la seguridad ética y respeta las leyes locales.