Seguridad en Unix y Redes
Libro en Formato HTML y PDF de seguridad informática realizado por Antonio Villalon Huerta

Los contenidos pueden estar desactualizados con respecto al original

Este documento se encuentra disponible también en formato PDF

Ataques remotos


next up previous contents
Siguiente: Sistemas de detección de Subir: Seguridad de la subred Anterior: Cortafuegos: Casos de estudio   Índice General

Subsecciones

Ataques remotos

Escaneos de puertos

Una de las primeras actividades que un potencial (o no tan potencial) atacante realizará contra su objetivo será sin duda un escaneo de puertos, un portscan; esto le permitirá obtener en primer lugar información básica acerca de qué servicios estamos ofreciendo en nuestras máquinas y, adicionalmente, otros detalles de nuestro entorno como qué sistema operativo tenemos instalados en cada host o ciertas características de la arquitectura de nuestra red. Analizando qué puertos están abiertos en un sistema, el atacante puede buscar agujeros en cada uno de los servicios ofrecidos: cada puerto abierto en una máquina es una potencial puerta de entrada a la misma.

Comprobar el estado de un determinado puerto es a priori una tarea muy sencilla; incluso es posible llevarla a cabo desde la línea de órdenes, usando una herramienta tan genérica como telnet. Por ejemplo, imaginemos que queremos conocer el estado del puerto 5000 en la máquina cuya dirección IP es 192.168.0.10; si el telnet a dicho puerto ofrece una respuesta, entonces está abierto y escuchando peticiones:
anita:~$ telnet 192.168.0.10 5000 
Trying 192.168.0.10...
Connected to 192.168.0.10.
Escape character is '^]'.
^D
Connection closed by foreign host.
anita:~$
Si por el contrario el puerto está abierto pero en él no hay ningún demonio atendiendo peticiones, la respuesta será similar a la siguiente:
anita:~$ telnet 192.168.0.10 5000
Trying 192.168.0.10...
telnet: Unable to connect to remote host: Connection refused
anita:~$
Por último, si el puerto está protegido por un cortafuegos, lo más probable18.1 es que no obtengamos respuesta alguna; el telnet lanzado se quedará intentando la conexión hasta que se produzca un timeout o hasta que lo paremos manualmente:
anita:~$ telnet 192.168.0.10 5000
Trying 192.168.0.10...
^D
anita:~$
Por lo general, nadie en su sano juicio usaría telnet para realizar un escaneo de puertos masivo contra un sistema o contra toda una red; existen herramientas como strobe o nmap (la más conocida) que pueden realizar esta tarea de una forma más o menos cómoda y automatizable. Evidentemente, ninguno de estos programas se dedica a lanzar telnets contra los puertos de un sistema: los escaneadores de puertos actuales implementan diferentes técnicas que permiten desde detectar desde la versión del sistema operativo usado en la máquina atacada hasta pasar inadvertidos ante diferentes sistemas de detección de intrusos.

Existen diferentes aproximaciones para clasificar los escaneos de puertos, tanto en función de las técnicas seguidas en el ataque como en función de a qué sistemas o puertos concretos va dirigido. Por ejemplo, se habla de un escaneo horizontal cuando el atacante busca la disponibilidad de determinado servicio en diferentes máquinas de una red; por ejemplo, si el pirata dispone de un exploit que aprovecha un fallo en la implementación de sendmail, es normal que trate de averiguar qué máquinas aceptan peticiones SMTP en un determinado segmento para posteriormente atacar a dichos sistemas. Si por contra el pirata sólo escanea puertos de una máquina, se denomina al ataque escaneo vertical, y suele denotar el interés del atacante en ese host concreto; si comprueba todos los puertos del sistema al escaneo se le denomina vanilla, mientras que si sólo lo hace contra determinados puertos o rangos, se le denomina strobe (en referencia al programa del mismo nombre). Si nos basamos en las técnicas utilizadas, podemos dividir los escaneos en tres grandes familias: open, half-open y stealth; vamos a hablar con más detalle de cada una de ellas y de los diferentes tipos escaneos que las forman.

Los escaneos open se basan en el establecimiento de una conexión TCP completa mediante el conocido como protocolo de acuerdo de tres vías o three-way handshake ([Tom75]), por lo que son muy sencillos de detectar y detener. Utilizan la llamada connect(), siendo lo más similar - guardado las distancias - al ejemplo del telnet que hemos visto antes: el escaneador intenta establecer una conexión con un puerto concreto del host atacado, y en función de la respuesta obtenida conoce su estado: una técnica rápida, sencilla, fiable y que no necesita de ningún privilegio especial en la máquina atacante.

La segunda técnica que hemos comentado es la de los escaneos half-open; en este caso, el pirata finaliza la conexión antes de que se complete el protocolo de acuerdo de tres vías, lo que de entrada dificulta - aunque no mucho - la detección del ataque por parte de algunos detectores de intrusos muy simples (casi todos los actuales son capaces de detectarlos). Dentro de esta técncia se encuentra el SYN Scanning: cuando el origen - atacante - recibe del destino - máquina escaneada - los bits SYN+ACK, envía un bit RST (no es necesaria una nueva trama, ya que este bit se envía automáticamente a nivel de núcleo) en lugar del ACK correspondiente a un three-way handshake completo. Los escaneos SYN son fácilmente detectables y pueden ser bloqueados en cualquier cortafuegos; existe una variable de esta técnica denominada dumb scanning ([Det01]) en la que entra en juego una tercera máquina denominada `tonta' (por el poco tráfico que emite y recibe), algo que puede ayudar al pirata a camuflar su origen real. Sin embargo, el dumb scanning es más complicado que el SYN scanning, por lo que se utiliza mucho menos en la vida real.

Finalmente, existe otra modelo de escaneo denominado stealth scanning. En diciembre de 1995 Christopher Klaus proporcionó las pautas de ciertas técnicas de escaneo que permitían al atacante eludir la acción de los sistemas de detección de intrusos de la época ([Kla95]) y a las que bautizó como stealth scanning; actualmente el significado del término ha cambiado, ya que lo que Klaus presentó se denomina hoy en día half-open scanning, y por stealth scanning se conoce a una familia de técnicas de escaneo que cumplen alguna de las siguientes condiciones18.2:
  • Eludir cortafuegos o listas de control de acceso.
  • No ser registradas por sistemas de detección de intrusos, ni orientados a red ni en el propio host escaneado.
  • Simular tráfico normal y real para no levantar sospechas ante un analizador de red.
Una de las técnicas que encontramos dentro de la familia de los escaneos stealth es la conocida como SYN+ACK. La idea es muy simple, y consiste en una violación del three-way handshake: el atacante, en lugar de enviar en primer lugar una trama SYN, envía SYN+ACK. Si el puerto está abierto simplemente se ignora, y si está cerrado sabe que no ha recibido previamente un paquete SYN, por lo que lo considera un error y envía una trama RST para finalizar la conexión.

Los escaneos basados en este método se usan poco en la actualidad, debido al elevado número de falsos positivos que pueden generar: sólo debemos pensar en los múltiples motivos - aparte de un puerto abierto - que pueden existir para que un sistema no responda ante una petición SYN+ACK: desde listas de control de accesos en los routers o cortafuegos hasta simples timeouts.

Otra técnica dentro de los escaneos stealth es el FIN scanning ([Mai96]): en este caso, el atacante envía a su objetivo una trama con el bit FIN activo, ante lo que este responde con un RST si el puerto está cerrado, o simplemente no responde en caso de estar abierto; como en el caso de los escaneos SYN+ACK este método puede proporcionar muchos falsos positivos, por lo que tampoco se utiliza mucho hoy en día.

También en [Mai96], se propone un método de escaneo algo más complejo: el ACK. El atacante envía una trama con este bit activo, y si el puerto destino está abierto es muy posible que o bien el campo TTL del paquete de vuelta sea menor que el del resto de las tramas RST recibidas, o que el tamaño de ventana sea mayor que cero: como podemos ver, en este caso no basta con analizar el bit RST sino también la cabecera IP del paquete respuesta. Este método es difícil de registrar por parte de los detectores de intrusos, pero se basa en el código de red de BSD, por lo que es dependiente del operativo escaneado.

Para finalizar con la familia de stealth scanning vamos a hablar de dos métodos opuestos entre sí pero que se basan en una misma idea y proporcionan resultados similares: se trata de XMAS y NULL. Los primeros, también denominados escaneos `árbol de navidad', se basan en enviar al objetivo tramas con todos los bits TCP (URG, ACK, PST, RST, SYN y FIN) activos; si el puerto está abierto el núcleo del sistema operativo eliminará la trama, ya que evidentemente la considera una violación del three-way handshake, pero si está cerrado devolverá un RST al atacante. Como antes, este método puede generar demasiados falsos positivos, y además sólo es aplicable contra máquinas Unix debido a que está basado en el código de red de BSD.

Por contra, el método opuesto al XMAS se denomina NULL scanning, y evidentemente consiste en enviar tramas con todos los bits TCP reseteados; el resultado es similar: no se devolverá ningún resultado si el puerto está abierto, y se enviará un RST si está cerrado. Aunque en principio este método sería aplicable a cualquier pila TCP/IP ([Ark99]), la implementación - incorrecta - que de la misma hacen algunos operativos (entre ellos HP/UX o IRIX) hace que en ocasiones se envien bits RST también desde los puertos abiertos, lo que puede proporcionar demasiados falsos positivos.

Antes de acabar el punto, vamos a hablar de otra técnica de escaneo de puertos que no se puede englobar en las tres clases de las que hemos hablado: se trata de los escaneos UDP, que al contrario de todos los comentados hasta el momento utiliza este protocolo, y no TCP, para determinar el estado de los puertos de una máquina. Al enviar un datagrama UDP a un puerto abierto este no ofrece respuesta alguna, pero si está cerrado devuelve un mensaje de error ICMP: ICMP/SMALL>_PORT/SMALL>_UNREACHABLE. Evidentemente, estos ataques son muy sencillos de detectar y evitar tanto en un sistema de detección de intrusos como en los núcleos de algunos Unices, y por si esto fuera poco debemos recordar que UDP no es un protocolo orientado a conexión (como lo es TCP), por lo que la pérdida de datagramas puede dar lugar a un elevado número de falsos positivos.

Hemos repasado las técnicas más habituales - no todas - que un atacante puede utilizar para averiguar el estado de los puertos de nuestras máquinas; muchas de ellas son sencillas de detectar y evitar utilizando cortafuegos sencillos y gratuitos como iptables o IPFilter, por lo que tenemos una razón más para utilizar un firewall que proteja nuestra red. Los puertos abiertos de un sistema proporcionan a un pirata una valiosa información sobre el mismo, en muchos casos suficiente para iniciar un ataque más serio contra la máquina, así que mucho mejor para nosotros cuanto más difícil le pongamos esta tarea.

Spoofing

Por spoofing se conoce a la creación de tramas TCP/IP utilizando una dirección IP falseada; la idea de este ataque - al menos la idea - es muy sencilla: desde su equipo, un pirata simula la identidad de otra máquina de la red para conseguir acceso a recursos de un tercer sistema que ha establecido algún tipo de confianza basada en el nombre o la dirección IP del host suplantado. Y como los anillos de confianza basados en estas características tan fácilmente falsificables son aún demasiado abundantes (no tenemos más que pensar en los comandos r-, los accesos NFS, o la protección de servicios de red mediante TCP Wrapper), el spoofing sigue siendo en la actualidad un ataque no trivial, pero factible contra cualquier tipo de organización.

Como hemos visto, en el spoofing entran en juego tres máquinas: un atacante, un atacado, y un sistema suplantado que tiene cierta relación con el atacado; para que el pirata pueda conseguir su objetivo necesita por un lado establecer una comunicación falseada con su objetivo, y por otro evitar que el equipo suplantado interfiera en el ataque ([HB96]). Probablemente esto último no le sea muy difícil de conseguir: a pesar de que existen múltiples formas de dejar fuera de juego al sistema suplantado - al menos a los ojos del atacado - que no son triviales (modificar rutas de red, ubicar un filtrado de paquetes entre ambos sistemas...), lo más fácil en la mayoría de ocasiones es simplemente lanzar una negación de servicio contra el sistema en cuestión. Aunque en el punto siguiente hablaremos con más detalle de estos ataques, no suele ser difícil `tumbar', o al menos bloquear parcialmente, un sistema medio; si a pesar de todo el atacante no lo consigue, simplemente puede esperar a que desconecten de la red a la máquina a la que desea suplantar (por ejemplo, por cuestiones de puro mantenimiento).

El otro punto importante del ataque, la comunicación falseada entre dos equipos, no es tan inmediato como el anterior y es donde reside la principal dificultad del spoofing. En un escenario típico del ataque, un pirata envía una trama SYN a su objetivo indicando como dirección origen la de esa tercera máquina que está fuera de servicio y que mantiene algún tipo de relación de confianza con la atacada. El host objetivo responde con un SYN+ACK a la tercera máquina, que simplemente lo ignorará por estar fuera de servicio (si no lo hiciera, la conexión se resetearía y el ataque no sería posible), y el atacante enviará ahora una trama ACK a su objetivo, también con la dirección origen de la tercera máquina. Para que la conexión llegue a establecerse, esta última trama deberá enviarse con el número de secuencia adecuado; el pirata ha de predecir correctamente este número: si no lo hace, la trama será descartada), y si lo consigue la conexión se establecerá y podrá comenzar a enviar datos a su objetivo, generalmente para tratar de insertar una puerta trasera que permita una conexión normal entre las dos máquinas.

Podemos comprobar que el spoofing no es inmediato; de entrada, el atacante ha de hacerse una idea de cómo son generados e incrementados los números de secuencia TCP, y una vez que lo sepa ha de conseguir `engañar' a su objetivo utilizando estos números para establecer la comunicación; cuanto más robusta sea esta generación por parte del objetivo, más difícil lo tendrá el pirata para realizar el ataque con éxito. Además, es necesario recordar que el spoofing es un ataque ciego: el atacante no ve en ningún momento las respuestas que emite su objetivo, ya que estas van dirigidas a la máquina que previamente ha sido deshabilitada, por lo que debe presuponer qué está sucediendo en cada momento y responder de forma adecuada en base a esas suposiciones. Sería imposible tratar con el detenimiento que merecen todos los detalles relativos al spoofing por lo que para obtener información adicional es necesario dirigirse a excelentes artículos que estudian todos los pormenores del ataque, como [Dae96] o [HB96]; de la misma forma, para conocer con detalle el funcionamiento del protocolo TCP/IP y sus problemas podemos consultar [Ste94], [Tan96], [Bel89] y [Mor85].

Para evitar ataques de spoofing exitosos contra nuestros sistemas podemos tomar diferentes medidas preventivas; en primer lugar, parece evidente que una gran ayuda es reforzar la secuencia de predicción de números de secuencia TCP: un esquema de generación robusto puede ser el basado en [Bel96], que la mayoría de Unices son capaces de implantar (aunque muchos de ellos no lo hagan por defecto). Otra medida sencilla es eliminar las relaciones de confianza basadas en la dirección IP o el nombre de las máquinas, sustituyéndolas por relaciones basadas en claves criptográficas; el cifrado y el filtrado de las conexiones que pueden aceptar nuestras máquinas también son unas medidas de seguridad importantes de cara a evitar el spoofing.

Hasta ahora hemos hablado del ataque genérico contra un host denominado spoofing o, para ser más exactos, IP Spoofing; existen otros ataques de falseamiento relacionados en mayor o menor medida con este, entre los que destacan el DNS Spoofing, el ARP Spoofing y el Web Spoofing ([Ris01]). Para finalizar este punto, vamos a comentarlos brevemente e indicar algunas lecturas donde se puede ampliar información sobre los mismos:
  • DNS Spoofing
    Este ataque hace referencia al falseamiento de una dirección IP ante una consulta de resolución de nombre (esto es, resolver con una dirección falsa un cierto nombre DNS), o viceversa (resolver con un nombre falso una cierta dirección IP). Esto se puede conseguir de diferentes formas, desde modificando las entradas del servidor encargado de resolver una cierta petición para falsear las relaciones dirección-nombre, hasta comprometiendo un servidor que infecte la caché de otro (lo que se conoce como DNS Poisoning); incluso sin acceso a un servidor DNS real, un atacante puede enviar datos falseados como respuesta a una petición de su víctima sin más que averiguar los números de secuencia correctos.
  • ARP Spoofing
    El ataque denominado ARP Spoofing hace referencia a la construcción de tramas de solicitud y respuesta ARP falseadas, de forma que en una red local se puede forzar a una determinada máquina a que envíe los paquetes a un host atacante en lugar de hacerlo a su destino legítimo. La idea es sencilla, y los efectos del ataque pueden ser muy negativos: desde negaciones de servicio hasta interceptación de datos, incluyendo algunos Man in the Middle contra ciertos protocolos cifrados. En [Vol97] podemos obtener más información acerca de este ataque, así como código fuente para enviar tramas falseadas y comprobar los efectos del ARP Spoofing en nuestra red.
  • Web Spoofing
    Este ataque permite a un pirata visualizar y modificar cualquier página web que su víctima solicite a través de un navegador, incluyendo las conexiones seguras vía SSL. Para ello, mediante código malicioso un atacante crea una ventana del navegador correspondiente, de apariencia inofensiva, en la máquina de su víctima; a partir de ahí, enruta todas las páginas dirigidas al equipo atacado - incluyendo las cargadas en nuevas ventanas del navegador - a través de su propia máquina, donde son modificadas para que cualquier evento generado por el cliente sea registrado (esto implica registrar cualquier dato introducido en un formulario, cualquier click en un enlace, etc.). Para obtener más información acerca del Web Spoofing podemos consultar [FBDW96].

Negaciones de servicio

Las negaciones de servicio (conocidas como DoS, Denial of Service) son ataques dirigidos contra un recurso informático (generalmente una máquina o una red, pero también podría tratarse de una simple impresora o una terminal) con el objetivo de degradar total o parcialmente los servicios prestados por ese recurso a sus usuarios legítimos; constituyen en muchos casos uno de los ataques más sencillos y contundentes contra todo tipo de servicios, y en entornos donde la disponibilidad es valorada por encima de otros parámetros de la seguridad global puede convertirse en un serio problema, ya que un pirata puede interrumpir constantemente un servicio sin necesidad de grandes conocimientos o recursos, utilizando simplemente sencillos programas y un módem y un PC caseros.

Las negaciones de servicio más habituales suelen consistir en la inhabilitación total de un determinado servicio o de un sistema completo, bien porque ha sido realmente bloqueado por el atacante o bien porque está tan degradado que es incapaz de ofrecer un servicio a sus usuarios. En la mayor parte de sistemas, un usuario con acceso shell no tendría muchas dificultades en causar una negación de servicio que tirara abajo la máquina o la ralentizara enormemente; esto no tiene porqué ser - y de hecho en muchos casos no lo es - un ataque intencionado, sino que puede deberse a un simple error de programación. Por ejemplo, pensemos en el siguiente shellscript (funciona en Linux):
luisa:~# cat /usr/local/bin/lanzador
#!/bin/sh
ps -ef|grep calcula|grep -v grep 2>&1 >/dev/null
if [ $? -eq 1 ]; then
        /usr/local/bin/calcula &
fi
luisa:~#
Como podemos ver, este script comprueba si un determinado programa está lanzado en la máquina, y si no lo está lo lanza él; algo completamente inofensivo a primera vista, y planificado habitualmente en muchos sistemas para que se ejecute - por ejemplo, cada cinco minutos - desde crond. Sin embargo, nos podemos parar a pensar qué sucedería bajo algunas circunstancias anormales: >y si en el arranque de la máquina, por el motivo que sea, no se ha montado correctamente el directorio /proc/? Si esto sucede, la orden `ps' generará un error, la condición se cumplirá siempre, y cada cinco minutos se lanzará una copia de calcula; si este programa consume mucha CPU, al poco tiempo tendremos un elevado número de copias que cargarán enormemente el sistema hasta hacerlo inutilizable. Un ejemplo perfecto de negación de servicio.

Por fortuna, como ya hemos visto en capítulos anteriores, todos los sistemas Unix ofrecen mecanismos para evitar que un usuario normal pueda tirar abajo una máquina de esta forma; incluso si no los ofrecieran, en la mayor parte de los casos el responsable podría ser disciplinado fuera del sistema operativo, por otros medios, como dijo Dennis Ritchie. El problema real no es que usuarios legítimos de un entorno causen, intencionada o inintencionadamente, negaciones de servicio: el mayor problema es que esas negaciones sean causadas de forma remota por piratas ajenos por completo a nuestra organización, capaces de tumbar un servidor de millones de pesetas con sencillos programas, sin dejar ningún rastro y lo peor, sin ser muchas veces conscientes del daño que están haciendo.

Estos ataques remotos de negación de servicio son considerados negativos incluso por muchos de los propios piratas - especialmente los más experimentados -, ya que realmente no suelen demostrar nada positivo de quien los lanza (si es que algún ataque demuestra algo positivo de alguien, lo cual sería muy discutible...): generalmente se trata de un script-kiddie ejecutando un programa que ni ha hecho, ni entiende, ni será capaz de entender. En la mayor parte de los casos la negación de servicio tiene éxito porque el objetivo utiliza versiones no actualizadas de demonios (si se para un servicio concreto) o del propio núcleo del sistema operativo, si se detiene o degrada por completo la máquina. Para evitar esto, la norma a seguir es evidente: mantener siempre actualizados nuestros sistemas, tanto en lo referente al nivel de parcheado o versiones del núcleo, como en lo referente a programas críticos encargados de ofrecer un determinado servicio (demonios, por norma general: sendmail, httpd, pop3d...).

De un tiempo a esta parte - en concreto, desde 1999 - se ha popularizado mucho el término `negación de servicio distribuida' (Distributed Denial of Service, DDoS): en este ataque un pirata compromete en primer lugar un determinado número de máquinas y, en un determinado momento, hace que todas ellas ataquen masiva y simultaneamente al objetivo u objetivos reales enviándoles diferentes tipos de paquetes; por muy grandes que sean los recursos de la víctima, el gran número de tramas que reciben hará que tarde o temprano dichos recursos sean incapaces de ofrecer un servicio, con lo que el ataque habrá sido exitoso. Si en lugar de cientos o miles de equipos atacando a la vez lo hiciera uno sólo las posibilidades de éxito serían casi inexistentes, pero es justamente el elevado número de `pequeños' atacantes lo que hace muy difícil evitar este tipo de negaciones de servicio.

Según el CERT ([HW01]) los ataques de negación de servicio distribuidos más habituales consisten en el envío de un gran número de paquetes a un determinado objetivo por parte de múltiples hosts, lo que se conoce como packet flooding (en función del tipo de paquetes utilizados se habla de ping flood, de SYN flood...). Defenderse de este tipo de ataques es difícil: en primer lugar, uno piensa en bloquear de alguna forma (probablemente en un cortafuegos o en un router) todo el tráfico proveniente de los atacantes; pero >qué sucede cuando tenemos miles de ordenadores atacando desde un gran número de redes diferentes? >Los bloqueamos uno a uno? Esto supondría un gran esfuerzo que difícilmente ayudaría, ya que lo más probable es que en el tiempo que nos cueste bloquear el tráfico de una determinada máquina, dos o tres nuevas nos comiencen a atacar. Entonces, >bloqueamos todo el tráfico dirigido hacia el objetivo? Si hacemos esto, estamos justamente ayudando al atacante, ya que somos nosotros mismos los que causamos una negación en el servicio a los usuarios legítimos de nuestro sistema...

Como vemos, la defensa ante una negación de servicio distribuida no es inmediata; en cualquier caso, podemos tomar ciertas medidas preventivas que nos ayudarán a limitar el alcance de uno de estos ataques (y en general de las negaciones de servicio remotas, distribuidas o no). De entrada, un correcto filtrado del tráfico dirigido a nuestras máquinas es vital para garantizar nuestra seguridad: no hay que responder a pings externos a nuestra red, es necesario activar el antispoofing en nuestros cortafuegos y en los elementos de electrónica de red que lo permitan, etc. Establecer correctamente límites a la utilización de nuestros recursos, como ya hemos visto, es también una importante medida preventiva; es posible limitar el ancho de banda dedicado a una determinada aplicación o a un protocolo, de forma que las utilizaciones por encima del margen son negadas. También podemos limitar los recursos del sistema (CPU, memoria, disco...) que puede consumir en global una determinada aplicación servidora (por ejemplo, un demonio sirviendo páginas web), además de restringir sus recursos por cliente simultáneo (en base, por ejemplo, a la dirección origen de ese cliente).

A pesar de las dificultades con las que nos podemos encontrar a la hora de prevenir ataques de negación de servicio, una serie de medidas sencillas pueden ayudarnos de forma relativa en esa tarea; las negaciones de servicio son por desgracia cada día más frecuentes, y ninguna organización está a salvo de las mismas. Especialmente en los ataques distribuidos, la seguridad de cualquier usuario conectado a Internet (aunque sea con un sencillo PC y un módem) es un eslabón importante en la seguridad global de la red, ya que esos usuarios se convierten muchas veces sin saberlo en satélites que colaboran en un ataque masivo contra organizaciones de cualquier tipo. Cuanto más difícil se lo pongamos cada uno de nosotros a los piratas, mucho mejor para todos.

Interceptación

En la sección 2.3.1 ya comentamos algunos aspectos relacionados con la interceptación de datos en tránsito o en proceso por parte de usuarios no autorizados; allí hablamos de los ataques y defensas desde un punto de vista casi exclusivamente físico, por lo que vamos a entrar ahora en algunos puntos más relacionados con la interceptación lógica. Y sin duda, la interceptación lógica de datos más conocida y extendida es el sniffing: en esa misma sección ya introdujimos este término y hablamos de dispositivos hardware como los sniffers de alta impedancia; sin embargo, en entornos de trabajo de seguridad media es mucho más común que el sniffing se produzca utilizando programas (sniffers) y no elementos hardware.

En las redes de difusión, cuando una máquina envía una trama a otra indica en un campo reservado la dirección del host destino18.3; todas las máquinas del dominio de colisión ven esa trama, pero sólo su receptora legítima la captura y elimina de la red. Este es el funcionamiento normal de TCP/IP; sin embargo, es necesario insistir en un aspecto: todas las máquinas ven la trama, y si no leen todos sus campos es porque no `quieren'. Existe un modo de funcionamiento de las interfaces de red denominado modo promiscuo, en el cual la tarjeta lee todas las tramas que circulan por la red, tanto dirigidas a ella como a otras máquinas; el leerlas no implica el eliminarlas de la red, por lo que el host destino legítimo la recibirá y eliminará sin notar nada extraño.

Para hacer funcionar un interfaz de red en modo promiscuo es necesario tener un control total del sistema o, dicho de otra forma, ser root en la máquina; esto ayuda un poco en la defensa, pero ni de lejos soluciona el problema que estamos planteado: no podemos permitir que cualquiera que sea superusuario de un sistema pueda capturar todo el tráfico que pasa por el mismo (incluyendo claves, correo electrónico, y cientos de datos privados). Por si esto fuera poco, en los sistemas donde todos los usuarios tienen un control total de la máquina (por ejemplo, en toda la familia Windows 9x) ni siquiera hace falta ese privilegio: cualquiera que se siente en un PC puede ejecutar un sniffer y capturar todo el tráfico de la red.

Programas para `esnifar' tráfico hay para todos los gustos y colores: desde dsniff y su familia, capaces hasta de capturar los correos electrónicos directamente en formato SMTP o cargar de forma automática en un navegador las mismas páginas que visita la víctima del ataque, hasta el arcaico snoop de Solaris, que vuelca paquetes en un formato por defecto casi ilegible, pasando por los clásicos tcpdump o sniffit (que en algunas de sus versiones incluía el Touch of Dead, capaz de cortar conexiones establecidas entre dos máquinas sin más que pulsar F5). Para evitar que programas de este tipo capturen nuestra información existen diferentes aproximaciones más o menos efectivas, como sustituir los HUBs de nuestra red por switches que aislan dominios de colisión (<ojo, esto dificulta el ataque pero no lo imposibilita!) o implantar redes privadas virtuales. Pero sin ninguna duda la más barata y sencilla es el uso de protocolos cifrados siempre que nos sea posible (que lo suele ser casi siempre); repetimos una vez más lo que hemos dicho ya en muchas ocasiones: sustituir telnet y rlogin por SSH y FTP por scp o sftp es muy sencillo, y nos proporciona un incremento de seguridad abismal en nuestro entorno. Implantar SSL o túneles seguros quizás es algo más costoso - en tiempo solamente -, pero también en la mayoría de ocasiones es algo que vale la pena hacer: en todo momento hemos de tener presente que el sniffing es un peligro real, que no necesita de grandes medios y, lo que es peor, indetectable en la mayor parte de casos; a pesar de que existen métodos para tratar de detectar sistemas con un interfaz en modo promiscuo, no suelen ser todo lo efectivos que uno podría esperar, ya que detectar una máquina en este estado no es ni de lejos inmediato.

Como hemos dicho, el sniffing es el ataque de interceptación más conocido y utilizado, pero no es el único que se puede poner en práctica contra un sistema determinado, Unix o no. En algunas versiones de Linux existe un programa denominado ttysnoop (por snooping - fisgoneo - se conoce a los ataques genéricos de interceptación de datos) capaz de registrar en tiempo real todo lo que un usuario teclea en una terminal, tanto física como virtual. Aunque el resultado es en muchos aspectos similar al sniffing, técnicamente poco tiene que ver con este: en ningún momento se capturan datos que circulan por la red, la tarjeta no trabaja en modo promiscuo (es mas, ni siquiera es necesario un interfaz de red), etc; simplemente, la información que un usuario introduce en una terminal es clonada en otra, permitiendo tanto la entrada como la salida de datos a través de ambas. Aunque Linux sea el sistema Unix nativo de ttysnoop existen versiones también para otros entornos, y por supuesto esta no es la única herramienta para `fisgonear' en las terminales de usuarios (otro ejemplo podría ser TTY Watcher, disponible para SunOS y Solaris).

Otro ataque de interceptación, menos utilizado que los anteriores pero igual de peligroso, es el keylogging, el registro de las teclas pulsadas por un usuario en una sesión. Aunque es más habitual el uso de keyloggers en entornos Windows, en Unix también disponemos de ellos: podríamos incluso considerar a ttysnoop como un keylogger avanzado, que no se limita únicamente a registrar lo tecleado sino que permite interacción en tiempo real; otro ejemplo de un programa que capture esta información puede ser una mula de troya clásica, de las que ya hemos hablado. Incluso en cualquier Unix viene de serie un keylogger: el programa script, que guarda en un archivo lo que el usuario que lo invoca lee o escribe en la pantalla; bastaría una llamada a este programa en el inicio de sesión de cada usuario para conseguir un registro - muy arcaico y fácilmente falseable - de lo que cada usuario teclea en su terminal, algo parecido a lo siguiente:
luisa:~# grep script /etc/profile
exec /usr/bin/script -a /tmp/comandos-$USER
luisa:~#
Podemos ver que al invocar a script especificamos el archivo donde deseamos que se replique la información; si en lugar de un fichero plano indicamos una terminal, tenemos un clonador de sesiones perfecto, aunque no interactivo.

Para finalizar este punto podemos reflexionar brevemente sobre la peligrosidad de los ataques de interceptación; muchos de ellos necesitan privilegios de superusuario en al menos una máquina, pero por lo demás son realmente sencillos. Sencillos y peligrosos: aunque se trate de ataques pasivos, y aunque alguien pueda pensar que si el pirata ya es root no se puede atacar más al sistema, permiten capturar datos relativos no sólo al sistema comprometido, sino a otras máquinas que quizás aún no han sido atacadas y que posiblemente representan el objetivo real del pirata. Evitar estos ataques pasa en primera instancia por no permitir que un pirata consiga privilegios en un sistema - mejor si no consigue nada, pero esto no siempre es posible -, y en segunda por lo que ya sabemos: cifrar cuanto más tráfico mejor.

Ataques a aplicaciones

Correo electrónico

Desde hace muchos años los sistemas de correo electrónico de una organización han sido para los piratas una fuente inagotable de puntos de entrada a la misma; lo más probable es que si le preguntamos a cualquier administrador de máquinas Unix con algo de experiencia cuál ha sido el software que más problemas de seguridad le ha causado nos responda sin dudarlo: sendmail, por supuesto. Y ya no sólo sendmail y el protocolo SMTP, sino que también, con la popularización de POP3, los servidores de este protocolo son un peligro potencial a tener en cuenta en cualquier entorno informático donde se utilice el correo electrónico: es decir, en todos.

De entrada, un programa como sendmail - lo ponemos como ejemplo por ser el más popular, pero podríamos hablar en los mismos términos de casi cualquier servidor SMTP - proporciona demasiada información a un atacante que simplemente conecte a él:
luisa:~$ telnet 0 25
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
220 luisa ESMTP Sendmail 8.9.3/8.9.3; Mon, 29 Oct 2001 03:58:56 +0200
quit
221 luisa closing connection
Connection closed by foreign host.
luisa:~$
Y no sólo se proporcionan datos útiles para un pirata como la versión del programa utilizada o la fecha del sistema, sino que se llega incluso más lejos: tal y como se instalan por defecto, muchos servidores SMTP (aparte de sendmail, algunos tan populares como Netscape Messaging Server) informan incluso de la existencia o inexistencia de nombres de usuario y de datos sobre los mismos:
luisa:~$ telnet 0 25
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
220 luisa ESMTP Sendmail 8.9.3/8.9.3; Mon, 29 Oct 2001 04:03:22 +0200
vrfy root
250 El Spiritu Santo <root@luisa>
expn root
250 El Spiritu Santo <root@luisa>
quit
221 luisa closing connection
Connection closed by foreign host.
luisa:~$
Parece evidente que de entrada estamos dándole a cualquier pirata demasiada información sobre nuestro entorno de trabajo; una de las primeras cosas que deberíamos hacer en todos nuestros servidores de correo es deshabilitar este tipo de opciones. En concreto, para deshabilitar las órdenes vrfy y expn, en sendmail.cf debemos modificar la línea
O PrivacyOptions=authwarnings
para que no se proporcione información, de la forma siguiente:
O PrivacyOptions=goaway
Para conseguir que que sendmail además tampoco informe de su versión y la fecha del sistema - algo recomendable, evidentemente - la entrada a modificar es SmtpGreetingMessage. Si lo hacemos, y además hemos deshabilitado las PrivacyOptions, cuando alguien conecte a nuestro servidor verá algo similar a:
luisa:/# egrep "Privacy|Greeting" /etc/sendmail.cf 
O PrivacyOptions=goaway
O SmtpGreetingMessage=Servidor
luisa:/# telnet 0 25
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
220 Servidor ESMTP
vrfy root
252 Cannot VRFY user; try RCPT to attempt delivery (or try finger)
quit
221 luisa closing connection
Connection closed by foreign host.
luisa:/#
En realidad, si un atacante quiere conocer la versión del servidor que estamos utilizando aún no lo tiene difícil, ya que simplemente ha de teclear una orden como `help':
luisa:~$ telnet 0 25
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
220 Servidor ESMTP
help
214-This is Sendmail version 8.9.3
214-Topics:
214-    HELO    EHLO    MAIL    RCPT    DATA
214-    RSET    NOOP    QUIT    HELP    VRFY
214-    EXPN    VERB    ETRN    DSN
214-For more info use "HELP <topic>".
214-To report bugs in the implementation send email to
214-    sendmail-bugs@sendmail.org.
214-For local information send email to Postmaster at your site.
214 End of HELP info
quit
221 luisa closing connection
Connection closed by foreign host.
luisa:~$
Para evitar esto debemos modificar convenientemente el fichero sendmail.hf (en función del Unix utilizado su ubicación en la estructura de directorios cambiará) de forma que se restrinjan más los mensajes que proporciona el demonio en una sesión interactiva; para obtener información sobre este fichero, así como del resto de configuraciones de sendmail podemos consultar [CA97a]. Debemos tener presente que conocer ciertos datos que el programa proporciona puede facilitarle mucho la tarea a un pirata; ocultar esta información no es ni mucho menos una garantía de seguridad, ni por supuesto ha de suponer uno de los pilares de nuestra política, pero si con un par de pequeñas modificaciones conseguimos quitarnos de encima aunque sólo sea a un atacante casual, bienvenidas sean - aunque muchos consideren esto una apología del security through obscurity -.

Independientemente del programa que utilicemos como servidor de correo y su versión concreta, con vulnerabilidades conocidas o no, otro gran problema de los sistemas de correo SMTP es el relay: la posibilidad de que un atacante interno utilice nuestros servidores para enviar correo electrónico a terceros, no relacionados con nuestra organización. Aunque en principio esto a muchos les pueda parecer un mal menor, no lo es; de entrada, si nuestros servidores permiten el relay estamos favoreciendo el SPAM en la red, el envío de e-mail no deseado con fines casi siempre publicitarios, algo que evidentemente a nadie le hace gracia recibir. Además, el relay causa una negación de servicio contra nuestros usuarios legítimos, tanto desde un punto de vista estrictamente teórico - alguien consume nuestros recursos de forma no autorizada, degradando así el servicio ofrecido a nuestros usuarios legítimos - como en la práctica: cuando un robot encuentra un servidor SMTP en el que se permite el relay lo utiliza masivamente mientras puede, cargando enormemente la máquina y entorpeciendo el funcionamiento normal de nuestros sistemas. Por si esto fuera poco, si se incluye a nuestra organización en alguna `lista negra' de servidores que facilitan el SPAM se causa un importante daño a nuestra imagen, e incluso ciertos dominios pueden llegar a negar todo el correo proveniente de nuestros servidores.

Sólo existe una manera de evitar el relay: configurando correctamente todos nuestros servidores de correo. Por supuesto, esto es completamente dependiente de los programas (sendmail, iPlanet...) utilizados en nuestro entorno, por lo que es necesario consultar en la documentación correspondiente la forma de habilitar filtros que eviten el relay; por Internet exiten incluso filtros genéricos para los servidores más extendidos, por lo que nuestro trabajo no será excesivo ni complicado. Si queremos verificar que nuestros servidores no permiten el relay podemos ejecutar, desde una dirección externa a nuestra organización, el siguiente programa:
luisa:~$ cat security/prog/testrelay.sh
#!/bin/sh
# Este script comprueba que un servidor de correo no permite el relay.
# Basado en los test disponibles en 
# http://133.30.50.200/~takawata/d/resource/relaytest.html
# Necesitamos netcat (nc) instalado en el sistema.
# Toni Villalon <toni@aiind.upv.es>, 03 Enero 2000
# NOTA: Es necesario personalizar la variable DSTADDR
#

# Argumentos erroneos?
if (test $# -lt 1); then
        echo "Uso: $0 mail.dominio.com"
        exit
fi
# Especificamos una direccion origen (no es necesario que sea real)
SRCADDR=prova@prova.com 
SRCUSR=`echo $SRCADDR|awk -F@ '{print $1}'`
SRCDOM=`echo $SRCADDR|awk -F@ '{print $2}'`
# Direccion destino, para comprobar si realmente llega el mail
# SUSTITUIR POR UNA QUE PODAMOS COMPROBAR!!!
DSTADDR=toni@aiind.upv.es
DSTUSR=`echo $DSTADDR|awk -F@ '{print $1}'`
DSTDOM=`echo $DSTADDR|awk -F@ '{print $2}'`
# Direccion IP del host a testear
TESTIP=`host $1|grep address|tail -1|awk '{print $4}'`
if [ $? -ne 0 ]; then
       TESTIP=`/usr/bin/nslookup $1|grep ^Address|awk -F: 'NR==2 {print $2}'`
fi
# Ejecutable NetCat
NC=/usr/local/bin/nc
# Conectamos al servidor y lanzamos los test
# No ponemos todo en un 'cat <<EOF' porque si se generan errores, el servidor
# de correo nos tirara y quedaran test sin realizarse
#
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCADDR>
RCPT TO: <$DSTADDR>
DATA
Relay test no. 1
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET 
HELO $SRCDOM
MAIL FROM: <$SRCUSR>
RCPT TO: <$DSTADDR>
DATA
Relay test no. 2
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: < >
RCPT TO: <$DSTADDR>
DATA
Relay test no. 3
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTADDR>
DATA
Relay test no. 4
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@[$TESTIP]>
RCPT TO: <$DSTADDR>
DATA
Relay test no. 5
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTUSR%$DSTDOM@$1>
DATA
Relay test no. 6
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTUSR%$DSTDOM@[$TESTIP]>
DATA
Relay test no. 7
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <"$DSTADDR">
DATA
Relay test no. 8
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <"$DSTUSR%$DSTDOM">
DATA
Relay test no. 9
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTADDR@$1>
DATA
Relay test no. 10
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <"$DSTADDR"@$1>
DATA
Relay test no. 11
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTADDR@[$TESTIP]>
DATA
Relay test no. 12
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <@$1:$DSTADDR>
DATA
Relay test no. 13
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <@[$TESTIP]:$DSTADDR>
DATA
Relay test no. 14
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTDOM!$DSTUSR>
DATA
Relay test no. 15
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTDOM!$DSTUSR@$1>
DATA
Relay test no. 16
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCUSR@$1>
RCPT TO: <$DSTDOM!$DSTUSR@[$TESTIP]>
DATA
Relay test no. 17
.
QUIT
EOF
cat <<EOF | $NC $1 25
RSET
HELO $SRCDOM
MAIL FROM: <$SRCADDR>
RCPT TO: <$1!$DSTADDR>
DATA
Relay test no. 18
.
QUIT
EOF
luisa:~$
Es muy importante para nosotros cuidar cualquier aspecto de la seguridad relativo a nuestros sistemas de correo, ya que en la actualidad el correo electrónico constituye uno de los servicios básicos de cualquier empresa; simplemente hemos de contar el número de e-mails que solemos recibir al día para hacernos una idea del desastre que supondría un fallo en los sistemas encargados de procesarlo.

Ataques vía web

Durante los últimos años los servidores web se han convertido en una excelente fuente de diversión para piratas: cualquier empresa que se precie, desde las más pequeñas a las grandes multinacionales, tiene una página web en las que al menos trata de vender su imagen corporativa. Si hace unos años un pirata que quisiera atacar a una empresa (y no a todas, ya que muy pocas tenían representación en la red) tenía que agenciarselas para obtener primero información de la misma y después buscar errores de configuración más o menos comunes de sus sistemas (o esperar al próximo bug de sendmail), hoy en día le basta con teclear el nombre de su objetivo en un navegador y añadir la coletilla `.com' detrás del mismo para contactar con al menos una de sus máquinas: su servidor web.

Los ataques a las páginas web de una organización son casi siempre los más `vistosos' que la misma puede sufrir: en cuestión de minutos piratas de todo el mundo se enteran de cualquier problema en la página web principal de una empresa más o menos grande pueda estar sufriendo, y si se trata de una modificación de la misma incluso existen recopilatorios de páginas `hackeadas'. Por supuesto, la noticia de la modificación salta inmediatamente a los medios, que gracias a ella pueden rellenar alguna cabecera sensacionalista sobre `los piratas de la red', y así se consigue que la imagen de la empresa atacada caiga notablemente y la del grupo de piratas suba entre la comunidad 'underground' nacional o internacional.

La mayor parte de estos ataques tiene éxito gracias a una configuración incorrecta del servidor o a errores de diseño del mismo: si se trata de grandes empresas, los servidores web suelen ser bastante complejos (alta disponiblidad, balanceo de carga, sistemas propietarios de actualización de contenidos...) y difíciles de administrar correctamente, mientras que si la empresa es pequeña es muy posible que haya elegido un servidor web simple en su instalación y administración pero en el cual es casi (>casi?) imposible garantizar una mínima seguridad: sí, hablamos de Microsoft Internet Information Server, un sistema que reconocidos expertos en seguridad han recomendado públicamente no utilizar en entornos serios. Sea por el motivo que sea, la cuestión es que cada día es más sencillo para un pirata ejecutar órdenes de forma remota en una máquina, o al menos modificar contenidos de forma no autorizada, gracias a los servidores web que un sistema pueda albergar.

Cualquier analizador de vulnerabilidades que podamos ejecutar contra nuestros sistemas (NESSUS, ISS Security Scanner, NAI CyberCop Scanner...) es capaz de revelar información que nos va a resultar útil a la hora de reforzar la seguridad de nuestros servidores web; incluso existen analizadores que están diseñados para auditar únicamente este servicio, como whisker. Ejecutando este último contra una máquina podemos obtener resultados similares a los siguientes:
anita:~/security/whisker$ ./whisker.pl -h luisa
-- whisker / v1.4.0 / rain forest puppy / www.wiretrip.net --

= - = - = - = - = - =
= Host: luisa
= Server: Apache/1.3.19 (Unix) PHP/4.0.4pl1 mod_ssl/2.8.2 OpenSSL/0.9.5a

+ 200 OK: HEAD /docs/
+ 200 OK: HEAD /cgi-bin/Count.cgi
+ 200 OK: HEAD /cgi-bin/textcounter.pl
+ 200 OK: HEAD /ftp/
+ 200 OK: HEAD /guestbook/
+ 200 OK: HEAD /usage/

anita:~/security/whisker$
Podemos ver que el servidor nos proporciona excesiva información sobre su configuración (versión, módulos, soporte SSL...), y que la herramienta ha obtenido algunos archivos y directorios que pueden resultar interesantes para un atacante: en el caso de los CGI no tiene más que acercarse a alguna base de datos de vulnerabilidades (especialmente recomendables son
http://www.securityfocus.com/
o http://icat.nist.gov/) e introducir en el buscador correspondiente el nombre del archivo para obtener información sobre los posibles problemas de seguridad que pueda presentar. El caso de los directorios es algo diferente, pero típicamente se suele tratar de nombres habituales en los servidores que contienen información que también puede resultarle útil a un potencial atacante.

>Cómo evitar estos problemas de seguridad de los que estamos hablando? Una medida elemental es eliminar del servidor cualquier directorio o CGI de ejemplo que se instale por defecto; aunque generalmente los directorios (documentación, ejemplos...) no son especialmente críticos, el caso de los CGIs es bastante alarmante: muchos servidores incorporan programas que no son ni siquiera necesarios para el correcto funcionamiento del software, y que en ciertos casos - demasiados - abren enormes agujeros de seguridad, como el acceso al código fuente de algunos archivos, la lectura de ficheros fuera del DocumentRoot, o incluso la ejecución remota de comandos bajo la identidad del usuario con que se ejecuta el demonio servidor.

Otra medida de seguridad básica es deshabilitar el Directory Indexing que por defecto muchos servidores incorporan: la capacidad de obtener el listado de un directorio cuando no existe un fichero index.html o similar en el mismo; se trata de una medida extremadamente útil y sobre todo sencilla de implantar, ya que en muchos casos un simple `chmod -r' sobre el directorio en cuestión es suficiente para evitar este problema. A primera vista esta medida de protección nos puede resultar curiosa: a fin de cuentas, a priori todo lo que haya bajo el Document Root del servidor ha de ser público, ya que para eso se ubica ahí. Evidentemente la teoría es una cosa y la práctica otra muy diferente: entre los ficheros de cualquier servidor no es extraño encontrar desde archivos de log - por ejemplo, del cliente FTP que los usuarios suelen usar para actualizar remotamente sus páginas, como WS/SMALL>_FTP.LOG - hasta paquetes TAR con el contenido de subdirectorios completos. Por supuesto, la mejor defensa contra estos ataques es evitar de alguna forma la presencia de estos archivos bajo el Document Root, pero en cualquier caso esto no es siempre posible, y si un atacante sabe de su existencia puede descargarlos, obteniendo en muchos casos información realmente útil para atacar al servidor (como el código de ficheros JSP, PHP, ASP...o simplemente rutas absolutas en la máquina), y una excelente forma de saber que uno de estos ficheros está ahí es justamente el Directory Indexing; por si esto no queda del todo claro, no tenemos más que ir a un buscador cualquiera y buscar la cadena `Index of /admin', por poner un ejemplo sencillo, para hacernos una idea de la peligrosidad de este error de configuración.

Además, en cualquier servidor web es muy importante el usuario bajo cuya identidad se ejecuta el demonio httpd: ese usuario no debe ser nunca el root del sistema (evidente), pero tampoco un usuario genérico como nobody; se ha de tratar siempre de un usuario dedicado y sin acceso real al sistema. Por supuesto, las páginas HTML (los ficheros planos, para entendernos) nunca deben ser de su propiedad, y mucho menos ese usuario ha de tener permiso de escritura sobre los mismos: con un acceso de lectura (y ejecución, en caso de CGIs) es más que suficiente en la mayoría de los casos. Hemos de tener en cuenta que si el usuario que ejecuta el servidor puede escribir en las páginas web, y un pirata consigue - a través de cualquier tipo de error (configuración, diseño del demonio...) - ejecutar órdenes bajo la identidad de dicho usuario, podrá modificar las páginas web sin ningún problema (que no olvidemos, es lo que perseguirá la mayoría de atacantes de nuestro servidor web).

Igual de importante que evitar estos problemas es detectar cuando alguien trata de aprovecharlos intentando romper la seguridad de nuestros servidores; para conseguirlo no tenemos más que aplicar las técnicas de detección de intrusos que veremos en el capítulo siguiente. Una característica importante de los patrones de detección de ataques vía web es que no suelen generar muchos falsos positivos, por lo que la configuración de la base de datos inicial es rápida y sencilla, al menos en comparación con la detección de escaneos de puertos o la de tramas con alguna característica especial en su cabecera.
next up previous contents
Siguiente: Sistemas de detección de Subir: Seguridad de la subred Anterior: Cortafuegos: Casos de estudio   Índice General
2002-07-15