Revista Informática

Permisos especiales en Linux: Sticky bit, SUID y SGID

Publicado el 11 enero 2017 por Drassill
Hoy quiero traeros un concepto que si bien no es especialmente "desconocido" hay muchas personas que lo pasan por alto debido a su poco uso. En su día hablé sobre el concepto de los permisos de los ficheros en Linux con bastante profundidad; pero hoy quiero traeros un concepto derivado de éste que va un pequeño paso más allá: Los permisos especiales.
Permisos_especiales_portada
Estos permisos están diseñados tanto para garantizar un cierta "flexibilidad" a la hora de ejecutar algunos binarios cómo para evitar posibles accidentes por parte de algunos usuarios... Permisos especiales que, si bien son pocos, conviene conocer adecuadamente. En concreto habrían 3 tipos de permisos especiales.
Sticky bit
Por un lado tendríamos el sticky bit; que se trata de un permiso especial que puede ser asignado tanto a ficheros como directorios. Este permiso puede ser muy útil en ficheros de cierta relevancia tales como los ficheros de log o ficheros importantes, ya que lo que permite es leer y escribir en el fichero y/o directorio en cuestión, pero no se podría ni renombrar ni borrar por nadie a excepción de dos usuarios: El creador de éste y root; lo que hace que a nivel de seguridad tengamos una cierta tranquilidad, ya que los usuarios pueden leer y escribir en el fichero con libertad pero jamás podrán alterar su nombre ni borrarlo. Este permiso se puede agregar de dos formas; a nivel directo o a nivel octal.
La forma directa sería:
Para añadir el permiso sticky bit:
chmod +t fichero
Para quitar el permiso sticky bit:
chmod -t fichero
A nivel octal lo veremos mejor más adelante con el fin de englobar todos los permisos especiales.
SUID
Por otro lado tendríamos el SUID o "Set Owner ID up on execution", cuya función sería que el usuario que ejecute el archivo, tendría exactamente los mismos permisos que el dueño de éste. Esto puede parecer algo simple pero no lo es; si por ejemplo tuviésemos un archivo con permisos de ejecución (para todos) y tuviese dicho SUID, cualquiera que lo ejecute lo estaría ejecutando como si fuese el dueño del script, lo que es muy útil y muy peligroso al mismo tiempo. Imaginemos que el script perteneciese a root y tuviese permisos de ejecución para todos y el SUID activado; además el contenido de dicho script , escrito en C y llamado test.c, sería algo como lo siguiente:
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. main(){
  4.   printf("UID: %d, EUID: %d\n",getuid(),geteuid());
  5.   system("cat /etc/shadow");
  6. }

Obviamente el programa estaría compilado; es decir:
gcc test.c -otest
Al ejecutar lo que pasaría sería que mostraría los valores UID y EUID e intentaría ejecutar el comando "cat /etc/shadow". UID sería el User ID del usuario que generalmente sería valor a partir de 1000 (1000, 1001, 1002...) y el EUID sería el Effective User ID, valor que indica el User ID que se está usando para realizar la tarea en cuestión. Al no tener el permiso especial activo, ambos valores serían iguales y el comando cat diría que no tenemos permisos para ver el contenido del fichero. Ahora bien, vamos a activar el SUID:
chmod u+s test
Si lo ejecutásemos veríamos por un lado que el valor EUID ha cambiado a 0 (ya que el UID de root es ese) y que permite ejecutar el comando cat sobre el fichero shadow, lo cual es peligroso.
Esto implica que si bien este permiso es útil, hay que ser extremadamente peligroso con él ya que se puede utilizar como recurso para escalar privilegios. La forma de deshabilitar este permiso sería:
chmod u-s test
SGID
Es extremadamente parecido al SUID con la diferencia de que en este caso el SGID o "Set Group ID on execution" tomaría los permisos del grupo, no del usuario en sí. Aún así, si el grupo fuese root o uno grupo con privilegios de administrador, este permiso podría ser usado en favor de la escalada de privilegios.
Para añadir el SGID habría que escribir:
chmod g+s fichero
Mientras que para quitarlo sería:
chmod g-s fichero
Cambiando los permisos especiales a nivel Octal
En mi opinión, el conocer como cambiar los permisos especiales a nivel octal es mucho más útil que a nivel "normal" ya que ofrece muchas más potencia y flexibilidad el hacerlo de esta forma; no es obligatorio hacerlo así; es más es perfectamente viable hacer el cambio de permisos de las formas que he comentado, pero en mi opinión es muy útil conocer la forma de cambiar los permisos en octal.
Lo primero que habría que saber sería que cuando hacemos una asignación de permisos "normales" a nivel octal, lo hacemos mediante el comando chmod más tres dígitos que pueden oscilar entre 0 y 7; pues bien, el octal que asignaría los permisos especiales iría antes de dichos tres dígitos, haciendo que el comando chmod se tenga que hacer mediante el comando chmod más 4 dígitos. Por ejemplo:

chmod 1755 fichero
El 1 sería el octal que haría referencia a los permisos especiales y sería dicho octal el que habría que tener en cuenta a la hora de asignar los permisos especiales. El valor octal sería el mismo que el asignado para los permisos normales, es decir entre 0 y 7. He aquí una tabla muy explicita que explica exactamente qué significa cada número:
chmod_especiales
Gracias a esta tabla, podemos asignar los permisos especiales a nuestro antojo y poder asignar uno o varios permisos especiales con total libertad; pudiendo hacer cosas como éstas:
Otorgar sticky bit junto con los permisos 644:
chmod1644 fichero
Activar el SUID y el SGID en el fichero junto con los permisos 755:
chmod6755 fichero
Darle el sticky bit y el SUID a un fichero más los permisos 600:
chmod5600 fichero
Como veis, los permisos especiales son muy útiles y al mismo tiempo peligrosos según el caso, pero es muy conveniente tenerlos presentes, ya sea para evitar escaladas de privilegios accidentales o para prevenir el borrado o renombrado accidental de un fichero.
Espero que os haya sido útil.
Saludos.

Volver a la Portada de Logo Paperblog