Mostrando entradas con la etiqueta password. Mostrar todas las entradas
Mostrando entradas con la etiqueta password. Mostrar todas las entradas
Autenticar con kerberos y almacenar información de usuarios con LDAP en GNU/Linux
En los artículos anteriores se explicaron las bases del funcionamiento y utilización de kerberos, LDAP y PAM. Además se explicó cómo autenticar usuarios de GNU/Linux utilizando kerberos. Con esta información en mente, ahora somos capaces de armar un servicio de autenticación centralizada para hosts GNU/Linux, que utilice estos ampliamente aceptados y utilizados servicios.

Para lograr que toda la información de usuarios y grupos se almacene y administre en servidores LDAP, debemos encontrar la forma de que las workstations GNU/Linux se comuniquen con LDAP para obtener los datos que comúnmente se encuentran en los archivos /etc/passwd, /etc/shadow y /etc/group.

En /etc/passwd tenemos los datos concernientes a los usuarios del sistema. Cada entrada representa un usuario y los campos almacenados son los siguientes:
  • credenciales (sólo el nombre de usuario se almacena en /etc/passwd, cuestiones de contraseña se encuentran en /etc/shadow)
  • ID, identificador de usuario
  • grupos a los cuales pertenece
  • nombre real
  • directorio home (ej: /home/demasiadovivo)
  • shell a utilizar (opcional)
Como ya adelanté en el punto anterior, /etc/shadow contiene información de contraseñas. Las contraseñas se almacenan hasheadas (o encriptadas en soluciones antiguas) utilizando un salt. Los campos que se almacenan para cada usuario son:
  • nombre de login
  • hash del password o el password encriptado.
  • fecha del último cambio de password.
  • edad mínima de un password, es decir, el número de días que el usuario debe esperar entre cambios de passwords.
  • edad máxima de un password. Duración del password, es decir, cuanto tiempo podemos usar un password como máximo.
  • período de advertencia. Cuántos días antes de que el password expire, el sistema debe avisar al usuario que esto sucederá.
  • período de inactividad de un password. La cantidad de días que un password debe ser aceptado para generar uno nuevo, luego de que el password expiró. Una vez que este período expira, el usuario no podrá loguearse más y deberá contactar al administrador.
  • fecha de expiración del usuario, en formato timestamp Unix.
Por su parte /etc/group contiene los datos de los grupos, donde para cada grupo se almacena lo siguiente:
  • nombre de grupo
  • contraseña de grupo encriptada (opcional)
  • GID, o identificador de grupo
  • lista de los usuarios que pertenecen al grupo
Cambiar el mecanismo de autenticación de usuarios en GNU/Linux es simple gracias a PAM (ver artículo anterior).
El problema con PAM, es que no permite acceder el resto de la información del usuario almacenada en un LDAP, es decir, información comúnmente almacenada en passwd, shadow y group. Para ello debemos valernos de otra herramienta, llamada NSS (Name Service Switch).
NSS permite utilizar distintas fuentes para obtener diferentes tipos de datos comunes, como los datos de usuario citados anteriormente. Es decir, agrega transparencia al resto de los programas a la hora de acceder dinstinta información. NSS es la capa que permite a un administrador configurar los sistemas para que obtengan de fuentes remotas datos que normalmente se buscarían en archivos locales en /etc (como passwd, group, hosts, etc).
Gracias a NSS, ahora podremos almacenar los datos que nos interesen, como los de usuarios y grupos, en LDAP, simplemente configurando el archivo /etc/nsswitch.conf


Creación de usuarios en kerberos

Para autenticar usuarios con kerberos, primero debemos agregar los principals correspondientes en la base de datos. Agregar un principal para un usuario es tan fácil como ejecutar addprinc utilizando kadmin:
# kadmin.local
Authenticating as principal root/admin@DEMASIADOVIVO.ORG with password.
kadmin.local: addprinc demasiadovivo
WARNING: no policy specified for demasiadovivo@DEMASIADOVIVO.ORG; defaulting to no policy
Enter password for principal "demasiadovivo@DEMASIADOVIVO.ORG":
Re-enter password for principal "demasiadovivo@DEMASIADOVIVO.ORG":
Principal "demasiadovivo@DEMASIADOVIVO.ORG" created.
Podemos checkear que el usuario se creó correctamente ejecutando kinit y klist:
# kinit demasiadovivo
Password for demasiadovivo@DEMASIADOVIVO.ORG:
# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: demasiadovivo@DEMASIADOVIVO.ORG
Valid starting Expires Service principal
06/22/11 14:07:18 06/23/11 00:07:18 krbtgt/DEMASIADOVIVO.ORG@DEMASIADOVIVO.ORG
renew until 06/23/11 14:07:14
Lo que hicimos fue obtener un ticket para el usuario demasiadovivo (con kinit), y luego listar los tickets cacheados en la máquina (klist). Como pudieron ver, /tmp/krb5cc_0 es nuestro ticket. Con klist se pueden ver varias propiedades de los tickets, como algoritmos de encripción (-e), direcciones en las credenciales (-a), etc. kinit también acepta varios parámetros, como tiempo de vida (-l), hora de inicio (-s), renovar un ticket (-R), etc.


Creación de usuarios en LDAP

Si bien podríamos utilizar la autenticación LDAP para autenticar los usuarios, lo mejor es utilizar el confiable kerberos, y dejar LDAP para almacenar los datos de usuarios, grupos y demás.
Como vimos anteriormente, debemos almacenar ciertos atributos del usuario que normalmente estarían en /etc/passwd. Dado que la autenticación la realizamos con kerberos, no es necesario almacenar el password del usuario, aunque esto podría hacerse si se quisiera autenticar con LDAP.

Existe un RFCs (RFC 2307), que describe un mecanismo para mapear entidades UNIX al estándar X.500, para que los atributos se puedan resolver utilizando LDAP. Si bien este documento es experimental, se utiliza ampliamente en el mundo UNIX.
La librería NSS-LDAP utiliza este mapeo para resolver los atributos del usuario, por lo tanto es el formato que debemos adoptar para crear las entradas en el LDAP. OpenLDAP trae esquemas predefinidos para este mapeo, los cuales pueden encontrar en /etc/ldap/schema/nis.schema. Los objectClass que utilizaremos comúnmente son posixAccount, shadowAccount y posixGroup.

Veamos cómo se mapea cada campo del /etc/passwd en atributos LDAP:
  • login name = uid
  • user ID = uidNumber
  • group ID = gidNumber
  • nombre de usuario = cn para el nombre y sn para el apellido.
  • directorio home = homeDirectory
  • shell = loginShell (opcional)
Los usuarios que deseemos autenticar con Kerberos y LDAP deberán tener definida una entrada con estos datos, en la unidad organizativa (OU) People, y con posixAccount como objectClass. El Distinguished Name (DN) de cada usuario tendrá el formato uid=,ou=People,dc=demasiadovivo,dc=org.

Por su parte, el equivalente de atributos para cada grupo es el siguiente:

  • nombre del grupo = cn
  • contraseña = userPassword (opcional)
  • group ID = gidNumber
  • lista de usuarios = memberUid
Los grupos deben situarse en la OU Group y con posixGroup como objectClass. El DN se arma utilizando cn=,ou=Group,dc=demasiadovivo,dc=org.

Ahora que contamos con los datos suficientes para crear un usuario, creemos el archivo user1.ldif donde pondremos la definición de nuestro primer usuario y grupo.

dn: cn=Administrador_Seguridad,ou=Group,dc=demasiadovivo,dc=org cn: Administrador_Seguridad gidNumber: 2000 objectClass: top objectClass: posixGroup
dn: uid:demasiadovivo,ou=People,dc=demasiadovivo,dc=org uid: demasiadovivo uidNumber: 2000 gidNumber: 2000 cn: Victor objectClass: top objectClass: person objectClass: posixAccount objectClass: shadowAccount loginShell: /bin/bash homeDirectory: /home/demasiadovivo
En la definición encontramos varios objectClass. Para el caso de grupos, utilizamos la ya mencionada posixGroup, mientras que para usuarios usamos person, posixAccount, y shadowAccount. La clase person nos permite agregar información atributos como número de teléfono y descripción. Por su parte, shadowAccount permite agregar atributos concernientes al tratamiento de passwords, como el password en si, fecha de último cambio, y resto de información que se encuentra en /etc/shadow. Si bien no almacenaremos passwords en LDAP, sí resulta útil guardar el resto de la información referente al mismo.

Para agregar el usuario, ejecutamos ldapadd de la siguiente manera:
ldapadd -c -x -D cn=admin,dc=demasiadovivo,dc=org -W -f user1.ldif
Podemos verificar los datos recien ingresados con:

ldapsearch "(uid=demasiadovivo)" -x
y
ldapsearch "(cn=Administrador_Seguridad)" -x


Configurar PAM para utilizar kerberos

Este paso ya se explicó en el artículo del mismo nombre que pueden encontrar aquí


Configurar NSS para utilizar LDAP

Como ya adelante en las secciones anteriores NSS (Name Service Switch) es una funcionalidad provista por la librería GNU C para independizar a las aplicaciones de la ubicación de los servicios.
Antíguamente los datos se buscaban en archivos locales como /etc/passwd, /etc/group, /etc/hosts, etc, pero con el crecimiento de tecnologías de base de datos centralizadas como DNS, NIS, LDAP, etc, se hizo evidente la necesidad de contar con un servicio que abstraiga al programa de la ubicación de los datos. Por ello se creó NSS, basándose en un método utilizado por Sun en Solaris 2.
NSS permite al administrador configurar dónde se encontrarán los datos de diferentes bases de datos a través del archivo nsswitch.conf. Incluso se puede establecer un orden sobre qué base de datos consultar primero. El programa sólo utiliza una llamada al sistema y se olvida de donde se encuentran los datos. Gracias a esto, cambiar de base de datos es muy simple. Este caso es muy similar al de PAM.
Entre las bases de datos que podemos configurar tenemos:
  • password: información de usuarios. Default /etc/passwd
  • group: información de grupos de usuarios. Default: /etc/group
  • shadow: contraseñas de usuario. Default: /etc/shadow
  • hosts: nombres de computadoras. Default: /etc/hosts
  • network: nombres de redes. Default: /etc/networks
 Algunas posibles fuentes de datos son:
  • files: archivos, por ejemplo /etc/passwd
  • compat: se puede usar para traer información de usuarios y grupos en archivos con nueva sitaxis como /etc/passwd, /etc/shadow, /etc/group
  • dns: obtener la información de hosts de servidores DNS
  • ldap: traer los datos del directorio LDAP
 Para utilizar LDAP como base de datos de usuarios, deberemos instalar la librería NSS correspondiente. Antes de hacer este paso, es recomendable hacer un backup de los archivos /etc/pam.d/{common-auth,common-account,common-password,common-session}:
cp /etc/pam.d/{common-auth,common-account,common-password,common-session} /root/backup
Luego entenderán porque es necesario este backup.
Ahora si, instalamos la librería libnss-ldapd que provee servicios LDAP para NSS, y el demonio nslcd que es el encargado de realizar las búsquedas LDAP para los procesos que quieran información de usuarios, grupos, etc:
# apt-get install libnss-ldapd nslcd
NOTA: Algo a tener en cuenta aquí es utilizar libnss-ldapd y no libnss-ldap. Con la segunda no pude realizar autenticación de usuarios utilizando GSSAPI, a pesar de mucho intentarlo. libnss-ldapd es más nueva y mejora varias cuestiones de libnss-ldap.

En la instalación, debconf requerirá algunos datos de configuración.
Para el paquete libnss-ldapd:

  • Servicios a configurar para que utilicen LDAP. Los valores por defecto sirven para la mayoría de los casos: passwd, shadow, y group.
 Por su parte, el paquete nslcd solicita:
  • URI del servidor LDAP: ldap://ldap.demasiadovivo.org/
  • DN base para las búsquedas ldap: dc=demasiadovivo,dc=org
El siguiente paso es configurar NSS para que utilice LDAP para buscar información de usuarios. Para esto, hay que editar el archivo /etc/nsswitch.conf para que quede de la siguiente manera:
passwd: files ldap group: files ldap shadow: files ldap
hosts: files dns networks: files
protocols: db files services: db files ethers: db files rpc: db files
netgroup: nis
Se puede observar que el sistema intentará resolver los datos de usuario localmente, y si no puede, consultará al servidor ldap.
Como el demonio nscd cachea los valores, es necesario reiniciarlo:

# /etc/init.d/nscd restart
Para testear la configuración, se puede utilizar el comando getent. Este comando permite obtener entradas de la base de datos administrativa, esto incluye passwd, group, hosts, services, protocols y networks.
La mejor forma de ver que todo está funcionando es obtener los datos de un usuario que esté declarado en el servidor LDAP, pero que no esté localmente. Si por ejemplo el usuario demasiadovivo no se encuentra declarado en el /etc/passwd local y si en el LDAP, pueden probar el siguiente comando:

$ getent passwd demasiadovivo demasiadovivo:x:2000:2000:Victor:/home/demasiadovivo:/bin/bash
Pueden corroborar que el usuario no existe localmente mirando /etc/passwd.
Si ejecutan "getent passwd" sin un nombre de usuario, pueden ver la base de datos completa de usuarios, que incluye a los locales y a los de LDAP.


Prueba de login

Bien, ya tenemos todo lo necesario para ver si nuestro sistema centralizado de usuarios está funcionando correctamente. Veamos los pasos que seguimos hasta aquí:

  • instalamos kerberos
  • instalamos LDAP
  • dimos de alta al usuario demasiadovivo en kerberos y configuramos un password
  • dimos de alta al usuario demasiadovivo en LDAP, donde pusimos toda la información necesaria del /etc/passwd
  • configuramos PAM en la máquina cliente para que autentique utilizando kerberos. Incluso agregamos una regla en common-session para que se cree un directorio home para los usuarios que no existan localmente.
  • configuramos NSS en la máquina cliente para busque los datos del usuario en LDAP
Ufff, fue mucho trabajo, pero si todo fue bien, estamos al borde de la gloria (?!). La prueba? loguearnos con el usuario demasiadovivo en la máquina cliente y ver si anda =D
machine login: demasiadovivo Password: Linux machine 2.6.32-5-amd64 #1 SMP Mon Mar 7 21:35:22 UTC 2011 x86_64
The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Creating directory '/home/demasiadovivo' machine@demasiadovivo:~$ id uid=2000(demasiadovivo) gid=2000(Administrador_Seguridad) grupos=2000(Administrador_Seguridad)
yeah! como se puede observar, el sistema automáticamente creó el directorio home y asignó los IDs correspondientes al usuario, como se declaró en la correspondiente entrada LDAP.

CUIDADO!
Algo que hay que tener muy en cuenta es que kerberos utiliza verificación de host resolviendo el nombre de la máquina desde donde nos conectamos. Por ello es necesario tener definido el nombre de la máquina y el mapeo IP-nombre (registro PTR) en el servidor DNS. Caso contrario, pueden encontrarse con el siguiente error en /var/log/auth.log:

pam_krb5(login:auth): (user demasiadovivo) credential verification failed: Hostname cannot be canonicalized

Referencias

- Authentication against LDAP servers
- PADL Software Pty Ltd - nss_ldap
- OpenLDAP installation on Debian
- MIT Kerberos installation on Debian
- OpenLDAP provider with MIT Kerberos V on Debian squeeze
- OpenLDAPServer
- SingleSignOn
- The POSIX API
- Linux NSS (libnss) and nss_ldap problems and possible solutions
- LDAPClientAuthentication
- LDAP Implementation HOWTO - 2. LDAP authentication using pam_ldap and nss_ldap
- opensolaris - About the Name Service Switch
- NSS Wiki
- Linux Authentication Using OpenLDAP, Part One
- ZYNTRAX - Chapter 5. OpenLDAP Samples - 5.2 Securing the Directory
- SEAM Error Messages and Troubleshooting
- Kerberos and LDAP
- Replacing NIS with Kerberos and LDAP HOWTO
LDAP System Administration - A.2 Name Service Switch (NSS)
Configurar PAM para utilizar kerberos
En artículos anteriores se explicó cómo funciona kerberos y la forma de utilizarlo en GNU/Linux. Las workstations con Linux instalado pueden autenticar sus usuarios contra servidores de este tipo, ya sea que los mismos utilicen Linux, Windows (Active Directory), o cualquier otro SO que implemente el estándar. La configuración descripta a continuación es la misma sin importar sobre qué plataforma se implemente el servicio kerberos. Es decir, se puede utilizar, por ejemplo, para autenticar clientes Linux contra el servicio Active Directory de Windows.

Para la autenticación con kerberos, hay que instalar el módulo de PAM correspondiente, en todos los clientes. En debian, el paquete se denomina libpam-krb5:
# apt-get install krb5-{config,user} libpam-krb5
Durante la instalación, debconf requerirá algunos datos para continuar:
- el nombre del realm: DEMASIADOVIVO.ORG
- servidores kerberos para el realm, separados con espacios.
- servidor administrativo para el realm, para administrar cambio de contraseña.
Estos son los mismos datos que configuramos al instalar el servidor kerberos. Toda esta configuración se puede cambiar en el archivo /etc/krb5.conf.
En este archivo, como se explicó en la instalación del servidor, pueden eliminar todos los realms que aparecen en la instalación default (athena, mit, etc), y deberán agregar el dominio de su realm en la sección domain_realm:
[domain_realm]
.demasiadovivo.org = DEMASIADOVIVO.ORG
demasiadovivo.org = DEMASIADOVIVO.ORG
Luego de que se instala el módulo de kerberos, debian automáticamente establece en PAM que la autenticación de usuarios debe utilizar este protocolo. Si no están utilizando debian, tal vez requieran una configuración adicional para empezar a utilizarlo.

Veamos entonces cómo deberían quedar cada uno de los archivos de PAM, y el significado de cada configuración:

/etc/pam.d/common-account
account [success=1 new_authtok_reqd=done default=ignore] pam_unix.so
account requisite pam_deny.so
account required pam_permit.so
account required pam_krb5.so minimum_uid=1000
Se puede observar que este archivo es muy similar a cuando se utiliza sólo autenticación Unix. Para agregar la autenticación de kerberos, se agrega una línea final que invoca el módulo pam_krb5 con el argumento minimum_uid=1000.
En este caso, el sistema invoca tanto el módulo pam_unix como pam_krb5 como required, lo cual implica que si alguno de estos falla, la operación falla. El argumento "minimum_uid=1000" hace que la autenticación kerberos se aplique a los usuarios cuyo user ID sea mayor a 1000. Esto permite tener cuentas locales como la de root (uid=0), la cual no autentica contra kerberos.

/etc/pam.d/common-auth
auth [success=2 default=ignore] pam_krb5.so minimum_uid=1000
auth [success=1 default=ignore] pam_unix.so nullok_secure try_first_pass
auth requisite pam_deny.so
auth required pam_permit.so
En este archivo podemos ver como funciona la autenticación propiamente dicha. Primero se intenta autenticar con kerberos a los usuarios cuyo uid es mayor o igual a 1000. Si esto tiene éxito, se salta a la línea pam_permit (success=2) y el usuario puede entrar. Si la autenticación kerberos falla, se intenta con la autenticación unix tradicional, permitiendo password en blanco (nullok_secure), y utilizando el mismo password que se utilizó en la autenticación kerberos (try_first_pass). Esto último se hace para que el sistema no requiera el password dos veces cuando la autenticación kerberos falla. Si ninguna de las autenticaciones es exitosa, se niega el acceso (pam_deny).

/etc/pam.d/common-pasword
password requisite pam_krb5.so minimum_uid=1000
password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass sha512
password requisite pam_deny.so
password required pam_permit.so
Para el cambio de password se utiliza como requisito pam_krb5 con uid mayor igual a 1000. Si esto falla, el password no se actualiza. Si el password kerberos se actualiza correctamente, se intenta actualizar el password local, utilizando el mismo pass ingresado para kerberos (use_authtok). El resto de los argumentos de pam_unix son los mismos que cuando se utiliza autenticación tradicional, donde obscure checkea fortaleza del pass, y sha512 es el algoritmo para hashear el pass.
Algo a tener en cuenta aquí es que si la actualización del password local falla, la operación falla aunque el password kerberos no haya tenido problemas.

/etc/pam.d/common-session
session [default=1] pam_permit.so
session requisite pam_deny.so
session required pam_permit.so
session optional pam_krb5.so minimum_uid=1000
session required pam_unix.so
Finalmente en el archivo de session encontramos una regla adicional y opcional que es la de kerberos. Algo interesante que podemos hacer en este archivo es agregar una regla para la creación del directorio home del usuario.
Si creamos un usuario en kerberos y no en la máquina cliente, cuando éste intente ingresar, el sistema arrojará error si el home no existe, porque este directorio no se crea al agregar el usuario.
Para esto, existe un módulo denominado pam_mkhomedir. Este módulo crea el directorio home del usuario cuando éste se loguea por primera vez. Si el directorio ya existe, no hace nada. Un argumento interesante para este módulo es skel, que permite especificar el esqueleto del directorio home.
Podemos modificar el archivo anterior para agregar esta funcionalidad, de la siguiente manera:
session [default=1] pam_permit.so
session requisite pam_deny.so
session required pam_permit.so
session required pam_mkhomedir.so skel=/etc/skel/
session optional pam_krb5.so minimum_uid=1000
session required pam_unix.so
Con esto, la próxima vez que se autentique un usuario en el cliente configurado, éste utilizará kerberos en lugar del tradicional sistema Unix. Claro que el usuario a utilizar debe estar previamente creado en el servidor kerberos.
Una vez autenticados, se puede ver el ticket generado ejecutando klist:
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000_s6uumi
Default principal: demasiadovivo@DEMASIADOVIVO.ORG

Valid starting Expires Service principal
09/24/11 08:08:07 09/24/11 18:07:57 krbtgt/DEMASIADOVIVO.ORG@DEMASIADOVIVO.ORG
renew until 09/24/11 18:08:07
Autenticación en GNU/Linux con PAM
Antiguamente, la autenticación en sistemas UNIX estaba ligada al que hoy conocemos como "sistema tradicional UNIX", el cual verifica usuario y contraseña contra los valores almacenados en el archivo /etc/passwd (en versiones modernas el password se movió al archivo /etc/shadow por cuestiones de seguridad).
Dado que con los años se fueron desarrollando distintos métodos de autenticación más seguros, seguir clavados utilizando el método tradicional era poco flexible y sin sentido.
A partir de la necesidad de poder cambiar fácilmente entre métodos de autenticación y utilizar distintos métodos, Sun diseñó PAM (Pluggable Authentication Modules). PAM es un conjunto de librerías que permiten una gran variedad de mecanismos de autenticación, entre los cuales contamos con Kerberos, LDAP, y RADIUS (además del tradicional /etc/passwd). Gracias a esto, actualmente es posible autenticar usuarios GNU/Linux contra bases centralizadas de usuarios como el citado kerberos.
PAM no sólo permite utilizar distintos métodos de autenticación, sino que permite utilizar varios al mismo tiempo. Además agrega la posibilidad de utilizar otros medios de autenticación (más allá del clásico usuario/password), como ser smartcards, tockens, etc.

En este artículo les explicaré cómo se configura la autenticación utiliando PAM, y sobre el final podremos entender la configuración de un debian default.


Configuración

PAM divide la tarea de autenticación en cuatro grupos de administración separados:
- account provee verificación de tipos de servicio para la cuenta: el password expiro? tiene permitido acceder el servicio requerido? root puede loguearse por consola?
- authentication autentica el usuario, y luego otorga los privilegios correspondientes (como membresía de grupo). Este módulo permite setear distintos requerimientos para autenticar al usuario, como passwords, smartcards, tockens, etc.
- password es responsable de actualizar los mecanismos de autenticación. Estos servicios están fuertemente acoplados con los del grupo authentication.
- session cubre las acciones que se deben hacer antes de que se otorgue un servicio y luego de que el servicio haya sido retirado. En el caso de login, las acciones pueden ser logging y montado de directorios.
La configuración de PAM se realiza a través de reglas y el archivo principal es /etc/pam.conf, aunque en general se prefiere dividir las reglas en diferentes archivos del directorio /etc/pam.d/.
Cada regla tiene cinco campos, separados por espacios:
servicio tipo control path-modulo argumentos-modulo
donde:
- servicio es el nombre familiar que corresponde a la aplicación (ej: login, su, sshd). Este campo no se incluye en los archivos de /etc/pam.d, dado que el servicio está indicado por el nombre del archivo en minúscula. El servicio correspondiente a login utiliza a los archivos common-account, common-auth, common-password y common-session para configurar cada uno de los grupos.

- tipo: es el grupo de administración al que se aplica la regla (account, auth, password o session).

- control indica el comportamiento que PAM debe seguir en caso de que el módulo asociado tenga éxito o falle. Este campo permite dos notaciones. En la notación simple, se utiliza una palabra clave, y en la compleja se encierran pares valor=acción entre corchetes [valor1=acción1, valor2=acción2, ....]
Una característica importante de PAM es que las reglas se pueden "apilar" para combinar los servicios de varios PAMs para una dada autenticación. Los valores de retorno de cada módulo se guardan en una pila. Gracias a esto, es posible, por ejemplo, intentar autenticar primero con kerberos, y si esto falla, intentar autenticar localmente con autenticación unix.

Las palabras claves más comúnmente utilizadas en la notación simple, son:
- required: indica que la ejecución del módulo debe ser exitosa para que la operación sea exitosa. Sin embargo, si el módulo falla, la operación fallará recién luego de que se invoque al resto de los módulos que vienen después.
- requisite: igual que required, pero si el módulo falla, se retorna el control directamente a la aplicación. Es decir, no se continua invocando módulos como sucede con required.
- sufficient: el éxito del módulo es requerimiento suficiente para la operación, esto es, no se continúa procesando los siguientes módulos. Si falla, el proceso continúa en la siguiente regla.
- optional: el resultado de este módulo es importante sólo si es el único en el stack.
En la notación compleja, los valores son códigos de retorno. Los más vistos comúnmente son:
- success: la función retornó ok
- ignore: ignorar el módulo en cuestión, sin importar si el flag de control es required, optional o sufficient.
- new_authtok_reqd: se requiere un nuevo token de autenticación. Utilizado generalmente cuando el password debe ser cambiado.
- default: implica todos los valores que no se mencionan explícitamente.
Las posibles acciones en esta notación pueden ser un entero n sin signo, que indica la cantidad de módulos a saltar en el stack, o tomar alguna de las siguientes formas:
- ignore: el estado de retorno del módulo no influenciará el resultado final, a menos que no haya otro módulo en el stack.
- bad: el estado de retorno debe indicar el fallo del módulo. Si esta es la primer falla, este estatus se usará para todo el stack.
- die: idem a bad, excepto que el stack termina y se retorna el control a la aplicación inmediatamente.
- ok: el código de retorno sobreescribirá un valor previo de éxito, pero no un estado previo de falla.
- done: idem a ok, excepto que el stack termina y el control se retorna inmediatamente a la aplicación.
- reset: se limpia el stack y se comienza de nuevo con el próximo modulo.
Como se puede observar, en la notación compleja se permite mucha más granularidad que utilizando palabras claves. Por ello, es posible representar los mismos valores que las palabras claves con notación compleja:
required = [success=ok new_authtok_reqd=ok ignore=ignore default=bad]
requisite = [success=ok new_authtok_reqd=ok ignore=ignore default=die]
sufficient = [success=done new_authtok_reqd=done default=ignore]
optional = [success=ok new_authtok_reqd=ok default=ignore]
- path-modulo es el path al módulo, o la dirección relativa al directorio donde se ubican los módulos por default, el cual es /lib/security en debian.

- argumentos-modulo son los argumentos, separados por espacios, que se envían al módulo.

Ejemplo práctico

Para entender mejor cómo funciona PAM, veamos el contenido de los archivos en la configuración de un sistema debian default.
/etc/pam.d/common-account (verificación de tipos de servicio)
account [success=1 new_authtok_reqd=done default=ignore] pam_unix.so
account requisite pam_deny.so
account required pam_permit.so
De la explicación anterior, podemos entender que el sistema utilizará el módulo pam_unix. Si esta autenticación tiene éxito (success=1), se saltea la siguiente regla y se ejecuta el módulo pam_permit, permitiendo el acceso.
En caso de fallar, se ejecuta el módulo pam_deny, el cual siempre retorna un valor de fallo; y como el parámetro de control es "requisite", la operación termina inmediatamente.

/etc/pam.d/common-auth (autenticación de usuario y seteo de credenciales)
auth [success=1 default=ignore] pam_unix.so nullok_secure
auth requisite pam_deny.so
auth required pam_permit.so
Este caso es casi igual al anterior, sólo que se utiliza el parámetro nullok_secure al llamar al módulo. En la acción default del módulo no se permite el acceso a un servicio si su password oficial es nulo. Lo que hace este parámetro es sobreescribir este comportamiento y permitir usuarios con password en blanco.

/etc/pam.d/common-password (actualización de passwords)
password [success=1 default=ignore] pam_unix.so obscure sha512
password requisite pam_deny.so
password required pam_permit.so
password optional pam_gnome_keyring.so
En este archivo el cambio es que se agregan los parámetros obscure y sha512 al módulo pam_unix. obscure fuerza el checkeo de la fortaleza del password y sha512 hace que los passwords se almacenen hasheados con sha512.
El módulo pam_gnome_keyring permite el desbloqueo del archivo donde Gnome almacena credenciales del usuario (viene con Gnome). Como ven, el resultado de la ejecución de este módulo no afecta el resultado final de la operación.

/etc/pam.d/common-session (acciones a realizar antes de login y luego de logout)
session [default=1] pam_permit.so
session requisite pam_deny.so
session required pam_permit.so
session required pam_unix.so
En este último archivo no encontramos nada especial, sólo que se ejecuta el módulo pam_unix. El formato de este archivo no tiene mucho sentido, porque dado que pam_permit siempre termina bien, lo siguiente a ejecutar es nuevamente pam_permit, con lo cual se continúa hasta la ejecución de pam_unix. La razón de que esto esté así es por compatibilidad con los archivos anteriores, ya que si observan bien, la estructura es similar.


Referencias

- PAM configuration guide for Debian
- The Linux-PAM System Administrators' Guide - 4. The Linux-PAM configuration file
- Understanding PAM
Cómo descifrar un hash MD5 online
Aloe Vera
Este fin de semana me encontré con la necesidad de descifrar un password hasheado con md5. Para ello estuve a punto de utilizar el viejo y querido John the Ripper, pero un segundo antes se me ocurrió buscar alguna herramienta online que haga el trabajo por mí. Motivado por la vagancia, pero también para hacerlo más rápidamente (aprovechando la nube o rainbow tables), encontré buscando en Google este muy buen artículo: How to crack MD5 passwords online, el cual contiene una lista de servicios para reconstruir texto digerido mediante md5.
La mayoría de estos sitios utilizan rainbow tables (grandes tablas de hashes precomputados) con el objetivo de intercambiar tiempo de ejecución por memoria. De esta forma el resultado logrado es muy rápido (si es exitoso). Aunque también algunos utilizan diccionarios.

A continuación dejo la lista de servicios que realizan esta tarea. Les recomiendo que lean el artículo original, ya que el autor incluye una valuación de los mismos (calculada como la cantidad de hashes encontrados de un conjunto de 10):
www.tmto.org
md5.noisette.ch
md5decryption.com
www.c0llision.net
www.netmd5crack.com
www.md5decrypter.com
md5hashcracker.appspot.com
www.hashhack.com
isc.sans.edu
www.md5crack.com
passcracking.com
authsecu.com
md5.rednoize.com
md5.web-max.ca
www.cmd5.com
md5.thekaine.de
www.shell-storm.org
www.md5this.com
www.hashchecker.com
hashcrack.com
md5pass.com
md5pass.info

Cabe destacar que algunos de estos sitios incluyen una herramienta para generar hashes md5. No es recomendable utilizarlas para calcular hashes de nuestras contraseñas, ya que no sabemos si guardan los hashes que calculamos en sus bases de datos, lo cual las vuelve 100% crackeables ;)

Para lograr mi objetivo, tomé el primer servicio de la lista y obtuve el texto hasheado (admin1234) en 3.55 segundos. Lo que más me molestó fue que había probado sin éxito varias contraseñas, entre las que se encontraban 'admin', '1234' y 'admin123' pero no 'admin1234'!



Para finalizar, dejo un excelente artículo que explica cómo utilizar Google como password cracker (a esta altura creo que a Google le descubren más propiedades que al Aloe Vera). La justificación de esta técnica es que a veces los programadores incluyen hashes md5 en la URL (para ver la explicación detallada les recomiendo lean el artículo), lo que transforma a las bases de datos de Google en rainbow tables.


No me deja de sorprender la cantidad de tareas útiles que se pueden realizar utilizando Google, la mayoría de las cuales con propósitos o fines no pensados en un simple buscador. Es aquí donde uno toma conocimiento del verdadero poder y valor de la información.

Espero que les sirva!
Configurando una red inalámbrica hogareña
Luego de un período con grandes cambios a nivel personal, vuelvo a tener tiempo (y ganas) de escribir un artículo. En este caso para contar mis experiencias configurando mi red inalámbrica hogareña.

Para comenzar el desarrollo de la red hace falta conseguir lo más importante, que es el router inalámbrico. La marca/modelo a comprar depende del área a cubrir y el dinero que dispongamos. En mi caso opté por un router TP-LINK TL-WR340G ya que sólo me interesa cubrir mi departamento y es una opción super económica.

La configuración de este router es extremadamente sencilla: conectamos el cable de red de nuestro ISP al router; conectamos nuestra PC/Notebook (utilizando una IP fija 192.168.0.0/24) a una boca ethernet del router; y finalmente ingresamos por Web al router ingresando 192.168.1.1 en nuestro navegador.

La interfaz Web es muy intuitiva y haciendo unos pocos clics ya tenemos la red inalámbrica funcionando con DHCP. Lo más importante son dos cuestiones. La primera: dependiendo del servicio de Internet contratado, será necesario configurar PPPoE (Point-to-Point Protocol over Ethernet) para conectarse al ISP (con un nombre de usuario y contraseña otorgados por el proveedor). La segunda: habilitar la seguridad Wireless en el router (autenticación y encripción). A pesar de que WEP es mejor que nada, es un protocolo que posee varias debilidades, por lo tanto es altamente recomendable utilizar WPA/WPA2. Basta con seleccionar WPA-PSK (PSK: Pre-Shard Key, autenticación mediante clave compartida) en el router y utilizar una clave fuerte (formada por letras mayúsculas, minúsculas, números, símbolos y lo suficientemente larga).

Luego de configurar el router (la parte sencilla) la tarea de configurar los clientes no fue tan trivial.

El primer cliente fue una Notebook con Windows XP instalado de base con su placa de red inalámbrica funcionando correctamente. Para conectarlo a nuestra red simplemente hacemos clic derecho sobre el ícono del adaptador de red inalámbrico en la barra de tareas, luego clic en "Ver redes inalámbricas disponibles", luego seleccionamos nuestra red, clic en "Conectar" e introducimos la contraseña dos veces. Hasta acá muy fácil y bonito.

El siguiente cliente fue una Notebook con Ubuntu 9.04. Esta versión de Ubuntu ya incorpora los drivers para la placa de red Realtek RTL8187B y funciona correctamente. Pero los problemas comenzaron al tratar de conectarse a una red protegida con WPA. Ya sea utilizando el administrador de redes "network-manager" o "Wicd", la conexión se pierde luego de un corto lapso de tiempo. El error se repite una y otra vez. Luego de investigar un tiempo en Internet supe que se trata de un problema de autenticación (bastante común entre los usuarios de esta distro) entre gnome-keyring/Dbus/Network Manager. Para solucionarlo le otorgué permisos para utilizar adaptadores inalámbricos al usuario en cuestión desde el menú "System > Administration > Users and Groups". Luego de esto, utilizando Wicd, la red comenzó a funcionar "más o menos bien" aunque tarda mucho tiempo en detectar y conectarse a la red y sufre alguna desconexión esporádica.
La solución a implementar para que la red funcione perfectamente en este sistema operativo es la misma que describo más adelante para Slackware.

El próximo cliente fue una PC con Windows XP. Como no tenía un adaptador de red inalámbrico decidí comprar uno USB (la solución más económica y práctica para mis necesidades). Luego de conectar el dispositivo cometí el error de instalar los controladores directamente desde el disco compacto que incluía en la caja. Este instalador agregó un horrible manejador de redes inalámbricas en la barra de tareas que reemplazó al manejador de redes inalámbricas de Windows. Luego de la clásica reiniciada, el manejador no detectó ninguna red y no me permitió utilizar el de Windows. Por lo tanto tuve que desinstalar los controladores, reiniciar y comenzar de nuevo, esta vez utilizando el "Asistente para agregar hardware" en lugar del instalador del CD. Cuando se abre el asistente insertamos el CD y presionamos en "Siguiente". Luego de que Windows detecta los drivers que se encuentran en el CD, seleccionamos el driver de acuerdo a nuestra versión de Windows y continuamos con la instalación.
Una vez instalado el hardware utilizamos (previa reiniciada) el manejador de redes inalámbricas de Windows que se encuentra en la barra de tareas y nos conectamos perfectamente a nuestra red (esta vez sin utilizar el horrible manejador de redes incorporado en el CD del fabricante) como para el caso del primer cliente.

Luego de renegar con Windows y Ubuntu me puse el overol para aprender cómo funcionan las cosas de la mano de Slackware. La versión 13.1 instalada en la PC incorpora los drivers para el adaptador USB (utiliza el mismo chip Realtek RTL8187B de la notebook) por lo tanto la red inalámbrica funciona perfectamente.
Ya que vamos a conectarnos a una red inalámbrica con seguridad WPA, no basta con utilizar iwconfig para configurar el adaptador, es necesario utilizar wpa_supplicant. WPA Supplicant es el componente del protocolo IEEE 802.1X/WPA utilizado en las estaciones cliente. Implementa la negociación de claves con un autenticador WPA (en este caso nuestro router). Funciona como un demonio que se ejecuta en background y actúa como un componente back-end que controla la conexión wireless. En Slackware 13.1 viene incluido en la instalación base y en las distribuciones basadas en Debian lo provee el paquete wpasupplicant.
wpa_supplicant toma la configuración de las redes inalámbricas con seguridad WPA desde el archivo /etc/wpa_supplicant.conf. Para agregar una red en este archivo se utiliza el comando wpa_passphrase con el SSID de la red como parámetro:

$ wpa_passphrase myssid


Este comando lee la clave compartida de la red WPA (la misma que ingresamos en el router) por la entrada estándar y genera la clave encriptada para almacenar en el archivo /etc/wpa_supplicant.conf (para no tener que escribir la contraseña cada vez que nos conectamos a la red). Copiamos la salida de wpa_passphrase y la pegamos al final del archivo /etc/wpa_supplicant.conf.
Luego de estos pasos podemos conectarnos a la red inalámbrica:

# iwconfig wlan0 essid "myssid"
# ifup wlan0
# wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf
# dhcpcd wlan0


El cliente WPA Supplicant es bastante vervoso e imprime por salida estándar todos los pasos durante la autenticación con el AP. Luego podemos verificar que la red haya tomado una dirección IP desde el AP utilizando el comando ifconfig.

Parece una tarea tediosa, pero el aprendizaje es invaluable y la red funciona excelentemente.

Aunque si no desean escribir estos 4 comandos cada vez que se conecten a la red, en Slackware pueden agregar un script en /etc/rc.d que lo haga automáticamente o en las distribuciones basadas en Debian pueden editar el archivo /etc/network/interfaces:

auto wlan0
iface wlan0 inet dhcp
up wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -Bw
down killall wpa_supplicant


La opción -B pone el demonio wpa_upplicant en background y la opción -w le indica que no haga anda hasta que la interfase esté levantada.

Luego de esta tarea tengo mi red inalámbrica funcionando en perfectas condiciones. A aquellos usuarios de Linux espero que les sirva la info y a los de Windows, bueno... nadie es ferpecto.

Saludos!


P.S.: Perdón por las screenshots!


Referencias:

  • http://hostap.epitest.fi/wpa_supplicant/
  • http://www.enterprisenetworkingplanet.com/netsecur/article.php/3594946/Linux-on-Your-WLAN-Configure-WPA.htm
Es todo acerca de passwords!
Uno de los temas en los que los departamentos de seguridad deben poner énfasis es en concientizar a los usuarios para que utilicen passwords fuertes. No es una tarea sencilla, y puede llevar a discusiones interminables sobre escusas de por qué es difícil recordar passwords largos, pero es algo que debe hacerse y es tal vez más importante que muchos otros aspectos de seguridad.
No es solo cuestión de los usuarios, sino y más importante, de los administradores de sistema. Es sorprendente la baja importancia que se le da a los passwords incluso en áreas donde se conocen los riesgos a los que uno se expone. En parte también es culpa de políticas mal diseñadas que fuerzan a un pobre mortal a cambiar un password continuamente y hacer que el olvido de contraseñas sea algo tan común que se decide utilizar pavadas como passwords.

Ojo, no me excluyo del tema, y es entendible que un usuario que tiene acceso a más de 3 aplicaciones por día, con distintos passwords, los cuales debe cambiar cada cierto tiempo y no se permiten repeticiones (por ejemplo, no podes repetir un password que pusiste hace 6 meses), hacen que uno termine cansándose y poniendo algo que sea fácil de recordar.
Imagínense al pobre administrador de dominio que debe acceder a más de 10 aplicaciones por día... recordar 10 passwords diferentes que cambian continuamente es casi para un robot.

Por esto, es tarea del departamento de seguridad encontrar una solución intermedia, que cumpla con un mínimo de seguridad, pero que no haga que los usuarios se vuelvan locos y quieran linchar al administrador de seguridad (osea, a mi).
Cómo se logra esto? en parte diseñando una buena política de contraseñas, y en parte concientizando a los usuarios sobre cómo crear passwords que sean fuertes y recordables. También es muy importante destacar los riesgos de utilizar passwords débiles, y explicar cuándo un password es débil para que no se cometan equivocaciones al elegirlos.

La fortaleza de los passwords debe ser consistente en todos las aplicaciones donde se necesiten utilizar estas cadenas de caracteres. El acceso a un sistema debido a una contraseña débil, puede hacer que se comprometan otros sistemas donde se utilizaban contraseñas fuertes. Supongan que en el trabajo utilizan una contraseña con 50 caracteres, imposible de romper con sistemas automatizados, pero en su casa utilizan una contraseña de 6 caracteres, bien fácil de romper. Si desde su casa acceden a la empresa a través de VPN, SSH o el protocolo que quieran, y utilizan certificados que almacenan en su máquina para autenticarse en la empresa... perdiste! Si en la máquina de su casa utilizan el "recordar contraseña" para no tener que marcar los 50 caracteres, perdiste!

Para que se den una idea de cuán importante es un password, tengan en mente que muchísimos sistemas se hackean por día debido a una mala elección de estos. Hace un par de meses se daba a conocer el robo de información empresarial alojada en una cuenta de gmail de un empleado de twitter. Cómo sucedió esto? hackearon twitter? NO!, hackearon gmail? NO, fue debido a un password débil (o pregunta de seguridad débil).

No hay parche de software contra la mala elección de passwords. Simplemente hay que aplicar algunas reglas generales para producir buenos passwords y reglas mentales para recordarlos. Es por esto, que la elección de passwords se vuelve el punto más débil de toda organización. Por más que usemos los firewalls más potentes, los mejores antivirus, actualicemos todos los días el sistema, usemos IDS, etc, etc, etc, si no elegimos un buen passwords, ésto no servirá de nada.


Qué debo saber para armar un buen password?

A continuación les dejo algunas reglas generales sobre passwords... apliquenlas siempre que puedan!

- Utilicen un mínimo de 10 caracteres. Con los sistemas actuales, un password que tenga menos de 10 caracteres es rompible en un tiempo razonable. 10 parece un montón para poder recordarlo, pero con algunas técnicas que describiré abajo, podrán armarlos.

- Utilicen una combinación de mayúsculas, minúsculas, números y caracteres especiales (por ejemplo !$%&/#=^´Ç*+@) en su password. Como mínimo agreguen un par de caracteres especiales. De esta forma harán mucho más difícil un ataque por fuerza bruta (ni hablar de los ataques de diccionario).

- Nunca utilicen una palabra que pueda encontrarse en un diccionario, no importa de qué jerga sea el diccionario. Si la contraseña se puede encontrar en un diccionario, un sistema automatizado la puede romper. Cuando digo diccionario, me refiero a cualquier diccionario, así contengan palabras impronunciables de medicina o términos inventados en películas o series (como trustno1, pokemon, starwars, etc), si la palabra es conocida, la van a descubrir.
Este concepto se aplica también a palabras escritas en lenguaje hacker o elite, donde se reemplazan letras por números y caracteres especiales (como el caso de mi nick), ejemplos de estos reemplazos son e -> 3, a -> 4 o @, s -> 5, t -> 7, o -> 0. Existen diccionarios con las palabras escritas en este lenguaje.

- No utilicen información personal. Nada de poner el nombre, dirección, teléfono, documento o cualquier otra información personal como passwords. Cualquier que los conozca puede obtener esta información y utilizarla.

- No utilicen el nombre de usuario como password.

- No utilicen secuencias predecibles como 123456, asdfgh, qwerty, etc.

- Cambien el password cada cierto tiempo. La cantidad de tiempo dependerá de la política de cada aplicación, de la fuerte que sea el password, de los mecanismos de protección de la aplicación (por ejemplo si cada 3 intentos fallidos, el sistema bloquea el usuario) y otros parámetros, pero por regla general, tengan en cuenta que el password debe cambiarse cada cierto tiempo.

- Cuando cambien un password, cambienlo de verdad. Agregar un número al final al password anterior no sirve. Si usaban micasitaloca, luego micasitaloca1, micasitaloca2, micasitaloca3, etc, si en algún momento descubren que el password es micasitaloca, conocerán los passwords que utilizan en cada cambio...

- Utilicen contraseñas distintas en las diferentes aplicaciones que tengan acceso. Esto tal vez sea lo más difícil de cumplir, pero es muy importante, sobre todo para administradores de sistema. Si utilizan el mismo password para todo, y este password se obtiene, el atacante tendrá acceso a todo!

- No le revelen el password ni a Dios (claro que Dios, según la creencia general, lo sabría igual =D). Más allá de los comentarios chistosos, es muy, pero muy importante que no le digan el password a nadie, ni a familiares, ni a amigos, ni siquiera a sus jefes! Que una cuenta sea utilizada por más de una persona hace que sea irrastreable quién generó un problema o realizó alguna maldad, quedando siempre como culpable el dueño de la cuenta. Aunque parezca loco, sus jefes no deberían pedirles el password, si necesita por alguna razón acceder a su cuenta, deberá hacerlo por otros medios, generando el papelerío adecuado que constate el por qué necesita utilizar la cuenta.

- No utilicen "recordar contraseña" en ninguna aplicación, y mucho menos en un celular, notebook, netbook, palm, o cualquier otro dispositivo que sea fácilmente robable. Esto hace que la seguridad de una organización se valla al tacho si alguien irrumpe en uno de estos sistemas.

- No hablar con nadie sobre temas relacionados a la contraseña. Tal vez uno utiliza una frase sacada de algún lugar loco que sería muy difícil de averiguar, pero si la andan comentando, la contraseña se vuelve fácil de adivinar.


Cómo alguien puede romper un password?

Para que no les parezca todo tan loco (el hecho de necesitar 10 caracteres que contenga mayúsculas, minúsculas, números y caracteres especiales puede parecer una locura), me parece que les va a servir una buena justificación. Porque hay una justificación a todo esto, no es un simple capricho de la gente que trabaja en seguridad (en serio!, no se la agarren con nosotros! =P ).

Los ataques utilizados para romper una contraseña son los siguientes:

- Fuerza Bruta. El más conocido de todos, también es el más simple, pero el que consume mayor tiempo. Un ataque por fuerza bruta consiste en utilizar todas las combinaciones de caracteres posibles (por ej. aaaaaa, aaaaab, aaaaac, .... zzzzza, zzzzzb, etc), hasta encontrar la combinación correcta. Este ataque es costoso, sobre todo si no se sabe de antemano la cantidad de caracteres utilizados, pero con la tecnología actual se pueden realizar cientos, miles o millones de pruebas por minuto, dependiendo de si se prueba localmente o por red.

- Diccionario. Este ataque se basa en utilizar diccionarios para realizar las pruebas. En lugar de hacer ataques ciegamente con todas las combinaciones posibles, se utilizan palabras conocidas para realizar cada intento. Existen diccionarios de todo tipo, con palabras de medicina, películas, computación, mecánica, etc. Por supuesto que existen diccionarios para todos los idiomas sobre todos los rubros. Estos ataque son los más efectivos y rápidos dado que la cantidad de palabras a probar siempre es menor a tener que probar todo el espectro combinaciones de caracteres.

- Rainbow Tables. Ataque con una lógica más compleja que los anteriores. Se basa en romper los passwords a partir de los hashes almacenados en un dado sistema. Para el que no lo sepa, la mayoría de los sistemas (si son sistemas bien hechos) no almacenan los passwords de forma plana, sino que primero les aplican una función de hash y luego almacenan el hash obtenido. Por esto, si alguien obtiene la lista de hashes, primero deberá obtener la contraseña a partir del hash para poder utilizar una cuenta de usuario. Por lógica estos hashes son difíciles de romper, pero con el ataque utilizando rainbow tables, dependiendo del algoritmo de hashing y de si se utiliza salt (número aleatorio pegado al password antes de generar el hash), obtener un password de menos de 15 caracteres es cuestión de minutos.
Claro que para poder aplicar este ataque, el atacante primero deberá obtener la lista de hashes, y para eso primero debe obtener acceso al sistema con privilegios de administrador.
No hay mucho que un usuario común pueda hacer contra los rainbow tables, al menos que utilice más de 15 caracteres en sus contraseñas, pero lo nombro porque es un ataque muy utilizado últimamente.

- Ingeniería Social. Para mi, el top de los ataques. Nada de esperar horas de ejecución, irrumpir en sistemas, buscar diccionarios, siempre es más fácil encontrar a alguien que termine revelando su password por voluntad propia. Es relativamente fácil utilizar artilugios en conversaciones para que otra persona, sin darse cuenta, termine revelando su password. Por ello en la sección anterior destaqué el hecho de que no le deben revelar el password a nadie!, mucho menos si no están seguros de con quién están hablando!

- Otras técnicas dependientes de la aplicación que autentica. Existen otras técnicas que se basan en falencias de cada aplicación y no tienen tanto que ver con lo fuerte que sea el password del usuario, por lo que quedarán para otro informe =P


Cómo mierd* armo un password de más de 10 caracteres con todo tipo de caracteres distintos y acordarmelo!!!???

Llegamos a la pregunta cumbre, cómo hacemos para cumplir con todo lo que dije y no quemarnos el cerebro en el intento.
Una contraseña debe ser difícil de romper, pero a su vez, debe ser recordable. Si a cada rato tenemos que llamar al administrador para que nos resetee la contraseña, no sólo nos haremos odiar, sino que no podremos trabajar. Por ello, algunas ideas generales que pueden encontrar en la red son las siguientes:

- Utilizar una frase con varias palabras. Las frases son buenas porque son recordables. Eso sí, no utilicen una frase que dicen continuamente, utilizan en la vida diaria, o sea extremadamente conocida. Utilicen algo sacado de algún libro o algo por el estilo. Nunca hablen de la frase frente a nadie, para no dar indicios.

- Utilizar las iniciales de una frase y agregarles complejidad. Como en el punto anterior, utilizaremos una frase, pero en lugar de tener la frase entera, usamos solamente las iniciales. Por ejemplo, podemos utilizar la frase "Los de Micrsoft son unos ladrones increíbles, pero de ladrones se compone el mundo" (by d3m4s1@d0v1v0), con lo que tenemos las iniciales ldmsuliplscem. Ahora para que no quede todo en minúsculas, rompible fácilmente, cambiamos algunas letras por mayúsculas y agregamos algunos símbolos, con lo que podría quedar así: "lDM5u|_1PdlSc#m". Traten de generar variaciones que luego recuerden.

- Utilizar dos palabras concatenadas con algún caracter especial en el medio. En este caso podemos usar las palabras seguridad y linux de la siguiente manera: seguridad$@linux.

- Utilizar dos palabras entrelazadas letra por letra, agregando caracteres especiales y números. En este caso, el ejemplo anterior (palabras seguridad y linux) podría quedar: sl31gnuXrid@d.

- Escribir cualquier cosa con todos los caracteres posibles y repetir la escritura muchas veces hasta hacerlo mecánico. Esta técnica es la que yo empleo. Escriben algo totalmente sin sentido como j#dw=menta67jjBOz3D en un archivo leíble, y lo repiten varias veces a lo largo del día hasta que se les hace tan mecánico que es como si escribieran algo con total sentido.

- Sorprendanse. Como última tip, queda decir que utilicen alguna técnica que mezcle a las anteriores o utilice otra idea. Siempre que el password sea de más de 10 caracteres y utilice mayúsculas, minúsculas, números y caracteres especiales, y no sea palabra de diccionario, y les resulte fácil de recordar.


Algunos ejemplos reales de malos passwords

Si buscan en google "common passwords" o "contraseñas comunes", se pueden encontrar con varias páginas que revelan datos sobre distintos exámenes en bases de datos de diferentes lugares.
En Most common password list from 3 databases se revelan los passwords hackeados de 3 sites muy utilizados (singles.org, phpBB y MySpace). En el top de los más utilizados nos encontramos con 123456, password, qwerty, 12345, jesus, 12345678, abc123.
En The top 500 Worst Passwords of All Time nos encontramos con una simpática lista de los passwords que la gente (de habla inglesa) suele utilizar. Lo gracioso es que 1 de cada 9 personas utiliza un password de esa lista y una de cada 50 utiliza alguno de los 20 primeros!
Muchos de los passwords en estas listas se aplican a gente de habla hispana.


Conclusiones

Incentivar a los usuarios para que utilicen passwords fuertes y recordables es una tarea difícil, pero que se tiene que hacer. Hay varias reglas a cumplir y es importante que estas sean transmitidas a todos los usuarios. Siempre que piensen en un password, piensen en las técnicas de cracking y en si sería posible crackearlo con alguna de ellas.
Existe formas relativamente simples de crear buenos passwords y que sean recordables, es cuestión de aplicarlas a la vida diaria.
Coincido totalmente con Roger A. Grimes en su artículo Password-cracking contest proves theory cuando dice: "I maintain that length is a better computational protector of password confidentiality than complexity, because true complexity is not easily enforced. And if it is enforced, most users will revolt, frequently forget passwords, or write them down. So if we can’t guarantee complexity, length is a better protector."
Es decir, el mantiene que el largo es mejor protector computacional de la confidencialidad de un password que la complejidad, porque la verdadera complejidad no es realmente forzada. Y si ésta no es forzada, la mayoría de los usuarios se revelarán, frecuentemente olvidando passwords o anotándolos. Así que si no podemos garantizar complejidad, el largo es un mejor protector.
Por esto, creo que las frases largas pueden ser mejores passwords que otro totalmente complejo pero olvidable.
Sistema de passwords incrackeables!
El otro día se me ocurrió una idea genial, y como nunca había oído hablar de algo así, ya me ilusionaba con que era el primero. Pero como suele suceder, después de buscar un poco, encontré que ya se le había ocurrido a otro... (f#@!04%&|#@#).
Igualmente como no es algo muy difundido, me pareció buena idea contarlo aca, para ver si se empieza a utilizar un poco más, debido a que creo que es una excelente forma de combatir crackers y ayudar a usuarios al mismo tiempo.

Como seguramente todo administrador entenderá, es complicado enseñar a los usuarios a utilizar passwords fuertes y luego recordarlos. El usuario suele utilizar passwords simples y adivinables, ya sea con diccionarios, ataques por fuerza bruta, rainbow tables o incluso un poco de ingeniería social. El problema es que si los forzamos por software a utilizar paswords complejos (que contengan mayúsculas, minúsculas, caracteres locos, un mínimo de 10 caracteres) y encima los forzamos a cambiarlos cada un cierto período de tiempo (digamos 30 días), lo que sucede es que un password que ponen a las 8 de la mañana, el administrador debe resetearlo a las 10 (con suerte), porque el usuario lo olvidó. Por otro lado, está el clásico password pegado en un post-it en el monitor, visible por todo el mundo.

Por todo esto, la idea que se me ocurrió (y a unos cuantos antes que yo ¬ ¬) es una que permita al usuario utilizar passwords recordables y a su vez hacer que los ataques por fuerza bruta, diccinario o rainbow tables sea imposible. Debido a que todos los ataques citados requieren del factor máquina, calculando passwors y probando hasta acertar, la idea es inutilizar este sistema. Y qué sistema venimos usando para que una máquina (sin interacción humana) haga trabajos automatizados en internet? el querido CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart). Siii esas clásicas letritas torcidas dentro de una imagen, encontrables en la mayoría de los blogs y foros para evitar que spammers dejen comentarios con propagandas por todos lados.
Los CAPTCHA van cambiando en cada intento de ingreso, e imposibles de adivinar por un programa (creo que una versión lograron romper algunos crackers, pero las nuevas no), así que nos brindan la herramienta necesaria para evitar la parte automatizable de un cracker.
El otro elemento que necesitamos es una clave secreta conocida solamente por el usuario. Lo bueno es que esta clave no necesita ser extremadamente fuerte y podría usarse un largo mínimo de 5 o 6 caracteres, algo fácilmente recordable.

El mecanismo sería el siguiente. La pantalla de log-in debe contar con el clásico formulario para que el usuario ingrese su nombre de usuario y clave secreta, pero además tendrá un CAPTCHA generado por el servidor, siempre distinto para cada intento de log-in. El usuario deberá ingresar sus credenciales y además lo escrito en el CAPTCHA. El password enviado puede ser la concatenación de la clave del usuario más el CAPTCHA o bien la clave y el CAPTCHA entrelazados de alguna forma, o incluso un xor entre ambos, el sistema lo elige el programador. Una vez que los datos llegan al servidor, éste conoce la clave y también sabe lo que dice el CAPTCHA (fue el que lo generó), así que necesita hacer el mismo cálculo que el cliente para corroborar si las credenciales son correctas.

Ahora, por qué esto es irrompible de forma automatizada?
El CAPTCHA siempre varía, si usáramos un cracker, éste debería acertar al primer intento, es decir, tiene una sola chance de averiguar el password porque al próximo intento, el password será distinto. Recuerden que el password es una concatenación del secreto conocido por el usuario más el CAPTCHA, por esto, aunque el secreto del usuario no cambie, el password real cambiará en cada intento, es decir, tenemos un sistema One-Time Password (OTP).
La única alternativa que queda a un hacker es averiguar la clave del usuario de forma manual, intentando combinaciones de claves de usuario más CAPTCHA, algo que, si la clave no es adivinable por ingeniería social, es muy difícil de averiguar.

Es importante que presten atención a la diferencia entre clave de usuario y password. El password será la concatenación de la clave de usuario más el CAPTCHA y es lo que se envía al servidor, y por eso es lo que tendrá que averiguar un sistema automatizado. El sistema automatizado no lee CAPTCHAs, así que no sabe cómo armar las combinaciones para hacer las pruebas.

Si bien el método de CAPTCHA por imagen sólo es útil en logins gráficos, también existen proyectos de CAPTCHAs en ascii como asciicaptcha que nos permite utilizar CAPTCHAs en sistemas no gráficos.

Algo que se me ocurre, para agregar seguridad al transmitir las claves para que no viajen de forma plana (si no contamos con una capa segura por debajo como TLS/SSL), es utilizar algún algoritmo de hashing, que calcule el hash del password (osea clave+CAPTCHA) antes de enviarlo. Entonces lo que obtenga un sniffer va a ser siempre algo distinto. Si bien el CAPTCHA es visible por un sniffer, éste no podrá averiguar la clave porque el hash varía completamente con solo modificar algún bit.


Espero que mi explicación los haya convencido, para que si desarrollan algún sistema de autenticación (como para alguna página web), utilicen este sistema para facilitarle la vida a los usuarios (no deberán recordar complejos passwords) y agregar una seguridad extrema a las cuentas de usuario.

Para que no crean que es una idea tan loca, simplemente busquen en google "CAPTCHA authentication" (sin las comillas) y van a encontrar varios ejemplos.
Utilidad para hackear passwords de Windows y Linux
Hace un par de meses, el colo (compañero de trabajo) me comentó sobre una herramienta extremadamente útil. Cuándo me comentaba lo que hacía mi sensación era "naaa, este me está verseando", y resultó que decía la verdad =D

La citada herramienta es Kon-Boot. Y qué tiene de especial?, bueno, que nos permite acceder a sistemas Windows y Linux sin tener que conocer ninguna contraseña, y sin tener que crackear ninguna cuenta!
Y ustedes dirán, pero qué!?, pero cómo?! sin crackear nada??? Si, aunque la solución es más simple de lo que parece. Una vez iniciado el sistema con un live-cd con la imágen de kon-boot, éste modifica el kernel del sistema operativo on-the-fly a medida que se carga, para evitar los mecanismos de autenticación.
Según la página oficial, kon-boot nos permite loguearnos en Windows como usuario administrador sin ingresar ninguna contraseña. El sistema arranca como si no hubiera autenticación para usuarios, directamente nos aparece el escritorio para comenzar a trabajar.
En sistemas linux, nos permite loguearnos como root sin tipear el password correcto, simplemente hay que escribir como nombre de usuario "kon-boot" y tendremos acceso root.
La imágen de kon-boot pesa sólo 110KB! y en la página está disponible tanto para disket como para cd.

Yo lo testié en un Windows XP corriendondo en un VirtualBox y realmente funciona como dicen en la página. También testie un trixbox (distro de linux para el que no sepa) que tengo en el VirtualBox, y también funcionó perfectamente.

Las versiones de Windows testeadas son:
Windows Server 2008 Standard SP2 (v.275)
Windows Vista Business SP0
Windows Vista Ultimate SP1
Windows Vista Ultimate SP0
Windows Server 2003 Enterprise
Windows XP
Windows XP SP1
Windows XP SP2
Windows XP SP3
Windows 7

Las versiones de Linux testeadas son:
Gentoo 2.6.24-gentoo-r5
Ubuntu 2.6.24.3-debug
Debian 2.6.18-6-6861
Fedora 2.6.25.9-76.fc9.i6862

Aunque esto no quiere decir que no funcione en otras distribuciones. Como ya mencioné, lo probé con trixbox y funcionó perfectamente.