¿Cómo puedo demostrar que este sitio tiene una gran vulnerabilidad de seguridad?

37

Descargo de responsabilidad: soy un programador informático, no soy un analista de seguridad ni nada relacionado con la seguridad. No tengo ninguna experiencia en el mundo de la criptografía, así que tengan paciencia, por favor.

Situación: Me dieron la tarea de integrar el sitio de un cliente con un sitio de alojamiento de datos. Mientras trabajaba en eso, me topé con una consulta que volcaba los datos de todos los usuarios. Para realizar esta consulta, el usuario tiene que 'autenticarse' para obtener una sesión y usar ese código de sesión para realizar esta consulta, que luego verifica que el usuario tenga privilegios de administrador antes de completar la consulta y responder.

Pero aún así ... eso me parece algo horrible. Especialmente porque estos son algunos de los datos que se devuelven si la consulta se ejecuta correctamente:

"username": "[email protected]",
"firstname": "Test",
"lastname": "Name",
"userpassword": "$1$te000000$qMpAriadAHuRyDkK58YKS0"

Se devolvieron más datos que son horribles de exponer, pero esa no es mi principal preocupación.

Claramente, ninguna persona ha sido nombrada "Nombre de prueba", y "testemail.blerg" no es un dominio registrado, y mucho menos "blerg" es un posible dominio de nivel superior. Incluso si lo fuera, esa cuenta se ha eliminado del sitio de alojamiento de datos y no se puede iniciar sesión. La contraseña que se usó es débil, de prueba de caso, y no está en uso por nadie.

¿Es posible para mí la fuerza bruta / la tabla del arco iris (aunque no tengo experiencia, sé algunas palabras de destello: P) o algo para obtener la contraseña de eso? Lo poco (creo) que sé es que la primera parte del userpassword es la sal MD5, pero no sé nada más.

Si alguien puede explicar lo fácil que es, puedo demostrarle a mi jefe que este sitio es completamente horrible y convencer a nuestro cliente para que migre desde este sitio de alojamiento de datos.

Hay más que sé sobre la salazón (es decir, cómo se obtiene la sal, qué lenguaje / función está usando, etc.), pero me gustaría ver con qué facilidad alguien que no tiene acceso a esa información puede resolverlo Otra cosa con la que puedo ir a mi jefe, con suerte.

EDITAR: Parece que hay una pequeña confusión relacionada con mi intencionalidad de ser vago en la descripción, parcialmente con el propósito de evitar cualquier indicación de qué CRM es, por razones legales / etc. También me doy cuenta de que llamarlo 'alojamiento de datos' era potencialmente engañoso, así que es malo. Esperemos que esto aclare:

El trabajo que está haciendo nuestro equipo es crear un sitio web básico para que una empresa muestre sus productos. La única interacción que tengo con el CRM es:

  1. Cuando una persona completa el formulario de Contacto, enviamos POST al objeto CRM un Contacts con la información del usuario.
  2. Haga un GET en una lista de Dealers que venda sus productos para mostrar.

Comencé con el # 2, la llamada a la API GET , donde descubrí que puedo consultar la tabla Users . No he creado la API, solo he estado haciendo solicitudes de ella.

La llamada GET requiere un parámetro query= donde el valor es una declaración SELECT en el lenguaje de consulta del sistema, que luego se traduce a SQL (probablemente previene ataques SQLI, pero no sé cómo se interpreta / se traduce a SQL, así que no estoy tocando eso con un polo de 10 pies). Al cambiar de SELECT * FROM Dealers; a SELECT * FROM Users; en la consulta, pude ver los datos de todos los usuarios.

La forma en que el CRM maneja a los usuarios es con un portal en su sitio. Se crea un usuario en el portal, donde hay una casilla de verificación "Es administrador". Esto se puede editar en cualquier momento a través del portal. Este es el proceso para realizar solicitudes de API:

  1. Un usuario realiza una solicitud al CRM, que contiene el nombre de usuario, para un token.

  2. El token se concatena con la clave de acceso "secreta" para ese usuario, la cadena resultante es un hash MD5 y luego se envía de vuelta para solicitar un token de sesión.

  3. Este token de sesión se incluye con cada solicitud, como parámetro de cadena de consulta, para "verificar" que la solicitud está "autorizada".

Uno de los problemas es que si un usuario 'administrador' realiza una solicitud de la tabla Users , la respuesta es una lista de todos los usuarios con la información que enumeré anteriormente así como el token de acceso "secreto" del usuario (y otra información). Así que es incluso peor que solo exponer una contraseña, es prácticamente otorgar acceso a cualquier persona mediante la suplantación de identidad a cualquiera.

    
pregunta Daevin 02.06.2017 - 17:42
fuente

5 respuestas

45

El formato de contraseña en el atributo userpassword se parece al formato estándar usado por varios servicios de Unix, como el servicio de contraseña del sistema predeterminado que almacena las contraseñas con hash en /etc/shadow . El formato es básicamente:

$ type $ salt $ hash

En su ejemplo, el tipo es 1, que designa un hash md5. Existen otros tipos conocidos, como varios tamaños de funciones hash de la familia sha.

Romper un hash md5 es casi trivial hoy, incluso cuando está salado, porque md5 es muy rápido. No es una función hash que sea segura de usar para contraseñas de hash; hashcat y otros crackers de contraseñas pueden, literalmente, hash millones o incluso miles de millones de candidatos de contraseña por segundo.

Por lo tanto, este servicio de almacenamiento de datos no es simplemente horrible porque devuelve los hashes de las contraseñas de los usuarios, es aún más horrible porque en realidad utiliza los hashes md5 para almacenar contraseñas.

Para demostrarle a tu jefe que esto realmente no es seguro, puedes descargar hashcat y algunas listas de contraseñas (puedes encontrarlas fácilmente en línea), y luego ejecutarlas en una computadora con una GPU muy poderosa en todas las contraseñas Usted obtiene del servicio. Tome nota de la cantidad de contraseñas que el hashcat puede descifrar (sin mirar las contraseñas en sí mismas; pueden revelar información privada sobre las personas que las eligieron, y no quiere saber realmente sus contraseñas), e informar a las personas cuyas contraseñas fueron comprometido que necesitan elegir una nueva contraseña. Probablemente necesitará obtener permiso para hacer todo esto primero, porque dependiendo de dónde viva y trabaje, esto podría considerarse un ataque malicioso o incluso ser ilegal.

Aparte : si no pudiera utilizar este servicio incluso después de expresar sus dudas, sugeriría que configure un descifrador de contraseñas automatizado que se ejecuta sin intervención humana e informa a las personas (enviándoles un correo electrónico) cuando logre descifrar su contraseña sería una manera de proteger a sus usuarios de este tipo de mal diseño. Ayudaría eliminar las contraseñas débiles y aumentar la cantidad de tiempo que necesita un atacante real para descifrar las contraseñas.

Editar : Zach señaló que no es una práctica común y que no debe ser intentada por alguien que no pueda evaluar los riesgos. Estoy completamente de acuerdo con eso. Por lo menos, si hiciste algo así, deberías tener la administración bien.

Sin embargo, NO hacer esto no hace que el sistema resultante sea más seguro. Es el equivalente a meter la cabeza en la arena por temor a que, si realmente hiciste algo para mejorar la seguridad de la contraseña, podría ser contraproducente para ti. sabemos que las personas eligen contraseñas malas, y sabemos que md5 no es una buena forma de hash de contraseñas. Si no podemos cambiar estos dos datos y estamos en condiciones de eliminar contraseñas débiles, entonces probablemente deberíamos hacerlo para que nuestros usuarios estén más seguros.

Una razón importante por la que esto no se ve mucho, o incluso se considera mucho, es que generalmente no estamos en condiciones de implementarlo. Los buenos sistemas no usan funciones hash rápidas para las contraseñas de hash, y generalmente no tenemos acceso a toda la base de datos de contraseñas hash.

    
respondido por el Pascal 02.06.2017 - 18:03
fuente
30

Este hash de contraseña parece utilizar el formato crypt() (que, a pesar de su nombre y lo que dicen algunas documentaciones, incluida esa misma página de manual, no tiene absolutamente nada que ver con el cifrado, es hashing ). Cuando comienza con $1$ , esto significa que es una función de hashing de contraseña basada en MD5. Su especificación exacta es "lo que haga glibc". Un vistazo a la código fuente muestra algunos pasajes ilustrativos:

 201   /* The original implementation now does something weird: for every 1
 202      bit in the key the first 0 is added to the buffer, for every 0
 203      bit the first character of the key.  This does not seem to be
 204      what was intended but we have to follow this to be compatible.  */
 205   for (cnt = key_len; cnt > 0; cnt >>= 1)
 206     md5_process_bytes ((cnt & 1) != 0
 207                        ? (const void *) alt_result : (const void *) key, 1,
 208                        &ctx, nss_ctx);
 209 
 210   /* Create intermediate result.  */
 211   md5_finish_ctx (&ctx, nss_ctx, alt_result);
 212 
 213   /* Now comes another weirdness.  In fear of password crackers here
 214      comes a quite long loop which just processes the output of the
 215      previous round again.  We cannot ignore this here.  */
 216   for (cnt = 0; cnt < 1000; ++cnt)
 217     {

De esto, podemos concluir que esta función de hashing no está muy bien documentada.

De todos modos , como funcionan las funciones de hash de contraseñas, no es muy bueno. Utiliza un salt , y eso es bueno, ya que debería evitar el uso por parte de atacantes de tablas precomputadas (incluidas las tablas de arco iris). También incluye un bucle con muchas (1000) iteraciones, como un intento de hacer que el hashing de contraseñas sea más lento, lo que dificulta que los atacantes intenten muchas contraseñas potenciales hasta que se encuentre una coincidencia (un proceso conocido como "fuerza bruta" o "ataque de diccionario" ").

Lamentablemente, tampoco es muy bueno. MD5 es rápido, y un millar de MD5 anidado, aunque aún 1000 veces más lento, sigue siendo rápido. Una PC disponible con una GPU básica orientada al juego puede calcular millones de tales hashes por segundo; una contraseña de usuario promedio no durará mucho tiempo; y con eso, quiero decir que un atacante que gaste un minuto de cómputo por contraseña de hash seguirá agrietando la mitad.

Aparte de la contraseña con hash, simplemente revelar las direcciones de correo electrónico de los usuarios ya es una ofensa bastante condenable, quiero decir legalmente. Por ejemplo, en Canadá, esto se conoce como "información personal" y todos los usuarios tienen derecho a demandarlo.

    
respondido por el Thomas Pornin 02.06.2017 - 18:15
fuente
22

Detener. No vayas más lejos. No haga más pruebas, demostraciones, etc. hasta que se le haya pedido explícitamente que lo haga por escrito, e incluso entonces comience y sugiera que hay muchas más personas calificadas que usted para realizar una auditoría / prueba / etc .

Conozco a 2 personas que hicieron algo similar con menos información (sin contraseñas, solo detalles a los que no necesitaban acceso y no deberían haber tenido acceso) hace unos pocos meses y todavía están en proceso. de tratar con delito grave cargos.

    
respondido por el ivanivan 04.06.2017 - 03:54
fuente
5

Ese formato parece un hash de contraseña de estilo Unix estándar. Los campos están separados por signos de dólar, primero es el algoritmo, luego la sal, luego el hash real. Asumiendo que es un sistema Linux, $ 1 $ indica el algoritmo de contraseña md5 (que es un poco más complejo que el md5 puro). Las longitudes de los campos también son consistentes con el algoritmo de hash de contraseña MD5.

Existen muchas herramientas para atacar los hashes de contraseña de Linux. Si tiene éxito con esas herramientas dependerá en gran medida de qué tan seguras sean las contraseñas.

También tengo en cuenta que su sal tiene muchos ceros. Si tiene una sal estática o un rango de sales relativamente pequeño (en comparación con el número de usuarios), esto puede abrir opciones para ataques precomputados.

Finalmente, me gustaría señalar que atacar contraseñas reales puede traer problemas legales.

    
respondido por el Peter Green 02.06.2017 - 18:04
fuente
4

Toda esta información está disponible para un usuario admin en un sistema Linux típico en /etc/passwd (legible por cualquier persona) y /etc/shadow (legible por la raíz). En Linux estándar, es difícil evitar que un usuario root acceda a /etc/shadow . Como la consulta requiere privilegios de administrador, no parece que esté exponiendo mucho dado que una cuenta de administrador ha sido comprometida. Como han mencionado otras respuestas, si el sistema realmente utiliza hash md5, eso es un problema, pero no está relacionado con la pregunta.

    
respondido por el StrongBad 02.06.2017 - 23:54
fuente

Lea otras preguntas en las etiquetas