Broken Brute-Force Protection — IP Block Bypass — PortSwigger Lab
Bypass del bloqueo por IP intercalando credenciales correctas entre intentos fallidos para resetear el contador de rate limit y forzar la contraseña de carlos.
Broken Brute-Force Protection — IP Block
1. Target Overview & Vulnerability Summary
| Campo | Valor |
|---|---|
| Severidad | Alta |
| Endpoint vulnerable | POST /login |
| Root cause | El contador de bloqueo se resetea al autenticar correctamente una cuenta; intercalando credenciales válidas entre intentos fallidos se evita el bloqueo por IP (Broken Brute-Force Protection) |
El lab es vulnerable por un fallo lógico en su protección contra fuerza bruta. El rate limit bloquea la IP tras un número de intentos fallidos, pero cualquier login exitoso resetea el contador. Inyectando la cuenta legítima wiener:peter entre los intentos contra carlos, la IP nunca se bloquea.
Credenciales del lab: wiener:peter (propias), víctima carlos, wordlist de candidatos provista por el lab.
2. Technical Breakdown & Exploitation Flow
2.1 Mapeo de respuestas
Los mensajes de error permiten además enumerar usuarios:
Incorrect password # Usuario existe, contraseña incorrecta
Invalid username # Usuario no existe
2.2 Fuerza bruta con reseteo de contador
El rate limit se elude intercalando una autenticación correcta cada 2-3 requests fallidas. Patrón de solicitudes contra /login:
POST /login HTTP/2
Content-Type: application/x-www-form-urlencoded
username=carlos&password=<CANDIDATO_1>
POST /login HTTP/2
Content-Type: application/x-www-form-urlencoded
username=carlos&password=<CANDIDATO_2>
POST /login HTTP/2
Content-Type: application/x-www-form-urlencoded
username=wiener&password=peter # Login válido: resetea el contador de la IP
Repitiendo el patrón (2-3 fallos + 1 acierto) para todo el wordlist, la IP nunca alcanza el umbral de bloqueo y el candidato correcto de carlos se descubre sin interrupción.
3. Root Cause Analysis
El defecto es que el contador de intentos fallidos es global por IP y se resetea con cualquier autenticación exitosa:
# Implementación vulnerable
if rate_limit_exceeded(request.ip):
block(request.ip) # Bloquea tras N fallos
if valid_credentials(username, password):
reset_failed_attempts(request.ip) # ❌ Cualquier éxito resetea el contador
create_session(username)
else:
increment_failed_attempts(request.ip)
El atacante controla el reseteo con una cuenta que conoce, anulando la protección. Es un caso clásico de Broken Brute-Force Protection.
4. Secure Remediation
Desacoplar el reset del contador del éxito de autenticación y contar por usuario+IP:
# Implementación segura
if rate_limit_exceeded(request.ip, request.username):
deny()
if valid_credentials(username, password):
create_session(username)
# El contador NO se resetea por una IP compartida
else:
increment_failed_attempts(request.ip, request.username)
return generic_error()
Medidas adicionales: ventanas de tiempo deslizantes, backoff exponencial, CAPTCHA tras N fallos, y no permitir que un login legítimo de una cuenta distinta limpie el contador de la IP.