Dentro de este apartado vamos a comentar brevemente la función de algunos servicios de Unix y sus potenciales problemas de seguridad. Los aquí expuestos son servicios que habitualmente han de estar cerrados, por lo que no implican excesivos problemas de seguridad conocidos. Así, no vamos a entrar en muchos detalles con ellos; en puntos siguientes hablaremos con más extensión de otros servicios que suelen estar ofrecidos en todas las máquinas, como ftp, telnet o SMTP, y que en su mayoría presentan mayores problemas de seguridad.
systat
El servicio systat se asocia al puerto 11 de una máquina Unix, de forma que al recibir una petición mediante TCP el demonio inetd ofrece una imagen de la tabla de procesos del sistema, por ejemplo ejecutando una orden como ps -auwwx en Linux o ps -ef en Solaris; en algunos Unices se ofrece la salida de órdenes como who o w en lugar de la tabla de procesos: es fácil configurar lo que cada administrador desee mostrar simplemente modificando la línea correspondiente de /etc/inetd.conf:
anita:~# grep systat /etc/inetd.conf
systat stream tcp nowait root /usr/bin/ps ps -ef
anita:~#
Bien se ofrezca la tabla de procesos o bien otro tipo de información sobre el sistema, este servicio es habitual encontarlo deshabilitado, ya que cualquier dato sobre nuestro sistema (especialmente procesos, nombres de usuario, máquinas desde las que conectan...) puede ser aprovechado por un pirata para atacar el equipo. Si por motivos de comodidad a la hora de administrar varios hosts dentro de una red local necesitamos tener abierto systat, debemos restringir las direcciones desde las que se puede acceder al servicio mediante TCP Wrappers.
daytime
El servicio daytime, asociado al puerto 13, tanto TCP como UDP, es un servicio interno de inetd (esto es, no hay un programa externo que lo sirva, el propio inetd se encarga de ello); al recibir una conexón a este puerto, el sistema mostrará la fecha y la hora, en un formato muy similar al resultado de la orden date:
anita:~# telnet rosita daytime
Trying 192.168.0.1...
Connected to rosita.
Escape character is '^]'.
Thu Apr 20 05:02:33 2000
Connection closed by foreign host.
anita:~#
Aunque a primera vista este servicio no represente un peligro para la integridad de nuestro sistema, siempre hemos de recordar una norma de seguridad fundamental: sólo hay que ofrecer los servicios estrictamente necesarios para el correcto funcionamiento de nuestras máquinas. Como daytime no es un servicio básico, suele ser recomendable cerrarlo; además, la información que proporciona, aunque escasa, puede ser suficiente para un atacante: le estamos indicando el estado del reloj de nuestro sistema, lo que por ejemplo le da una idea de la ubicación geográfica del equipo.
Un servicio parecido en muchos aspectos a daytime es time (puerto 37, TCP y UDP); también indica la fecha y hora del equipo, pero esta vez en un formato que no es inteligible para las personas:
anita:~# telnet rosita time
Trying 192.168.0.1...
Connected to rosita.
Escape character is '^]'.
['^Connection closed by foreign host.
anita:~#
Este servicio suele ser más útil que el anterior: aunque una persona no entienda la información mostrada por time, sí que lo hace una máquina Unix. De esta forma, se utiliza time en un servidor para que las estaciones cliente puedan sincronizar sus relojes con él con órdenes como netdate o rdate:
luisa:~# date
Thu Apr 20 02:19:15 CEST 2000
luisa:~# rdate rosita
[rosita] Thu Apr 20 05:10:49 2000
luisa:~# date
Thu Apr 20 02:20:02 CEST 2000
luisa:~# rdate -s rosita
luisa:~# date
Thu Apr 20 05:11:59 2000
luisa:~#
Los problemas de time son en principio los mismos que los de daytime; aunque también es recomendable mantener este servicio cerrado, es más fácil imaginar situaciones en las que un administrador desee ofrecer time en varias máquinas que imaginar la necesidad de ofrecer daytime.
netstat
De la misma forma que systat ofrecía información sobre el estado de nuestro sistema, netstat la ofrece sobre el estado de nuestra red. Este servicio, asociado al puerto 15 con protocolo TCP, ejecuta una orden como netstat (con argumentos que dependen del clon de Unix utilizado) para mostar principalmente las conexiones activas en la máquina; por ejemplo, si en Linux invocamos a netstat desde /etc/inetd.conf con la opción `-A inet', al recibir una conexión se mostrará algo parecido a lo siguiente:
anita:~# telnet rosita netstat
Trying 192.168.0.1...
Connected to rosita.
Escape character is '^]'.
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 rosita:netstat anita:4990 ESTABLISHED
Connection closed by foreign host.
anita:~#
Como sucedía con systat, es recomendable deshabilitar este servicio comentando la línea correspondiente de /etc/inetd.conf, o en todo caso restringir el acceso al mismo a máquinas de nuestra red local, mediante TCP Wrappers. La información sobre el estado del sistema de red - o al menos de parte del mismo - puede ser muy útil para un atacante, ya que por ejemplo le está mostrando nombres de hosts y además le permite hacerse una idea del tráfico que soporta la máquina, de los servicios que ofrece, de los hábitos de conexión de los usuarios...
chargen
chargen (puerto 19, TCP y UDP) es un generador de caracteres servido internamente por inetd, que se utiliza sobre todo para comprobar el estado de las conexiones en la red; cuando alguien accede a este servicio simplemente ve en su terminal una secuencia de caracteres ASCII que se repite indefinidamente.
Los posibles problemas de seguridad relacionados con chargen suelen ser negaciones de servicio, tanto para la parte cliente como para la servidora. Sin duda el ejemplo más famoso de utilización de chargen es una de las anécdotas del experto en seguridad Tsutomu Shimomura (el principal contribuidor en la captura de Kevin Mitnick, el pirata más famoso de los noventa): cuando conectaba a un servidor de ftp anónimo, Shimomura se dió cuenta de que la máquina lanzaba un finger contra el cliente que realizaba la conexión. Esto no le gustó, y decidió comprobar si ese sistema utilizaba el finger habitual; para ello modificó el fichero /etc/inetd.conf de su sistema de forma que las peticiones finger se redireccionaran al generador de caracteres chargen. Conectó al servidor de nuevo, y al hacer éste otro finger, la máquina de Shimomura se dedicó a enviar megas y megas de caracteres (chargen no finaliza hasta que el cliente corta la conexión); en unas pocas horas el sistema remoto quedó inoperativo, y a la mañana siguiente ese finger automático había sido eliminado de la configuración del servidor. Ese servidor no habría sufrido una caída si hubiera utilizado safe_finger, un programa de Wietse Venema que se distribuye junto a TCP Wrappers y que limita la potencial cantidad de información que finger puede recibir.
tftp
tftp (Trivial File Transfer Protocol) es un protocolo de transferencia de ficheros asociado al puerto 69 y basado en UDP que no proporciona ninguna seguridad. Por tanto en la mayoría de sistemas es obligatorio que este servicio esté desactivado; su uso principal es el arranque de estaciones diskless o de routers a través de la red, ya que la simpleza del protocolo permite implementarlo en un chip, y sólo en ese caso nos veremos obligados a ofrecer el servicio. Si es este el caso, los ficheros que deseemos que sean públicos se han de situar en un determinado directorio (dependiendo del clon de Unix, /tftpboot/, /etc/tftpboot/, /usr/local/boot/...) o utilizar otros nombres de directorio como argumentos del demonio en /etc/inetd.conf, algo no recomendable. Por ejemplo, si en /tftpboot/ guardamos una copia de la imagen del kernel, los clientes podrán acceder a ella mediante la orden tftp:
luisa:~# tftp rosita
tftp> get vmlinuz
Received 531845 bytes in 3.4 seconds
tftp> quit
luisa:~#
Podemos ver que en ningún momento se solicita un nombre de usuario o una clave, lo que nos da una idea de los graves problemas de seguridad que el ofrecer este servicio puede implicarnos. Hasta hace unos años, era normal que los fabricantes de sistemas Unix vendieran sus productos con tftp abierto y sin configurar, con lo que un pirata lo tenía muy fácil para conseguir cualquier fichero de contraseñas:
luisa:~# tftp victima
tftp> get /etc/passwd /tmp/salida
Received 1845 bytes in 0.6 seconds
tftp> quit
luisa:~#
finger
Típicamente el servicio finger (puerto 79, TCP) ha sido una de las principales fuentes de problemas de Unix. Este protocolo proporciona información - demasiado detallada - de los usuarios de una máquina, estén o no conectados en el momento de acceder al servicio; para hacerlo, se utiliza la aplicación finger desde un cliente, dándole como argumento un nombre de máquina precedido del símbolo `@' y, opcionalmente, de un nombre de usuario (finger sobre el sistema local no utiliza el servicio de red, por lo que no lo vamos a comentar aquí). En el primer caso, finger nos dará datos generales de los usuarios conectados en ese momento a la máquina, y en el segundo nos informará con más detalle del usuario especificado como parámetro, esté o no conectado:
anita:~# finger @rosita
[rosita]
Login Name Tty Idle Login Time Office Office Phone
toni Toni at ROSITA */0 28 Apr 20 04:43 (anita)
root El Spiritu Santo 1 12 Apr 11 02:10
anita:~# finger toni@rosita
[rosita]
Login: toni Name: Toni at ROSITA
Directory: /home/toni Shell: /bin/bash
On since Thu Apr 20 04:43 (CEST) on pts/0 from anita
30 minutes 28 seconds idle
(messages off)
No mail.
No Plan.
anita:~#
Como podemos ver, finger está proporcionando mucha información que podría ser de utilidad para un atacante: nombres de usuario, hábitos de conexión, cuentas inactivas...incluso algunas organizaciones rellenan exhaustivamente el campo gecos del fichero de contraseñas, con datos como números de habitación de los usuarios o incluso su teléfono. Está claro que esto es fácilmente aprovechable por un pirata para practicar ingeniería social contra nuestros usuarios - o contra el propio administrador -. Es básico para la integridad de nuestras máquinas deshabilitar este servicio, restringir su acceso a unos cuantos equipos de la red local mediante TCP Wrappers o utilizar versiones del demonio fingerd como ph (Phone Book), que permiten especificar la información que se muestra al acceder al servicio desde cada máquina.
POP
El servicio POP (Post Office Protocol, puertos 109 y 110 en TCP) se utiliza para que los usuarios puedan acceder a su correo sin necesidad de montar sistemas de ficheros compartidos mediante NFS: los clientes utilizan SMTP para enviar correo y POP para recogerlo del servidor, de forma que el procesamiento se realice en la máquina del usuario. Se trata de un servicio que podríamos considerar peligroso, por lo que - como el resto, pero este especialmente - debemos deshabilitarlo a no ser que sea estrictamente necesario ofrecerlo; en ese caso debemos restringir al máximo los lugares desde los que se puede acceder, mediante TCP Wrappers.
En algunos sistemas se utiliza POP simplemente para evitar otorgar cuentas completas a los usuarios: si sólo van a utilizar la máquina para leer su correo, >por qué ofrecerles un shell `completo', con acceso a todo el sistema? Realmente esto es cierto (sería un error permitir ejecutar ciertas órdenes a aquellos que sólo utilizarán el equipo para gestionar su correo), pero en muchas ocasiones esta solución no es del todo conveniente: aparte de los peligros que implica un servicio adicional, que de otra forma no utilizaríamos - en algunos demonios de POP han surgido bugs que incluso otorgaban un privilegio de root remoto sin necesidad de ninguna clave -, estamos generando un tránsito peligroso de contraseñas a través de la red. POP ofrece tres modelos distintos de autenticación: uno basado en Kerberos, apenas utilizado, otro basado en un protocolo desafío-respuesta (APOP, que tampoco se suele utilizar), y otro basado en un simple nombre de usuario con su password correspondiente. Este último, el más usado en todo tipo de entornos, es un excelente objetivo para un pirata con un sniffer: los usuarios suelen configurar sus clientes para que chequeen el buzón de correo cada pocos minutos, con lo que a intervalos muy cortos envían su clave a un puerto conocido de una máquina conocida; al realizar toda esta comunicación en texto claro, un atacante no tiene más que interceptar la sesión POP para averiguar nombres de usuario y claves (aparte de poder leer el correo que baja del servidor al cliente). Si lo que deseamos es que nuestros usuarios no disfruten de una cuenta completa simplemente para gestionar su correo, podemos sustituir su shell en /etc/passwd por el nombre de dicho lector:
ircd:x:1001:100:Gestion IRC,,,:/home/ircd:/usr/bin/pine
En este caso hemos de tomar una precaución adicional: la mayoría de programas de correo (elm, pine...) permiten escapes al shell, procedimientos que tarde o temprano ejecutan con éxito un intérprete de órdenes; por ejemplo, con elm no tenemos más que iniciar vi para escribir un mensaje y en el editor ejecutar :!/bin/sh para ejecutar este intérprete. Para evitar estos escapes o bien podemos modificar el código del gestor de correo - algo no muy habitual - o utilizar ya versiones modificadas disponibles a través de Internet.
auth
Se llama socket a la combinación de una dirección de máquina y un puerto; esta entidad identifica un proceso único en la red ([CZ95]). Un par de sockets, uno en la máquina receptora y otro en la emisora definen una conexión en protocolos como TCP; esta conexión también será única en la red en un instante dado. Como vemos, no entra en juego ningún nombre de usuario: en TCP/IP se establecen canales de comunicación entre máquinas, no entre personas; no obstante, en muchas ocasiones nos puede interesar conocer el nombre de usuario bajo el que cierta conexión se inicia. Por ejemplo, de esta forma podríamos ofrecer o denegar un servicio en función del usuario que lo solicita, aparte de la máquina desde donde viene la petición.
El protocolo auth (puerto 113, TCP) viene a solucionar este problema con un esquema muy simple: cuando un servidor necesita determinar el usuario que ha iniciado una conexión contacta con el demonio identd y le envía los datos necesarios para distinguir dicha conexión (los componentes de los dos sockets que intervienen) de las demás. De esta forma, el demonio identifica al usuario en cuestión y devuelve al servidor información sobre dicho usuario, generalmente su login. Por ejemplo, si utilizamos TCP Wrappers - un programa servidor que utiliza este mecanismo para determinar nombres de usuario siempre que sea posible -, se registará el login del usuario remoto que solicita un servicio en nuestra máquina si el sistema remoto tiene habilitado auth:
luisa:~# tail -2 ~adm/syslog
Apr 24 04:16:19 luisa wu.ftpd[1306]: connect from rosita
Apr 24 04:16:21 luisa ftpd[1306]: ANONYMOUS FTP LOGIN FROM \
rosita [192.168.0.1], toni@
luisa:~#
No obstante, si el sistema desde el que esa persona conecta no tiene habilitado dicho servicio, el nombre de usuario no se va a poder conseguir:
luisa:~# tail -2 ~adm/syslog
Apr 24 04:19:37 luisa wu.ftpd[1331]: connect from root@anita
Apr 24 04:19:39 luisa ftpd[1331]: ANONYMOUS FTP LOGIN FROM \
root @ anita [192.168.0.3], toni@
luisa:~#
El servicio auth no se debe utilizar nunca con propósitos de autenticación robusta, ya que dependemos no de nuestros sistemas, sino de la honestidad de la máquina remota; un atacante con el suficiente nivel de privilegio en esta puede enviarnos cualquier nombre de usuario que desee. Incluso en ciertas situaciones, si ident no está habilitado ni siquiera hacen falta privilegios para devolver un nombre falso: cualquier usuario puede hacerlo. En cambio, sí que es útil para detectar pequeñas violaciones de seguridad, por lo que quizás interese habilitar el servicio en nuestras máquinas (aunque limitemos su uso mediante TCP Wrappers.
NNTP
El servicio NNTP (Network News Transfer Protocol, puerto 119 TCP) se utiliza para intercambiar mensajes de grupos de noticias entre servidores de news. Los diferentes demonios encargados de esta tarea (como in.nntpd o innd) suelen discriminar conexiones en función de la dirección o el nombre de la máquina cliente; por ejemplo, el primero utiliza el fichero nntp_access para decidir si ofrece el servicio de news a un determinado host, y si es así concretar de que forma puede acceder a él (sólo lectura, sólo ciertos grupos...). De esta forma, los servidores NNTP son muy vulnerables a cualquier ataque que permita falsear la identidad de la máquina origen, como el IP Spoofing.
Los problemas relacionados con las news no suelen ser excesivamente graves desde un punto de vista estrictamente técnico, pero en ocasiones sí que lo son aplicando una visión global. Por ejemplo, habría que evaluar el daño que le supone a la imagen de nuestra organización el que un atacante envíe mensajes insultantes o pornográficos utilizando nuestro nombre o nuestros recursos. También es un problema la mala educación de los usuarios en materias de seguridad informática: tienden a creer todo lo que leen en ciertos grupos de noticias, por lo que un atacante podría utilizar ingeniería social para perjudicar a nuestra organización. Otra amenaza común es el uso de grupos de news privados (internos) para tratar información confidencial en la organización: esto es un error, ya que si la privacidad del servidor se ve comprometida un atacante puede obtener datos que a priori no estaría autorizado a saber.
Realmente, es muy poco probable que necesitemos ofrecer este servicio, por lo que lo más razonable para nuestra seguridad es deshabilitarlo. Generalmente sólo existen servidores de noticias en grandes organizaciones - como las universidades -, y además lo normal es que sólo haya uno por entidad. Si debemos administrar ese equipo la mejor forma de proteger el servicio NNTP es utilizando un buen cortafuegos ([GS96]).
NTP
NTP (Network Time Protocol, puerto 123 UDP y TCP) es un protocolo utilizado para sincronizar relojes de máquinas de una forma muy precisa; a pesar de su sofisticación no fué diseñado con una idea de robustez ante ataques, por lo que puede convertirse en una gran fuente de problemas ([Bis90]) si no está correctamente configurado o si no utilizamos versiones actualizadas de nntpd, el demonio que ofrece este servicio.
Son muchos los problemas de seguridad relacionados con un tiempo correcto; el más simple y obvio es la poca fiabilidad que ofrecerá nuestro sistema de log a la hora de determinar cuándo sucedió determinado evento: aunque se registrara que alguien hizo un telnet a las tres de la tarde, no podríamos ni siquiera asegurar que la hora es correcta. Otro problema típico radica en las facilidades que ofrece Unix para la planificación de tareas: si el reloj tiene problemas, es posible que ciertas tareas no se lleguen a ejecutar, que se ejecuten varias veces, o que se ejecuten cuando no han de hacerlo; esto es especialmente peligroso para tareas de las que depende nuestra seguridad, como la rotación de logs. Si hablamos de problemas más sofisticados, podemos pensar en sistemas distribuidos, en los que una correcta sincronización entre nodos es básica para garantizar el correcto funcionamiento del sistema global ([Tan95], [CDK94]...); la sincronización es muy importantes en modelos de autenticación como Kerberos, que utiliza marcas de tiempo como pruebas de frescura para evitar ataques por reenvío.
Como hemos visto, una correcta sincronización del reloj de nuestro equipo es vital para la seguridad; no obstante, muy pocos sistemas necesitan la precisión de NTP, por lo que es habitual tener este servicio deshabilitado. En la mayoría de ocasiones el propio reloj de la máquina, o un protocolo mucho más simple, como time, es más que suficiente para sincronizar equipos.
UUCP
UUCP (Unix to Unix CoPy, puerto 540 TCP) es un servicio que, como su nombre indica, se utiliza para copiar ficheros entre máquinas Unix, generalmente a través de líneas telefónicas o redes de baja velocidad; aunque hoy en día apenas se utiliza, durante años ha sido la base de los sistemas de correo electrónico y de news (incluso hoy en día algunos sistemas UUCP son capaces de transmitir noticias de Usenet más eficientemente que la más moderna implementación de NNTP).
Dos riesgos fundamentales amenazan a UUCP: al tratarse de una transmisión en texto claro, un potencial atacante puede tener acceso a información privada de los usuarios, vulnerando su privacidad. Evidentemente, en el caso de transmisión de news esto no es muy relevante, ya que todos los mensajes son en principio de acceso público, pero la cosa cambia si estamos transmitiendo correo electrónico. El segundo riesgo es incluso más preocupante que la pérdida de privacidad: las contraseñas de los usuarios también se transmiten en texto claro, con el consiguiente peligro que supone la interceptación por parte de un pirata de dichas claves. Aunque si utilizamos líneas telefónicas la probabilidad de que un sniffer capture los datos enviados es menor que si utilizamos una red TCP, en ambos casos el riesgo está presente.
Como siempre, y dado que como hemos dicho UUCP no se suele utilizar hoy en día, lo más recomendable es deshabilitar este servicio; es más, dado que suele existir un usuario uucp en todo sistema Unix (por motivos simplemente de compatibilidad), hemos de estar atentos a los posibles problemas que dicho usuario pueda generar. Es necesario asegurarse que no se permiten conexiones bajo este nombre de usuario, que en su directorio $HOME no existen un fichero .rhosts...las precauciones habituales con cualquier nombre de usuario de este tipo que tengamos en nuestro sistema; incluso nos puede interesar sustituir su shell original (si lo tiene) por uno como /bin/false, para que un posible atacante que se haga pasar por uucp no tenga posibilidad de ejecutar órdenes en la máquina. Si estamos obligados a ofrecer conexiones vía UUCP en nuestro sistema, una buena referencia para conocer más detalles de este mecanismo y su seguridad es [OT88] (sólo su fecha nos da una idea del grado de desuso en que ha caído UUCP); otra excelente fuente de información sobre la seguridad - e inseguridad - de UUCP es el capítulo 15 de [GS96]. Una medida de protección básica es asignar un login y password diferente para cada sistema que conecte con el nuestro mediante este método; aparte de incrementar la seguridad - si un atacante averigua una clave sólo podrá utilizar un acceso, no todos - así conseguimos un mayor refinamiento a la hora de registrar los eventos que se produzcan en nuestro sistema, lo que es muy útil de cara a perseguir un abuso del servicio por parte de usuarios no autorizados. Además, en situaciones extremas podemos configurar los módems para realizar un callback cuando reciben una petición, lo que asegura que estamos llamando al sistema deseado y no a otro - siempre que un atacante no haya podido modificar esos números -.