O.S. fingerprinting como medida antispam

3 October 2008 at 18:24

Hay ocasiones en que el tema del spam me recuerda a una escalada armamentística, en la que las dos partes de un conflicto van evolucionando sus medios y técnicas para obtener ventaja sobre el otro. Un ejemplo de esta escalada en el campo del spam son los filtros bayesianos: hace ya un tiempo los sistemas antispam implementaron filtros bayesianos [Wikipedia], que básicamente son unos algoritmos que son capaces de “leer” los correos y puntuar cuan probable es que ese correo sea spam. Algunos spammers reaccionaron enviando los correos con una imagen en la que incluían el texto de manera que los filtros bayesianos no pudieran leerlo. Para combatir esta técnica, los sistemas antispam implementaron sistemas de reconocimiento de carácteres (OCR) para poder “leer” el texto contenido en las imágenes, a lo que los spammers reaccionaron modificando el fondo de las imágenes para hacer más difícil el reconocimiento. Etc.

En este post os voy a explicar una técnica para luchar contra el spam que he descubierto recientemente y como configurarlo.

Introducción

Esta técnica antispam sólo es útil si se implementa a nivel de servidor de correo, y se fundamenta en dos pilares:

  1. Como se puede suponer del título del post, uno de los pilares es la detección de la versión del sistema operativo del servidor remoto que está intentando entregar un correo a una de las direcciones que alojamos.
  2. El otro pilar es el hecho de que nadie en su sano juicio instalaría un servidor de correo sobre un Windows XP, ya que está destinado a estaciones de trabajo y no a servidores. Pero incluso así, la gran mayoría de spam proviene de Windows XP, que seguramente tendrán instalado un virus que los convierte en relayers.

Es decir, si somos capaces de determinar que correos entrantes nos los está enviando un Windows XP, lo podremos usar para diferenciar mejor el correo legítimo del spam.

Descripción técnica

El núcleo de esta técnica lo forman amavis, spamassassin y p0f. Seguramente el único que no os debe sonar es p0f y me imagino que la mayoría ya conoceréis el amavis, sistema de filtrado de correo, y el spamassassin, el sistema antispam por excelencia. p0f es un sistema de O.S. fingerprining pasivo. Básicamente es un sniffer que es capaz de identificar la versión del sistema operativo a partir de los paquetes TCP/IP que vé. Es decir, es similar a la opción -O del nmap, pero de forma pasiva.

La idéa es que cuando amavis vaya a filtrar un nuevo correo entrante, consulte de alguna manera al p0f para saber la versión del sistema operativo de la máquina remota y el spamassassin pueda tener en cuenta esa información para determinar si el correo es spam o no.

Instalación y configuración

Los prerequisitos son tener un servidor de correo que use amavisd-new y spamassassin. No voy a explicar como se instalan y configuran ya que depende del MTA que uséis y existen muchos how-tos (como este de Jaume Sabater [copia en Bulma]). En cuanto a la distribución, me centraré en una Debian que es lo que tengo por mano.

Instalación de P0F

Lo primero es instalar el p0f: aptitude install p0f (o apt-get install p0f, me da igual :-) )

Para la comunicación entre p0f y amavis, usaremos un programilla en perl que viene dentro del paquete de amavisd-new: p0f-analyzer (que se instala en /usr/sbin). Este programa espera recibir los datos del p0f por su entrada estandar y abre un puerto por el que el amavis le hace las consultas. Por defecto, p0f-analyzer escucha en todas las interfaces del servidor aunque implementa unas ACLs muy simples por las que sólo contesta a peticiones que le lleguen del localhost (127.0.0.1). Como a mi no me gusta tener servicios internos escuchando en todas las interfaces, cambie la línea 79 de

  bind(S, sockaddr_in($port,INADDR_ANY)) or die "bind: $!";

a

  bind(S, sockaddr_in($port,INADDR_LOOPBACK)) or die "bind: $!";

Las ACLs se controlan mediante el array @inet_acl que se define en la línea 70.

Si ejecutas /usr/sbin/p0f-analyzer sin parámetros, te da un ejemplo de uso que es el que yo utilicé:

  /usr/sbin/p0f -l 'tcp dst port 25' 2>&1 | /usr/sbin/p0f-analyzer.pl 2345

De esta manera, el p0f identificará las conexiones destinadas al puerto 25/tcp y el p0f-analyzer abre el puerto 2345 para recibir las consultas del amavis. Primera parte resuelta.

Configuración de amavis

El siguiente paso es configurar el amavis para que consulte al p0f-analyzer. Para ello debemos usar el parámetro de configuración $os_fingerprint_method. En el caso de Debian, modifiqué el fichero /etc/amavis/conf.d/50-user e incluí las dos líneas siguientes:

  $os_fingerprint_method = 'p0f:127.0.0.1:2345';
  $policy_bank{'MYNETS'}{os_fingerprint_method} = undef;

En la primera línea le indicamos donde puede consultar al p0f-analyzer y en la segunda que no use el p0f-analyzer para las máquinas de la red interna.

Finalmente reiniciamos el amavisd-new. Si hemos realizado los cambios en la configuración de forma correcta, en /var/log/mail.log deberíamos encontrar la línea que nos indica que ha activado la opción de OS_Fingerprinting:

  Oct  3 12:23:14 server amavis[29216]: OS_Fingerprint code  loaded

Ahora ya sólo falta que el spamassassin use la información que nos proporciona p0f.

Configuración de spamassassin

La forma que tiene el amavis para pasar la información que ha recibido del p0f al spamassassin es añadiendo la cabecera X-Amavis-OS-Fingerprint al correo. Esta cabecera no se añade al correo que recibirá el usuario, sólo se usa internamente entre el amavis y el spamassassin.

Como a mi me interesaba que todos los usuarios se beneficiaran de esta nueva técnica, modifiqué el fichero /etc/spamassassin/local.cf para que incluyera la siguiente configuración:

  #   Set score for different client OS
  #   Needs p0f-analyzer up and running
  header P0F_WindowsXP X-Amavis-OS-Fingerprint =~ /^Windows XP/
  header P0F_Windows   X-Amavis-OS-Fingerprint =~ /^Windows(?! XP)/
  header P0F_Unknown   X-Amavis-OS-Fingerprint =~ /^UNKNOWN/
  header P0F_Unix      X-Amavis-OS-Fingerprint =~ /^Linux|((Free|Open|Net)BSD)|Solaris|HP-UX|Tru64/

  score  P0F_WindowsXP 3.5
  score  P0F_Windows   1.7
  score  P0F_Unknown   0.8
  score  P0F_Unix     -0.5

Definimos cinco tests y les damos puntuaciones. Las puntuaciones de los tests no son aleatorias, me basé en las que se indican aquí pero las modifiqué un poco a mi gusto. Con estas puntuaciones le estamos indicando al spamassassin que es muy probable que los correos que le lleguen desde máquinas Windows XP sean spam, ya que le damos una puntuación de 3.5, mientras que los que le lleguen desde Unixes tienen una menor probabilidad de serlo y por eso le damos una puntuación de -0.5.

Para que se empiecen a aplicar los nuevos tests, si estamos ejecutando el spamassassin en modo daemon (spamd) deberemos reiniciarlo y si se ejecuta de forma interna al amavis, deberemos reiniciar este último.

A partir de ahora, el spamassassin debería tener en cuenta el sistema operativo de la maquina remota para puntuar los correos. Si tenéis configurado el amavis para que incluya en las cabeceras los tests del spamassassin, podéis buscarlo allí. Por ejemplo:

X-Spam-Status: Yes, score=9.25 required=4.5 tests=[BAYES_99=3.5,
    HTML_MESSAGE=0.001, P0F_Unix=-0.5, RCVD_IN_BL_SPAMCOP_NET=1.96,
    URIBL_AB_SURBL=1.86, URIBL_BLACK=1.955, URIBL_SC_SURBL=0.474]

Conclusión

La técnica de O.S. fingerprinting no es la panacea en la lucha contra el spam, pero es un complemento al resto de tests, un aspecto más que nuestro sistema antispam puede tener en cuenta para clasificar mejor los mensajes. Y por el trabajo que lleva configurarlo, creo que merece la pena.