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.

Relacionado:  Vue con Laravel - Configuración con Laravel Mix

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:

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.

Relacionado:  Configurar VSCode y Vetur para programar con Vue

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.


Estoy disponible para trabajar en tu proyecto o realizar tu tarea pendiente, no dudes en ponerte en contacto conmigo.
Si el post fue de tu agrado muestra tu apoyo compartiéndolo, suscribiéndote al blog, siguiéndome o realizando una donación.

Suscribir por correo

Ingresa tu correo y recibirás mis últimas entradas sobre programación, open source, bases de datos y todo lo relacionado con informática

Únete a otros 768 suscriptores


parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

2 Comments

Presentando un sistema web para hacer cotizaciones y presupuestos, gratuito y open source - Parzibyte's blog · enero 10, 2019 a las 3:31 am

[…] PHP) pero antes de ello las convierto en una cadena de longitud fija con md5 (para evitar poner un límite en la longitud de las mismas). Así, aunque MD5 es rompible por un ataque de diccionario, bcrypt no, porque usa […]

hash_equals y ataques de temporización (timming attacks) en PHP - Parzibyte's blog · noviembre 8, 2018 a las 1:54 pm

[…] contraseñas son cadenas, simples cadenas. Ya sea hasheadas o no, son cadenas al final de todo. Imaginemos que están en texto plano, y que por cada comparación de […]

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

A %d blogueros les gusta esto: