lunes, 26 de octubre de 2009

Basic? y tan Basic...

Basic Authentication es un medio de autenticación en entornos web basada en usuario y contraseña muy común cuando el administrador o el desarrollador quieren controlar el acceso a determinada parte de una web por tratarse de la zona de administración o, en general, de una zona privada. Sin embargo, utilizar este tipo de autenticación puede llevarnos a tener algunos problemas, como vamos a comprobar.

Vamos a ver un pequeño ejemplo muy común sobre servidor Apache que me encuentro con mucha frecuencia durante la realización de test de intrusión. Para ello lo primero que tenemos que hacer que hacer es crear el fichero .htaccess en el directorio que queramos proteger con el siguiente contenido:

# cat /var/www/.htaccess
AuthType Basic
AuthName "Password Required"
AuthUserFile /var/passwd.file
Require User admin


Una vez creado este fichero en el que decimos que al actual directorio solo puede acceder el usuario "admin" según las credenciales del fichero passwd.file, tendremos que crear este fichero passwd.file, empleando típicamente el siguiente comando:

# htpasswd -c passwd.file admin
New password: completamente.1NS3GuR0
Re-type new password: completamente.1NS3GuR0
Adding password for user admin
#
# cat passwd.file
admin:I5kjirKBkSgLM


Una vez creado este fichero, ya podemos acceder a la web y nos aparecerá la ventana de autenticación. Este mismo entorno es el que nos encontraremo muchas veces al realizar test de intrusión.

Sin embargo, a pesar de tratarse de una contraseña fuerte (17 carcteres con mayúsculas, minúsculas, números y signos de puntuación), el funcionamiento por defecto del comando htpasswd puede arruinar una buena contraseña. Según podemos leer en la propia documentación de Apache, el cifrado por defecto de las claves en Apache sobre Unix es mediante la utilización de la función CRYPT, que toma como valores de entrada un número aleatorio de 32 bits (salt) y los 8 primeros caracteres de la contraseña.

Este funcionamiento quiere decir que podemos simplificar el intento de obtención de una contraseña por medio de fuerza bruta o diccionario contra un servidor web Apache sobre Unix que haya empleado el mecanismo por defecto para generar la contraseña (algo muy muy muy habitual).

Cómo ejemplo, en primer lugar vamos a coger un diccionario estandar y vamos a utilizar la potencia que nos da John The Ripper para convertirlo en un diccionario de palabras truncadas hasta 8 caracteres y de paso que nos genere variaciones de mayusculas y minúsculas y otras lindezas que hace JTR. Utilizaremos como diccionario estandar uno de castellano, por ejemplo este:

# /pentest/password/jtr/john --wordlist=/root/spanish --rules --stdout=8 | uniq > /root/basiccrypt.lst
words: 1609221 time: 0:00:00:03 100% w/s: 484705 current: Zuzing
real 0m3.328s user 0m3.056s sys 0m0.232s


Una vez que ya tenemos nuestro diccionario preparado para basic, sólo tenemos que llamar a alguna de las miles de herramientas que realizar ataques de diccionario contra autenticación basic, como por ejemplo Medusa:

# time medusa -h 127.0.0.1 -u admin -P /root/basiccrypt.lst -M http | grep -v "ACCOUNT CHECK:"
Medusa v1.4 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks

ACCOUNT FOUND: [http] Host: 127.0.0.1 User: admin Password: completa [SUCCESS]

real 0m17.745s
user 0m3.036s
sys 0m3.708s


Como podemos ver, aunque estamos atacando un servidor web en local y por lo tanto el tiempo va a ser mucho más rápido que a través de Internet o en LAN, en no llega a 18 segundos hemos encontrado la contrasela completa como contraseña válida para el usuario admin, es decir, la contraseña que habiamos elegido pero truncada a 8 caracteres, con lo que ha perdido toda su fortaleza. Comprobemos si con esa contraseña efectivamente podemos entrar a la web:





Efectivamente, el funcionamiento por defecto del comando htpasswd de Apache sobre Unix nos ha hecho perder toda la fortaleza de la contraseña que habiamos elegido, lo cual puede facilitar a un intruso (o en mi caso a un pentester) el acceso a zonas privadas mediante un ataque de diccionario o incluso de fuerza bruta, limitando la longitud de la contraseña a 8 caracteres.

Para solucionar estos problemas, es necesario usar las opciones que nos proporciona el comando htpasswd para generar los hashes de las contraseñas. Veamos la ayuda del comando:

# htpasswd --help
Usage:
htpasswd [-cmdpsD] passwordfile username
htpasswd -b[cmdpsD] passwordfile username password

htpasswd -n[mdps] username
htpasswd -nb[mdps] username password
-c Create a new file.
-n Don't update file; display results on stdout.
-m Force MD5 encryption of the password.
-d Force CRYPT encryption of the password (default).
-p Do not encrypt the password (plaintext).
-s Force SHA encryption of the password.
-b Use the password from the command line rather than prompting for it.
-D Delete the specified user.
On Windows, NetWare and TPF systems the '-m' flag is used by default.
On all other systems, the '-p' flag will probably not work.


Por lo tanto, en lugar de usar las opciones por defecto, deberemos utilizar la opción que fuerza la utilización de SHA-1 para la generación de los hashes de las contraseñas, ya que de esta manera nuestra contraseña SI será tenida en cuenta en su totalidad, y las posibilidades de ataque se reducirán a la fortaleza de la contraseña que elijamos.

# htpasswd -c -s passwd.file admin
New password: completamente.1NS3GuR0
Re-type new password: completamente.1NS3GuR0
Adding password for user admin
#
# cat passwd.file
admin:{SHA}5Gi3c8394E/ruP7fIOVze6ZnJeM=

Si ahora volvemos a intentar entrar con la contraseña "completa" veremos que se nos deniega el acceso, por lo que deberemos obtener la contraseña real completa si queremos acceder al contenido protegido por la autenticación basic.

Un negativo para Apache por implementar en su comando una funcionalidad por defecto con estas características.

A cambiar hashes se ha dicho!!

2 comentarios :

José Miguel Holguín dijo...

Desde "pentester.es" hemos enviado una notificación a la lista de desarrollo de Apache para que añaden un aviso de que el password se trunca a 8 caracteres. Dado que CRYPT es usado por defecto es necesario avisar al usuario.
La contestación por parte de Apache ha derivado en la inclusion de un warning como podemos ver aquí.

Jose Selvi dijo...

Ahora falta que los admins se den cuenta del mensajito que les sale, que a veces se va con tanta prisa y es todo tan para ayer... que no se para uno ni a prestar atención en lo que pone el comando :P

Enga, le quitamos el negativo a Apache por su rápida respuesta xD