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.