Introducción
Esto es otra historia personal, se trata sobre una plataforma web que está mal programada, de la cual descubrí que no hashea (o encripta como dicen por ahí, aunque no es la forma correcta) las contraseñas de los usuarios, además de que no valida nada.
Todo comenzó porque por gracioso cambié mi contraseña y puse una de 100 caracteres. La cambié, cerré sesión y magia, ya no podía entrar.
Sobre la plataforma
Obviamente no diré de dónde es, o qué hace, pero eso nos da una visión de cómo es el mundo de malo; es decir, ¿qué harías si te digo que la plataforma web de tu hospital no tiene nada encriptado? no sabemos cómo es que protegen nuestra información por más que ésta sea confidencial.
El punto es que no sé quién la haya programado, pero espero por su bien que cambie esa cosa lo más pronto posible.
Cómo descubrí que no hashea las contraseñas
Muy bien, todo comenzó porque cambié mi contraseña; ya lo dije al inicio. Puse una de 100 y ya no podía entrar. Hablando con un compañero del trabajo (y bromeando) dijimos que seguramente se truncó, porque la base de datos no soportó los 100 caracteres.
Es como cuando definimos nuestra tabla en MySQL y ponemos VARCHAR(15)
, si metemos algo más grande que 15 entonces se trunca.
Todo bien hasta aquí, pero llegamos a la conclusión de que aunque el hash se hubiera truncado, si yo probaba truncando mi contraseña plana, no accedería nunca, ¿por qué? bueno, porque eso era suponiendo que la estaba hasheando.
Si mi contraseña era “xFhyPBA$aniVm7$6oq5^THNqZ$gQ1nJjorbDq^T5yc0mpm%&lm&6U#IS#x5U2Vs#xVCEZFaB@7cXSJ#wch*1WU64#YjWECCosp4q
“, al implementar un hasheo se convertiría en algo como: $2y$10$eIqwrbjcP9vnwb5hNAAEp.LmZmUMsZ1HYPc7lDmx4WsoYdWw46uw6
(esto es real, lo hice con password_hash de PHP, pero dudo que en el sitio usen PHP, deben usar algo mejorcito)
Si se truncó, el hash resultante podría ser este: $2y$10$eIqwrbjcP9vnwb5hNAAEp.LmZmUMsZ1HYPc7lDmx4WsoYdWw
(fijémonos en que falta 46uw6
)
Ese hash se quedó guardado y truncado en la base de datos. Pero si yo cortaba mi contraseña (le quitaba algunos carácteres) de modo que quedara así: xFhyPBA$aniVm7$6oq5^THNqZ$gQ1nJjorbDq^T5yc0mpm%&lm&6U#IS#x5U2Vs#xVCEZFaB@7cXSJ#wch*1WU64#YjWECC
(fijémonos en que falta osp4q
) al hashearla se convertía en algo como: $2y$10$zVX9TrV8Wd91d5MzV.70Pu0oZ4P3BRtfpH3uXeSbNqmfI2fN9XOhi
.
Lo que trato de explicar es que, si se truncó el hash original, truncar mi contraseña plana no iba a generar un nuevo hash con menos caracteres que fuera idéntico al que estaba guardado en la BD cuando yo intentara iniciar sesión. Así que era en teoría imposible.
Eso viéndolo desde el enfoque en donde el administrador fuera un experto en seguridad, con 100 años de experiencia. ¿pero qué tal si no? y entonces, si no hasheaba las contraseñas, sí podría ir probando contraseña por contraseña aumentando un carácter a la vez.
Y así fui, comencé desde 10 caracteres con este ciclo que puse en la consola de JavaScript:
for(let x = 10; x < pass.length - 1; x++){
console.log(pass.substr(0, x) + "\n");
}
Ahí iba a poner en una cadena mi contraseña cortada. Primero del 0 al 10, luego del 0 al 11. Es decir, me daría todas las combinaciones posibles truncadas de mi propia contraseña.
Comencé probando con 10, luego 11 y finalmente 12. Y sí, con 12 logré entrar. Eso me dio a entender que mi contraseña de 100 se truncó a 12 caracteres, y así fue guardada, en texto plano. O sea que ese es el límite, 12 caracteres.
Está de más mencionar que el sistema no me avisó ni marcó errores.
El peligro que esto supone
Para empezar, reducir a 12 el límite es el reto suicida dijeran por ahí. Una computadora poderosa podría hacer un ataque de fuerza bruta en lo que supongo sería poco tiempo. De hecho, igual y es vulnerable a un ataque de temporización.
Por otro lado, quien le da mantenimiento es un ser humano o seres humanos. ¿qué tal si ponía mi contraseña de Facebook y el administrador o un practicante husmeaban la base de datos? como está en texto plano, ahí aparecería mi nombre de usuario junto hunter2 como contraseña.
Peor aún, ¿qué tal si el administrador me conoce y le caigo mal? podría buscarme en la base de datos, tomar mi contraseña e inferir que es la que uso en otros lugares.
Muchas cosas podrían salir mal, pero al final de todo no perdí nada y aprendí sobre la forma de pensar del administrador.
Otras fallas
No está validando nada, y tampoco le importan los errores de la base de datos. Parece un ejercicio de un estudiante más que una plataforma del mundo real.
Pingback: Presentando un sistema web para hacer cotizaciones y presupuestos, gratuito y open source - Parzibyte's blog
Pingback: hash_equals y ataques de temporización (timming attacks) en PHP - Parzibyte's blog