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.

5.5.PROGRAMACIÓN SEGURA 87• strcpy(), strcat(), sprintf(), vsprintf(). . . : Estas funciones no comprueban la longitudde las cadenas con las que trabajan, por lo que son una gran fuente de buffer overflows. Se hande sustituir por llamadas equivalentes que sí realicen comprobación de límites (strncpy(),strncat(). . . ) y, si no es posible, realizar dichas comprobaciones manualmente.• getenv(): Otra excelente fuente de desbordamientos de buffer; además, el uso que hagamosde la información leída puede ser peligroso, ya que recordemos que es el usuario el que generalmentepuede modificar el valor de las variables de entorno. Por ejemplo, ¿qué sucedería siejecutamos desde un programa una orden como ‘cd $HOME’, y resulta que esta variable deentorno no corresponde a un nombre de directorio sino que es de la forma ‘/;rm -rf /’? Sialgo parecido se hace desde un programa que se ejecute con privilegios en el sistema, podemosimaginarnos las consecuencias. . .• gets(), scanf(), fscanf(), getpass(), realpath(), getopt(). . . : Estas funciones no realizanlas comprobaciones adecuadas de los datos introducidos, por lo que pueden desbordaren algunos casos el buffer destino o un buffer estático interno al sistema. Es preferible el usode read() o fgets() siempre que sea posible (incluso para leer una contraseña, haciendopor supuesto que no se escriba en pantalla), y si no lo es al menos realizar manualmentecomprobaciones de longitud de los datos leídos.• gethostbyname(), gethostbyaddr(): Seguramente ver las amenazas que provienen del usode estas llamadas no es tan inmediato como ver las del resto; generalmente hablamos dedesbordamiento de buffers, de comprobaciones de límites de datos introducidos por el usuario.. . pero no nos paramos a pensar en datos que un atacante no introduce directamente desdeteclado o desde un archivo, pero cuyo valor puede forzar incluso desde sistemas que ni siquierason el nuestro. Por ejemplo, todos tendemos a asumir como ciertas las informaciones que unservidor DNS – más o menos fiables, por ejemplo alguno de nuestra propia organización – nosbrinda. Imaginemos un programa como el siguiente (se han omitido las comprobaciones deerrores habituales por cuestiones de claridad):#include #include #include #include #include int main(int argc, char **argv){struct in_addr *dir=(struct in_addr *)malloc(sizeof(struct in_addr));struct hostent *maquina=(struct hostent *)malloc(sizeof(struct \hostent));char *orden=(char *)malloc(30);dir->s_addr=inet_addr(*++argv);maquina=gethostbyaddr((char *)dir,sizeof(struct in_addr),AF_INET);sprintf(orden,"finger @%s\n",maquina->h_name);system(orden);return(0);}Este código recibe como argumento una dirección IP, obtiene su nombre vía /etc/hosts odns,y ejecuta un finger sobre dicho nombre; aparte de otros posibles problemas de seguridad(por ejemplo, ¿seríamos capaces de procesar cualquier información que devuelva el finger?,¿qué sucede con la llamada a system()?), nada extraño ha de suceder si el nombre de máquinadevuelto al programa es ‘normal’:luisa:~/tmp$ ./ejemplo 195.195.5.1[rosita]

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

Saved successfully!

Ooh no, something went wrong!