En un sistema Unix habitual cada usuario posee un nombre de entrada al sistema
o login y una clave o password; ambos datos se almacenan
generalmente en el fichero /etc/passwd. Este archivo contiene una
línea por usuario (aunque hay entradas que no corresponden a usuarios
reales, como veremos a continuación) donde se indica la información
necesaria para que los usuarios puedan conectar al sistema y trabajar en él,
separando los diferentes campos mediante `:'. Por ejemplo, podemos
encontrar entradas parecidas a la siguiente:
toni:LEgPN8jqSCHCg:1000:100:Antonio Villalon,,,:/export/home/toni:/bin/sh
En primer lugar aparecen el login del usuario y su clave cifrada; a
continuación tenemos dos números que serán el identificador de usuario y
el de grupo respectivamente. El quinto campo, denominado GECOS es
simplemente información administrativa sobre la identidad real del usuario,
como su nombre, teléfono o número de despacho. Finalmente, los dos últimos
campos corresponden al directorio del usuario (su $HOME inicial) y al
shell que le ha sido asignado.
Al contrario de lo que mucha gente cree, Unix no es capaz de distinguir a sus
usuarios por su nombre de entrada al sistema. Para el sistema operativo lo que
realmente distingue a una persona de otra (o al menos a un usuario de otro) es
el UID del usuario en cuestión; el login es algo que se
utiliza principalmente para comodidad de las personas (obviamente es más
fácil acordarse de un nombre de entrada como toni que de un UID como
2643, sobre todo si se tienen cuentas en varias máquinas, cada una con un UID
diferente). Por tanto, si en /etc/passwd existen
dos entradas con un mismo UID, para Unix se tratará del mismo usuario, aunque
tengan un login y un password diferente: así, si dos usuarios
tienen asignado el UID 0, ambos tendrán privilegios de superusuario, sin
importar el login que utilicen. Esto es especialmente aprovechado por
atacantes que han
conseguido privilegios de administrador en una máquina: pueden añadir una
línea a /etc/passwd mezclada entre todas las demás, con un nombre
de usuario normal pero con el UID 0; así garantizan su entrada al sistema
como administradores en caso de ser descubiertos, por ejemplo para borrar
huellas. Como a simple vista puede resultar difícil localizar la
línea insertada, especialmente en sistemas con un gran número de
usuarios, para detectar las cuentas con privilegios en la máquina podemos
utilizar la siguiente orden:
anita:~# awk -F: '$3==0 {print $1}' /etc/passwd
root
anita:~#
En el fichero de claves van a existir entradas que no corresponden a usuarios
reales, sino que son utilizadas por ciertos programas o se trata de cuentas
mantenidas por motivos de compatibilidad con otros sistemas; típicos
ejemplos de este tipo de entradas son lp, uucp o postmaster.
Estas cuentas han de estar bloqueadas en la mayoría de casos, para evitar
que alguien pueda utilizarlas para acceder a nuestro sistema: sólo han de
ser accesibles para el root mediante la orden su. Aunque en su
mayoría cumplen esta condición, en algunos sistemas estas cuentas tienen
claves por defecto o, peor, no tienen claves, lo que las convierte en una
puerta completamente abierta a los intrusos; es conveniente que, una vez
instalado el sistema operativo, y antes de poner a trabajar la máquina,
comprobemos que están bloqueadas, o en su defecto que tienen claves no
triviales. Algunos ejemplos de cuentas sobre los que hay que prestar una
especial atención son9.4 root,
guest, lp, demos, 4DGifts, tour, uucp,
nuucp, games o postmaster; es muy recomendable
consultar los manuales de cada sistema concreto, y chequear periódicamente
la existencia de cuentas sin clave o cuentas que deberían permanecer
bloqueadas y no lo están.
Para cifrar las claves de acceso de sus usuarios, el sistema operativo
Unix emplea un criptosistema irreversible que utiliza la función estándar
de C crypt(3), basada en el algoritmo DES. Para una
descripción exhaustiva del funcionamiento de crypt(3) se puede consultar
[MT79], [FK90] o [GS96]. Esta función
toma como clave los ocho primeros caracteres de la contraseña elegida por el
usuario (si la longitud de ésta es menor, se completa con ceros) para cifrar
un bloque de
texto en claro de 64 bits puestos a cero; para evitar que dos passwords
iguales resulten en un mismo texto cifrado, se realiza una permutación durante
el proceso de cifrado elegida de forma automática y aleatoria para cada
usuario, basada en un campo formado por un número de 12 bits (con lo que
conseguimos 4096 permutaciones diferentes) llamado salt.
El cifrado resultante se vuelve a cifrar utilizando la contraseña del
usuario de nuevo como clave, y permutando con el mismo salt,
repitiéndose el
proceso 25 veces. El bloque cifrado final, de 64 bits, se concatena con dos
bits cero, obteniendo 66 bits que se hacen representables en 11 caracteres de 6
bits cada uno y que, junto con el salt, pasan a constituir el campo password del fichero de contraseñas, usualmente /etc/passwd. Así,
los dos primeros caracteres de este campo estarán constituidos por el salt y los 11 restantes por la contraseña cifrada:
toni:LEgPN8jqSCHCg:1000:100:Antonio Villalon,,,:/export/home/toni:/bin/sh
SALT:
PASSWORD CIFRADO:
Como hemos dicho antes, este criptosistema es irreversible. Entonces, >cómo
puede un usuario conectarse a una máquina Unix? El proceso es sencillo: el
usuario
introduce su contraseña, que se utiliza como clave para cifrar 64 bits a 0
basándose en el salt, leído en /etc/passwd, de dicho usuario.
Si tras aplicar el algoritmo de
cifrado el resultado se corresponde con lo almacenado en los últimos 11
caracteres del campo password del fichero de contraseñas, la clave del
usuario se considera válida y se permite el acceso. En caso contrario se le
deniega y se almacena en un fichero el intento de conexión fallido.
© 2002 Antonio Villalón Huerta