sábado, 14 de abril de 2012

Más sobre Passwords y Contraseñas

En el artículo anterior de esta serie comentábamos que la contraseña más fuerte de todas es aquella que no se la dices a nadie.

Sin embargo, queda todavía la pregunta en el aire: ¿Pero como hago para no decirle a nadie mi contraseña? A pesar que parezca tonta, la pregunta es muy pertinente. Muy pocas personas se han puesto a pensar que no importa lo que hagan, su contraseña tiene que ser revelada al menos a un ente más aparte de nosotros mismos. Este ente es, por supuesto, el sistema que nos la pide para autenticarnos.

En realidad, no existe nada técnicamente que nos proteja del administrador incapaz o inmoral, que al final de cuentas termina siendo más o menos lo mismo. Por ejemplo, ¿Cuantas personas utilizan la misma contraseña para ingresar a su correo electronico y al twitter o al facebook o a alguna otra red social? ni que hablemos de las cuentas de bancos y demás. La siguiente pregunta es: ¿Qué le cuesta al administrador de aquel foro insignificante que nos pidio nuestro email y que pongamos una contraseña a intentar esa misma contraseña contra la cuenta de correo que le hemos dado? Absolutamente nada. Si la contraseña que utilizamos en ese foro insignificante es la misma que usamos en el email que pusimos, las cosas se empiezan a complicar. Más aún, lo que realmente debería preocuparnos es lo que pasará cuando a ese foro insignificante lo vulneren y queden todas nuestras contraseñas y correos electrónicos comprometidas y publicadas en Internet.

Parece increible, pero incluso gente que es considerada "conocedora" en estos temas, todavía no hace mucho discutía sobre si era adecuado almacenar las contraseñas de los usuarios en texto claro, o debían, como lo hace la mayoría del mundo civilizado, almacenarlas en modo "ofuscado" utilizando algún algoritmo de "resumen", mejor conocido como "hashing".

Para efectos de este artículo, consideramos un escenario en donde los administradores del sitio a quien le confiamos nuestro password no tienen un pensamiento tan "anticuado" y asumimos que almacenan las contraseñas utilizando alguna función irreversible. Esta es la situación en donde cobran importancia las conocidas "tecnicas de cracking" con las que se intenta descubrir la contraseña de una victima sin saber ninguna otra información acerca de ella. En este análisis trato de demostrar que las creencias de hace algunos años simplemente no aplican a la hora de decidir la contraseña que debemos utilizar para autenticarnos contra cualquier sistema informático.

Una de estas creencias es que una contraseña de fortaleza adecuada tiene al menos 8 caracteres. De hecho hace poco leí un artículo en donde la NASA supuestamente recomendaba que las contraseñas debían tener al menos 8 caracteres y de paso, lanzaban una receta sobre la composición de la contraseña. Justamente lo que habíamos explicado en nuestro anterior artículo que no se debe hacer.

Nuestra primera afirmación es que una contraseña de 8 caracteres (dependiendo del algoritmo resumen que se utilice para almacenarla) ya no es lo suficientemente fuerte como para aguantar a prácticamente ningún atacante sin importar que tan poco sofisticado sea. Quiere decir, lamers, script kiddies, y toda clase de principiantes tienen a su alcance romper este tipo de contraseñas sin mucho trabajo utilizando herramientas enlatadas. Para efectos demostrativos, utilizaremos la herramienta hashcat. Esta herramienta hace uso de los GPUs de nuestras tarjetas de video y ademas provee una gran cantidad de tipos de hashes para crackear. Veamos esta herramienta en acción:


[neo@matrix oclHashcat-0.26]$ ./cudaHashcat64.bin -h
cudaHashcat, advanced password recovery

Usage: cudaHashcat [options] hashlist dict_left|mask_left dict_right|mask_right

...
Hash types:
  -m,  --hash-type=NUM       number correlates to hash-type

    0 = MD5
    1 = md5($pass.$salt)
    2 = md5($salt.$pass)
    3 = md5(md5($pass))
    5 = vBulletin < v3.8.5
  100 = SHA1
  101 = sha1($pass.$salt)
  102 = sha1($salt.$pass)
  300 = MySQL > v4.1
  900 = MD4
 1000 = NTLM
 1100 = Domain Cached Credentials
 1400 = SHA256


En donde se presenta una lista de los hashes más comunmente utilizados en la actualidad. Para aún más hashes, se puede utilizar la versión "plus" de esta herramienta.

Consideremos ahora el caso de los hashes MD5, muy utilizados en el mundo Unix e intentemos valorar el tiempo que nos tomaría "crackear" una contraseña de 8 caracteres (incluyendo números, mayúsculas y minusculas).

Status.......: Running
Input.Mode...: Mask (?1?1?1?1?1?1?1?1)
Hash.Target..: 696ebfe2a8b2c685802a5a33ed4f1bae
Hash.Type....: MD5
Time.Running.: 3 mins, 11 secs
Time.Left....: 3 days, 21 hours
Time.Util....: 191344.7ms/82.1ms Real/CPU, 0.0% idle
Speed........:   650.1M c/s Real,   652.1M c/s GPU
Recovered....: 0/1 Digests, 0/1 Salts
Progress.....: 124393881600/218340105584896 (0.06%)
Rejected.....: 0/124393881600 (0.00%)
HW.Monitor.#1:  0% GPU, 81c Temp
[s]tatus [p]ause [r]esume [q]uit => q

Lo que debe llamar la atención es que mi tarjeta de video (muy viejita ya por cierto), sólo requiere de menos de 4 días para recorrer exhaustivamente todo el espacio posible de contraseñas. El número total de posibilidades es el enorme número 218340105584896. Sin embargo, alcanza una velocidad de 650 millones de cifrados por segundo. Ahora veamos el caso de las contraseñas en el mundo Windows. Asumamos el mismo espacio de contraseñas, 8 caracteres, incluyendo minúsculas, mayusculas y dígitos. En este caso, el algoritmo utilizado es NTLM:

Status.......: Running
Input.Mode...: Mask (?1?1?1?1?1?1?1?1)
Hash.Target..: 504c4894815c8ececaa608268a0f3373
Hash.Type....: NTLM
Time.Running.: 30 secs
Time.Left....: 2 days, 19 hours
Time.Util....: 30571.4ms/19.1ms Real/CPU, 0.1% idle
Speed........:   901.6M c/s Real,   904.1M c/s GPU
Recovered....: 0/1 Digests, 0/1 Salts
Progress.....: 27563950080/218340105584896 (0.01%)
Rejected.....: 0/27563950080 (0.00%)
HW.Monitor.#1:  0% GPU, 61c Temp

Como se puede ver, en este caso sólo necesito de aproximadamente la mitad de tiempo! para conseguir la contraseña. Sin embargo, bajo ciertas condiciones, y por motivos de compatibilidad, Windows almacena la misma contraseña utilizando un algoritmo mucho más débil conocido como LM. En esos casos, el tiempo requerido para romper la contraseña es increiblemente menor. Pero ni siquiera vayamos ahí.

Un detalle que sí vale la pena tomar en cuenta es la diferencia de velocidad para romper las contraseñas en ambos algoritmos. Para el caso de NTLM, la velocidad llega a 900 millones de contraseñas por segundo. En consecuencia, se hace evidente que uno de los verdaderos aspectos a tener en cuenta es el algoritmo utilizado para almacenar la contraseña y no tanto su composición. Realmente, mientras más lento se haga el trabajo de nuestro atacante, mejor protección alcanzaremos.

Para finalizar, quisiera romper un último mito muy arraigado a pesar de que se ha hablado al respecto hasta las nauseas. Lo que quisiera desmentir son las famosas "recetas" y su verdadera contribución hacia la fortaleza de nuestro password. Para hacerlo más fácil, consideremos de nuevo el algoritmo NTLM, una contraseña de 8 caracteres, pero que tiene una sola mayuscula. La máscara para el ataque de fuerza bruta es muy sencilla:

./cudaHashcat-lite64.bin -1 ?l?d -2 ?u -m 1000 --pw-min=8 --pw-max=8 504c4894815c8ececaa608268a0f3373 ?2?1?1?1?1?1?1?1

El comando anterior significa lo siguiente:

-m 1000       ->    tipo de hash. NTLM en este caso.
-1 ?l?d         ->    primer charset, minúsculas y números.
-2 ?u            ->    segundo charset, sólo mayúsculas.
--pw-min=8 ->    intentar passwords de mínimo 8 caracteres
--pw-max=8 ->   intentar passwords de máximo 8 caracteres

Finalmente, ?2?1?1?1?1?1?1?1?1 es la "máscara" y quiere decir que intentemos passwords en donde el primer caracter proviene del charset #2 (?2), es decir, sólo mayusculas (?u), y el resto de caracteres provienen del charset #1 (?1) es decir minúsculas (?l) y números (?d). Pero esta no es nuestra receta de forma correcta, pues nosotros construiremos un password que tenga una mayuscula no sólamente en la primera posición sino en cualquiera de las 8. No hay problema, simplemente el resultado de nuestro experimento lo multiplicaremos por 8 para contar las 8 posiciones donde puede estar nuestra masyúscula. Si leyeron la pequeña nota al pie de página de mi artículo anterior, este factor les debe sonar conocido. En todo caso veamos la velocidad de cracking para esta receta:

Status.......: Running
Hash.Target..: 504c4894815c8ececaa608268a0f3373
Hash.Type....: NTLM
Time.Running.: 2 seconds
Time.Left....: 24 minutes, 32 seconds
Plain.Mask...: ?2?1?1?1?1?1?1?1
Plain.Text...: **ysguca
Plain.Length.: 8
Progress.....: 4025548800/2037468266496 (0.20%)
Speed.GPU.#1.:  1381.2M/s
HWMon.GPU.#1.:  0% GPU, 72c Temp
[s]tatus [p]ause [r]esume [q]uit => q

Descomunal!! en este caso, sólo necesito de 24 minutos para intentar todas las combinaciones. Por supuesto este número hay que multiplicarlo por 8 porque la mayuscula puede estar en cualquier posición. Lo cual nos da unas míseras 3 horas mas o menos. Si ahora hacemos que nuestro password tenga una mayuscula y un dígito, el resultado es:

Status.......: Running
Hash.Target..: 504c4894815c8ececaa608268a0f3373
Hash.Type....: NTLM
Time.Running.: 1 second
Time.Left....: 1 minute, 9 secondsPlain.Mask...: ?2?3?1?1?1?1?1?1
Plain.Text...: **eartka
Plain.Length.: 8
Progress.....: 1277952000/80318101760 (1.59%)
Speed.GPU.#1.:  1141.6M/sHWMon.GPU.#1.:  0% GPU, 55c Temp
[s]tatus [p]ause [r]esume [q]uit => q

Resulta que a este resultado hay que multiplicarlo por 8 y por 7, para contar las 8 posiciones donde puede estar la mayuscula y las 7 posiciones donde puede estar el dígito una vez que la mayuscula haya sido seleccionada. O viceversa, es lo mismo. El resultado es un poquito más de una hora. Como detalle de implementación, se ejecutará el comando de arriba con las siguientes combinaciones de máscaras:

?2?3?1?1?1?1?1?1
?2?1?3?1?1?1?1?1
?2?1?1?3?1?1?1?1
...
?1?2?3?1?1?1?1?1
?1?2?1?3?1?1?1?1

etc. Ésto nos dará 56 mascaras que se demorarán 1 minuto cada una.

Lamentablemente, a pesar de que no queramos entenderlo, mientras más "metainformación" demos a nuestro atacante en la forma de "recetas" para construir nuestros passwords, le estamos haciendo el trabajo increiblemente más fácil. Por otro lado, los verdaderos parámetros para determinar la fortaleza de una contraseña no es tanto su composición, como lo es su longitud y el algoritmo utilizado para protegerla. La composición no es importante pues abandonaremos las recetas y utilizaremos cualquier combinacion de minusculas, mayusculas y numeros de formas no convencionales y más importante aún: "divulgadas a la menor cantidad de personas posible".

No hay comentarios:

Publicar un comentario