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.
© 2002 Antonio Villalón Huerta