13.07.2015 Views

SEGURIDAD EN UNIX Y REDES

SEGURIDAD EN UNIX Y REDES

SEGURIDAD EN UNIX Y REDES

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

88No one logged on.luisa:~/tmp$CAPÍTULO 5. PROGRAMAS SEGUROS, INSEGUROS Y NOCIVOSPero, ¿qué pasaría si en lugar de devolver un nombre ‘normal’ (como ‘rosita’) se devuelveun nombre algo más elaborado, como ‘rosita;ls’? Podemos verlo:luisa:~/tmp$ ./ejemplo 195.195.5.1[rosita;ls]No one logged on.ejemplo ejemplo.cluisa:~/tmp$Exactamente: se ha ejecutado la orden ‘finger @rosita;ls’ (esto es, un ‘finger’ a lamáquina seguido de un ‘ls’). Podemos imaginar los efectos que tendría el uso de esteprograma si sustituimos el inocente ‘ls’ por un ‘rm -rf $HOME’. Un atacante que consigacontrolar un servidor dns (algo no muy complicado) podría inyectarnos datos maliciosos ennuestra máquina sin ningún problema. Para evitar esta situación debemos hacer una doblebúsqueda inversa y además no hacer ninguna suposición sobre la corrección o el formato delos datos recibidos; en nuestro código debemos insertar las comprobaciones necesarias paraasegurarnos de que la información que recibimos no nos va a causar problemas.• syslog(): Hemos de tener la precaución de utilizar una versión de esta función de libreríaque compruebe la longitud de sus argumentos; si no lo hacemos y esa longitud sobrepasa uncierto límite (generalmente, 1024 bytes) podemos causar un desbordamiento en los buffers denuestro sistema de log, dejándolo inutilizable.• realloc(): Ningún programa – privilegiado o no – que maneje datos sensibles (por ejemplo,contraseñas, correo electrónico. . . y especialmente aplicaciones criptográficas) debe utilizar estallamada; realloc() se suele utilizar para aumentar dinámicamente la cantidad de memoriareservada para un puntero. Lo habitual es que la nueva zona de memoria sea contigua a la queya estaba reservada, pero si esto no es posible realloc() copia la zona antigua a una nuevaubicación donde pueda añadirle el espacio especificado. ¿Cuál es el problema? La zona dememoria antigua se libera (perdemos el puntero a ella) pero no se pone a cero, con lo que suscontenidos permanecen inalterados hasta que un nuevo proceso reserva esa zona; accediendoa bajo nivel a la memoria (por ejemplo, leyendo /proc/kcore o /dev/kmem) sería posible paraun atacante tener acceso a esa información.Realmente, malloc() tampoco pone a cero la memoria reservada, por lo que a primera vistapuede parecer que cualquier proceso de usuario (no un acceso a bajo nivel, sino un simplemalloc() en un programa) podría permitir la lectura del antiguo contenido de la zona dememoria reservada. Esto es falso si se trata de nueva memoria que el núcleo reserva para elproceso invocador: en ese caso, la memoria es limpiada por el propio kernel del operativo,que invoca a kmalloc() (en el caso de Linux, en otros Unices el nombre puede variar aunquela idea sea la misma) para hacer la reserva. Lo que sí es posible es que si liberamos una zonade memoria (por ejemplo con free()) y a continuación la volvemos a reservar, en el mismoproceso, podamos acceder a su contenido: esa zona no es ‘nueva’ (es decir, el núcleo no laha reservado de nuevo), sino que ya pertenecía al proceso. De cualquier forma, si vamos aliberar una zona en la que está almacenada información sensible, lo mejor en cualquier casoes ponerla a cero manualmente, por ejemplo mediante bzero() o memset().• open(): El sistema de ficheros puede modificarse durante la ejecución de un programa deformas que en ocasiones ni siquiera imaginamos; por ejemplo, en Unix se ha de evitar escribirsiguiendo enlaces de archivos inesperados (un archivo que cambia entre una llamada a lstat()para comprobar si existe y una llamada a open() para abrirlo en caso positivo, como hemosvisto antes). No obstante, no hay ninguna forma de realizar esta operación atómicamente sinllegar a mecanismos de entrada/salida de muy bajo nivel; Peter Gutmann propone el siguientecódigo para asegurarnos de que estamos realizando un open() sobre el archivo que realmentequeremos abrir, y no sobre otro que un atacante nos ha puesto en su lugar:

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

Saved successfully!

Ooh no, something went wrong!