¿Es seguro almacenar hashes de posibles contraseñas no existentes de una manera menos segura?

6

Me gustaría implementar un mecanismo de bloqueo que no solo proteja contra el mismo nombre de usuario y muchos ataques de contraseñas, sino también muchos nombres de usuario y mismos ataques de contraseñas.

Para implementar esto, pensé que necesitaba una tabla para almacenar cada contraseña ingresada que causó un intento fallido. Luego, en cada intento de inicio de sesión, verifico si hubo un intento fallido de inicio de sesión con la misma contraseña.

Todas las contraseñas que pertenecen a las cuentas de usuario están cifradas con bcrypt, tienen una sal, un alto costo y todo lo demás. Pero no puedo cifrar las contraseñas utilizadas en un intento fallido de inicio de sesión, ¿verdad? No puedo hacer una búsqueda con MySQL usando la cláusula WHERE porque cada vez que se vuelve a borrar una contraseña, el valor difiere del hash anterior, incluso si es la misma contraseña.

Para poder realizar una búsqueda con MySQL usando la cláusula WHERE, pensé que necesitaba almacenar las contraseñas en la tabla de intentos de inicio de sesión fallidos de una manera menos segura, como SHA512. Sé que algunas contraseñas ingresadas en un intento de inicio de sesión fallido podrían pertenecer a una cuenta de usuario. Entonces, ¿es seguro almacenar los hashes en este formato para poder verificar los intentos fallidos de inicio de sesión? ¿O hay una mejor manera de lograr esto?

    
pregunta Stan 04.09.2013 - 20:39
fuente

3 respuestas

6

Si el procesamiento de un intento de inicio de sesión fallido falla debido a que el nombre de inicio de sesión no existe, incurre en un costo menor para usted que un inicio de sesión fallido debido a una contraseña incorrecta en un nombre de inicio de sesión existente, entonces el atacante podrá Véalo: su servidor responde más rápido en ese caso. Por lo tanto, el atacante podrá saber qué nombres de inicio de sesión existen y cuáles no, y luego concentrarse solo en los nombres de inicio de sesión existentes.

Si realmente quiere ocultar al atacante si existe un nombre de inicio de sesión determinado o no, entonces debe emularlo correctamente: independientemente de si el nombre de inicio de sesión existe o no, haga una invocación completa de bcrypt. Incluso simplemente durmiendo durante el tiempo aproximado aproximado no será suficiente, ya que su servidor podrá "procesar" muchas más operaciones de inicio de sesión por segundo cuando los nombres de inicio de sesión no existen, y luego cuando el inicio de sesión los nombres existen El atacante todavía puede notarlo.

Aunque Tradition exige no revelar si un nombre de inicio de sesión dado existe o no en su sistema, yo diría que el hashing de contraseña correcto es más importante, por lo que simplemente debe rechazar los intentos de nombres de inicio de sesión no existentes. Si desea ocultar el hecho de que un nombre de inicio de sesión no existe en su servidor, DEBE pagar el precio computacional; pero creo que no vale la pena el esfuerzo.

En cuanto a la detección de ataques de fuerza bruta, esto normalmente se hace con estadísticas en la fuente (la dirección IP de la máquina cliente) que en la destino (el nombre de el usuario objetivo). Si limita la velocidad de inicio de sesión a un intento por segundo o menos (o cualquier otra política de "lentitud") y por dirección IP de origen , detectará la mayoría de los ataques de fuerza bruta, independientemente de si están dirigidos a uno Nombre de inicio de sesión o varios, existentes o no existentes. Este es un método más robusto y también cubre el siguiente paso, es decir, cuando los atacantes intentan contraseñas diferentes en muchos nombres de inicio de sesión diferentes (¡y ciertamente pueden hacerlo!).

    
respondido por el Thomas Pornin 04.09.2013 - 21:26
fuente
5

No registraría las contraseñas de intentos de inicio de sesión fallidos de una manera menos segura, como en texto simple o un simple hash criptográfico sin sal. Muchos usuarios escriben accidentalmente la contraseña para el sitio A en el sitio B, u obtienen la contraseña correcta pero el nombre de inicio de sesión es incorrecto. Esta información podría ser muy valiosa a los ojos de un atacante, y sería trivial crear una tabla de arcoiris de contraseñas de uso frecuente para compararla con contraseñas probadas en su sistema.

Si alguien finalmente obtiene acceso a su base de datos (administrador disgustado; inyección SQL; copia de seguridad insegura) probablemente podrá obtener una lista de hashes sin sal asociados con varias contraseñas que pueden ejecutarse en una tabla de arco iris y luego probar estos Las contraseñas primero contra las contraseñas de bcrypt'd.

Rastrearía la cantidad de intentos incorrectos sucesivos de direcciones IP e implementaría CAPTCHA y ralentizaría el procesamiento. Además, podría requerir algún tipo de sistema de prueba de trabajo para hacerlo computacionalmente más difícil para las redes de bots.

Tampoco veo cómo funcionaría este esquema sin agregar características más complicadas. Digamos que un usuario tiene una contraseña bastante común, y algunas botnets intentan atacar muchas cuentas con esa contraseña y llegan a algún límite. ¿Impediría esto que el usuario A inicie sesión con su contraseña común? ¿Es esto aceptable?

Además, esto realmente no evita que las botnets distribuidas ataquen todas las cuentas en su sistema; solo significa que si tienen una lista de mil contraseñas para mil cuentas que quieren atacar, tendrán que hacer algo como la contraseña 1 para la cuenta 1, la contraseña 2 para la cuenta 2, ... luego, cuando se hayan ido a través de todas las 1000 contraseñas comunes, intente la contraseña 2 para la cuenta 1, la contraseña 3 para la cuenta 2, ... y simplemente haga un poco de contabilidad al final.

    
respondido por el dr jimbob 04.09.2013 - 21:19
fuente
2

Tenga en cuenta que la mayoría de las contraseñas incorrectas están a solo unas pocas pulsaciones de ser correctas. Si vale la pena mantener la información, vale la pena protegerla.

Si un cracker está probando contraseñas comunes contra muchas cuentas, entonces obtener su registro solo les dará el diccionario que ya tienen.

Por otra parte, alguien que intenta recordar una contraseña para su sitio sin un administrador de contraseñas está 1) obligado a cometer errores, y 2) es probable que use una contraseña común con algunos caracteres adicionales para hacerla única en su sitio . Para este usuario, tener hashes simples de sus contraseñas expuestas podría ser particularmente devastador.

En mi opinión, la responsabilidad de tal divulgación excede el beneficio potencial. Si no lo conservas, nadie te lo puede robar.

- parte 2: ¿Hay una mejor manera de hacer esto? ¿Cuál es tu modelo específico de amenaza? Supongo que el atacante controla una red bot para probar los nombres de usuario y las contraseñas de los archivos de diccionario.

Si es perezoso y el zombi se conecta directamente, es posible que pueda poner en cuarentena / limitar el IP de su cliente, antes si ve que se están probando muchos nombres de usuarios diferentes. No necesita la contraseña fallida para hacer esto: solo el nombre de usuario y la IP.

Incluso si él no es perezoso, puedes usar su diccionario contra él. Cuando un usuario crea una contraseña, ejecute un reverso de John the Ripper contra ella y rechace cualquier coincidencia. (Es posible que a los usuarios no les guste esto, pero es una oportunidad para educarlos). Luego, si ve una contraseña de diccionario en un intento de inicio de sesión, sabrá que es un atacante y tomará las medidas adecuadas.

algo parecido a:

create table antizombie (hashedip, hashedusername, timestamp, isdictionarypw );

badnews = selecciona hashedip distinto de antizombie donde cuenta (hashedusername) > 20 o isdictionarypw;

recuerda que solo los inicios de sesión fallidos ingresan a esta tabla y desaparecen después de un tiempo razonable.

    
respondido por el Terrel Shumway 04.09.2013 - 22:33
fuente

Lea otras preguntas en las etiquetas