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.

72CAPÍTULO 5. PROGRAMAS SEGUROS, INSEGUROS Y NOCIVOSuna colaboración entre fabricantes, administradores y programadores ([Ins97], [Smi97]. . . ). Losprimeros han de tratar de verificar más la robustez de los programas críticos antes de distribuirlos,mientras que los administradores han de mantener al mínimo el número de ficheros setuidados osetgidados en sus sistemas y los programadores tienen que esforzarse en generar código con menospuntos de desbordamiento; en [CWP + 00] se pueden encontrar algunas líneas a tener en cuenta enla prevención de buffer overflows.5.3.2 Condiciones de carreraOtro error muy conocido en el mundo de los sistemas operativos son las condiciones de carrera,situaciones en las que dos o más procesos leen o escriben en un área compartida y el resultado finaldepende de los instantes de ejecución de cada uno ([Tan91]). Cuando una situación de este tipo seproduce y acciones que deberían ser atómicas no lo son, existe un intervalo de tiempo durante elque un atacante puede obtener privilegios, leer y escribir ficheros protegidos, y en definitiva violarlas políticas de seguridad del sistema ([Bis95]).Por ejemplo, imaginemos un programa setuidado perteneciente a root que almacene informaciónen un fichero propiedad del usuario que está ejecutando el programa; seguramente el código contendráunas líneas similares a las siguientes (no se ha incluido la comprobación básica de errorespor motivos de claridad):if(access(fichero, W_OK)==0){open();write();}En una ejecución normal, si el usuario no tiene privilegios suficientes para escribir en el fichero, lallamada a access() devolverá -1 y no se permitirá la escritura. Si esta llamada no falla open()tampoco lo hará, ya que el UID efectivo con que se está ejecutando el programa es el del root; asínos estamos asegurando que el programa escriba en el fichero si y sólo si el usuario que lo ejecutapuede hacerlo – sin privilegios adicionales por el setuid –. Pero, ¿qué sucede si el fichero cambiaentre la llamada a access() y las siguientes? El programa estará escribiendo en un archivo sobreel que no se han realizado las comprobaciones necesarias para garantizar la seguridad. Por ejemplo,imaginemos que tras la llamada a access(), y justo antes de que se ejecute open(), el usuario borrael fichero referenciado y enlaza /etc/passwd con el mismo nombre: el programa estará escribiendoinformación en el fichero de contraseñas.Este tipo de situación, en la que un programa comprueba una propiedad de un objeto y luegoejecuta determinada acción asumiendo que la propiedad se mantiene, cuando realmente no es así,se denomina TOCTTOU (Time of check to time of use). ¿Qué se puede hacer para evitarla? Elpropio sistema operativo nos da las diferentes soluciones al problema ([BD96]). Por ejemplo, podemosutilizar descriptores de fichero en lugar de nombres: en nuestro caso, deberíamos utilizar unavariante de la llamada access() que trabaje con descriptores en lugar de nombres de archivo (noes algo que exista realmente, sería necesario modificar el núcleo del operativo para conseguirlo); conesto conseguimos que aunque se modifique el nombre del fichero, el objeto al que accedemos sea elmismo durante todo el tiempo. Además, es conveniente invertir el orden de las llamadas (invocarprimero a open() y después a nuestra variante de access()); de esta forma, el código anteriorquedaría como sigue:if((fd=open(fichero, O_WRONLY))==NULL){if (access2(fileno(fp),W_OK)==0){write();}}No obstante, existen llamadas que utilizan nombres de fichero y no tienen un equivalente que utilicedescriptores; para no tener que reprogramar todo el núcleo de Unix, existe una segunda solución que

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

Saved successfully!

Ooh no, something went wrong!