Time-based Token Vulnerability Exploitation
Introducción
En este caso la vulnerabilidad se va a centrar en que cada usuario tendra una bandeja de entrada como en un email donde le llegara la URL con el TOKEN que tiene que ser valido, estos TOKENs se generan por marcas de tiempo, por lo que podremos suplantar un TOKEN que se genere para cambiar la contraseña de otro usuario enviando dos peticiones de forma simultanea y conseguir obtener el TOKEN de cambio de contraseña del otro usuario.
CTF para practicar
URL = Download CTF Time-based Token
Código Vulnerable
1. Generación de Tokens Basada en Tiempo (config.php)
// VULNERABILIDAD: Token generado basándose en segmentos de tiempo
function generateResetToken($username) {
global $pdo;
// Limpiar tokens expirados (más de 10 minutos)
$pdo->prepare("DELETE FROM reset_tokens WHERE created_at < datetime('now', '-10 minutes')")->execute();
// VULNERABILIDAD CRÍTICA: Usar segmentos de tiempo predecibles
// El token cambia solo cada 10 segundos, permitiendo ventana de ataque
$time_segment = floor(time() / 10); // ¡VULNERABLE! Cambia cada 10 segundos
// VULNERABILIDAD: Token no incluye información única del usuario
// Mismo token generado para todos los usuarios en el mismo time_segment
$token = hash('sha256', $time_segment . 'weak_secret_salt');
// Debug: registrar el timestamp para verificar
error_log("Token generado para $username - Time segment: $time_segment - Token: " . substr($token, 0, 16) . "...");
// Guardar token en la base de datos
$stmt = $pdo->prepare("INSERT INTO reset_tokens (username, token) VALUES (?, ?)");
$stmt->execute([$username, $token]);
return $token;
}Problemas de seguridad:
✅ Time-based: Los tokens se generan basándose en
floor(time() / 10)✅ No único por usuario: Mismo token para todos los usuarios en el mismo segmento de tiempo
✅ Secret débil: Usa 'weak_secret_salt' como salt predecible
✅ Ventana de 10 segundos: Ampla ventana para ataques simultáneos
2. Verificación de Tokens (config.php)
Problemas de seguridad:
✅ Falta de vinculación usuario-token: El sistema no verifica que el token fue generado específicamente para ese usuario
✅ Reutilización potencial: Múltiples usuarios pueden usar el mismo token
3. Endpoint de Recuperación (forgot-password.php)
Problemas de seguridad:
✅ No rate limiting: Múltiples solicitudes permitidas sin restricción
✅ Generación inmediata: Token se genera sin verificar abuso
✅ Parámetro username en URL: Permite fácil manipulación
Mecanismo de Explotación
Flujo del Ataque
Preparación: Obtener dos sesiones diferentes (PHPSESSID)
Ataque Simultáneo: Enviar peticiones casi al mismo tiempo
Token Compartido: Ambos usuarios reciben el mismo token
Suplantación: Usar el token de un usuario para otro
Obtener CSRF y PHPSESSIONID de Victim
Tendremos que obligar al servidor que nos genere una nueva "sesion" para modificarla en la segunda peticion donde pondremos nuestro nombre de usuario.
Dejamos los campos vacios y le damos a enviar, en la respuesta del servidor tendremos que ver que se nos genera un nuevo PHPSESSIONID y un CSRF bajando un poco en el codigo que esta con a etiqueta hidden.
Esa informacion la tendremos que modificar en la Peticion 2 del siguiente cuadro.
Peticiones de Explotación
Resultado Esperado
Ambos usuarios recibirán el mismo token si las peticiones se procesan en el mismo segmento de tiempo (10 segundos).
Proof of Concept
URL de Reset Compartida
Verificación de la Vulnerabilidad
Mitigaciones
Solución 1: Tokens Únicos por Usuario
Solución 2: Vinculación Usuario-Token
Solución 3: Rate Limiting
Conclusión
Esta vulnerabilidad demuestra los peligros de usar componentes predecibles (como el tiempo) en la generación de tokens de seguridad. La combinación de tokens time-based con falta de vinculación usuario-token crea una ventana de explotación crítica que permite a un atacante resetear contraseñas de otros usuarios mediante ataques de race condition.
Last updated