13.07.2015 Views

SEGURIDAD EN UNIX Y REDES

SEGURIDAD EN UNIX Y REDES

SEGURIDAD EN UNIX Y REDES

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

5.5.PROGRAMACIÓN SEGURA 83El principal problema de la programación en Unix lo constituyen los programas setuidados; siun programa sin este bit activo tiene un fallo, lo normal es que ese fallo solamente afecte a quienlo ejecuta. Al tratarse de un error de programación, algo no intencionado, su primera consecuenciaserá el mal funcionamiento de ese programa. Este esquema cambia radicalmente cuando el programaestá setuidado: en este caso, el error puede comprometer tanto a quien lo ejecuta como a supropietario, y como ese propietario es por norma general el root automáticamente se comprometea todo el sistema. Para la codificación segura de este tipo de programas, [Bis86] proporciona unaslíneas básicas:• Máximas restricciones a la hora de elegir el UID y el GID.Una medida de seguridad básica que todo administrador de sistemas Unix ha de seguir esrealizar todas las tareas con el mínimo privilegio que estas requieran ([Sim90]); así, a nadiese le ocurre (o se le debería ocurrir) conectar a IRC o aprender a manejar una aplicacióngenérica bajo la identidad de root. Esto es directamente aplicable a la hora de programar:cuando se crea un programa setuidado (o setgidado) se le ha de asignar tanto el UID como elGID menos peligroso para el sistema. Por ejemplo, si un programa servidor se limita a mostrarun mensaje en pantalla y además escucha en un puerto por encima de 1024, no necesita paranada estar setuidado a nombre de root (realmente, es poco probable que ni siquiera necesiteestar setuidado); si pensamos en un posible error en dicho programa que permita a un atacanteobtener un shell vemos claramente que cuanto menos privilegio tenga el proceso, menos malasserán las posibles consecuencias de tal error.• Reset de los UIDs y GIDs efectivos antes de llamar a exec().Uno de los grandes problemas de los programas setuidados es la ejecución de otros programasde manera inesperada; por ejemplo, si el usuario introduce ciertos datos desde teclado, datosque se han de pasar como argumento a otra aplicación, nada nos asegura a priori que esosdatos sean correctos o coherentes. Por tanto, parece obvio resetear el UID y el GID efectivosantes de invocar a exec(), de forma que cualquier ejecución inesperada se realice con elmínimo privilegio necesario; esto también es aplicable a funciones que indirectamente realicenel exec(), como system() o popen().• Es necesario cerrar todos los descriptores de fichero, excepto los estrictamente necesarios, antesde llamar a exec().Los descriptores de ficheros son un parámetro que los procesos Unix heredan de sus padres; deesta forma, si un programa setuidado está leyendo un archivo, cualquier proceso hijo tendráacceso a ese archivo a no ser que explícitamente se cierre su descriptor antes de ejecutar elexec().La forma más fácil de prevenir este problema es activando un flag que indique al sistemaque ha de cerrar cierto descriptor cada vez que se invoque a exec(); esto se consigue mediantelas llamadas fcntl() e ioctl().• Hay que asegurarse de que chroot() realmente restringe.Los enlaces duros entre directorios son algo que el núcleo de muchos sistemas Unix no permitendebido a que genera bucles en el sistema de ficheros, algo que crea problemas a determinadasaplicaciones; por ejemplo, Linux no permite crear estos enlaces, pero Solaris o Minix sí. Enestos últimos, en los clones de Unix que permiten hard links entre directorios, la llamadachroot() puede perder su funcionalidad: estos enlaces pueden seguirse aunque no se limitenal entorno con el directorio raíz restringido. Es necesario asegurarse de que no hay directoriosenlazados a ninguno de los contenidos en el entorno chroot() (podemos verlo con la opción‘-l’ de la orden ls, que muestra el número de enlaces de cada archivo).• Comprobaciones del entorno en que se ejecutará el programa.En Unix todo proceso hereda una serie de variables de sus progenitores, como el umask, losdescriptores de ficheros, o ciertas variables de entorno ($PATH, $IFS. . . ); para una ejecuciónsegura, es necesario controlar todos y cada uno de estos elementos que afectan al entorno de

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!