Credit image

¿Te gusta el diseño web? ¡Echa un vistazo a la documentación de LenguajeCSS.com!

Spam bots en blogs y como detenerlos

Estudio con recomendaciones para construir un sistema que bloquee accesos de spammers. Trabajaremos sobre el fichero .htaccess de nuestro Apache, donde bloquearemos según la naturaleza de los spam bots.

Uno de los mayores problemas en un blog se da cuando se empieza a recibir comentarios de spam que llenan nuestros artículos de mensajes no deseados: casinos, pastillas de viagra y hasta en algunos casos spyware o falsos antivirus.

Cualquiera podría pensar, que bastaría con bloquear los accesos a la página web del spammer y listo. El problema es que, usualmente, no se trata de un ataque individual, sino de una amenaza mayor, un ataque distribuido.

Este tipo de ataques, las llamadas redes de bots están formadas por cientos, miles (o más) de ordenadores que pertenecen a personas individuales e independientes, infectadas (sin ser conscientes de su infección ni de las consecuencias) por malware o troyanos que convierten su ordenador en un zombie manipulable.

Bloquear miles de accesos de diferente naturaleza (pais, navegador, proveedor...) se convierte en una tarea muy complicada y aunque existen varios sistemas para bloquear y filtrar estos ataques, voy a proponer un método distinto por varios motivos que afectan a la mayoría de sistemas:

  • Producen un consumo alto de recursos del servidor.
  • Producen falsos positivos (comentarios legítimos como spam).
  • Dependen de servicios de terceros.
  • En algunos casos es necesaria la moderación.
  • No actuan sobre el foco original del problema.

Es por ello, que he realizado un pequeño estudio para crear el siguiente informe con varias recomendaciones para construir un sistema que bloquee accesos de spammers. Trabajaremos sobre el fichero .htaccess de nuestro Apache, donde iremos bloqueando según la naturaleza de los spam bots.

NOTA: Como se verá posteriormente, en lugar de bloquear la petición haré una redirección a una carpeta llamada malware con la variable GET ident seteada a una determinada cadena. En esa ruta existirá un script que registrará ciertos datos de los accesos (ip, host, pais, referer, petición, agente de usuario...) para mantener unas estadísticas de los spambots bloqueados, su naturaleza y descubrir nuevos patrones, para luego mostrar un error 404 y simular que no existe:

if (isset($_GET['ident'])) {
$log = fopen($_SERVER['DOCUMENT_ROOT'] . "/malware/spam.log", 'a+');
$msg = $_GET['ident'] . ' ' . date('Y-m-d H:i:s') . ' ' . $_SERVER['REMOTE_ADDR'] . ' ' . $_SERVER['HTTP_USER_AGENT'] . "\n";
fwrite($log, $msg);
fclose($log);
}
header("HTTP/1.0 404 Not Found");
exit(0);

Si tu intención es sólo bloquearlos, y no te preocupan otras cosas como el registro de accesos, reemplaza la línea RewriteRule de los siguientes códigos por la siguiente:

RewriteRule .* - [F]

Esto, hará que los bloquee con un código HTTP 403.

EDITADO: Como bien apunta ajmacias en los comentarios, dentro de la carpeta malware hay que desactivar las redirecciones para evitar dejar el Apache en un bucle infinito. Para ello en el fichero .htaccess de la carpeta malware escribimos:

RewriteEngine off

Si no sabes de que estoy hablando, te recomiendo echar un vistazo a la chuleta Emezeta ModRewrite Card.

La misteriosa flecha

Probablemente se trate de un spambot mal configurado, pero lo cierto es que varias redes de botnets tienen las peticiones de sus spambots de modo que se les «escapa» un patrón poco común en peticiones HTTP.

210.126.72.42 - - [19/Sep/2008:04:53:10 -0700] "GET /tag/consumo%2Bcpu/ GET http://www.emezeta.com/tag/consumo%2Bcpu/ [0,30618,48635] -> HTTP/1.0" 301 263 "http://www.emezeta.com/tag/consumo%2Bcpu/ GET http://www.emezeta.com/tag/consumo%2Bcpu/ [0,30618,48635] ->" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Crazy Browser 2.0.0 Beta 1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)"

Lo aprovecharemos para bloquearlo, introduciendo en el fichero .htaccess lo siguiente:

RewriteCond %{SERVER_PROTOCOL} " -> " [OR]
RewriteCond %{REQUEST_METHOD} " -> " [OR]
RewriteCond %{HTTP_REFERER} " -> "
RewriteRule .* /malware/?ident=arrow-spam

La IP oculta

Algunos bots se aprovechan de ciertos trucos para evitar ser identificados. Uno de ellos es aprovechar servidores Apache con HostnameLookups activado (resolver las DNS inversa / hostname) de la IP del usuario.

Esa información suele ser una cadena que da información acerca del ISP, IP enmascarada u otros datos. No todos los usuarios deben tener DNS inverso, es más, los spammers acostumbran no tenerlo para hacer más dificil su identificación.

En este caso, el spammer camufla la IP en un DNS inverso que es un único punto (.) buscando la confusión y que no se registre la IP en los logs, ni se tenga forma de resolverla.

RewriteCond %{REMOTE_HOST} ^\.$
RewriteRule .* /malware/?ident=dot-spam

El spammer no canónico

Este es bastante ingenioso. En múltitud de casos, lo ideal es tener nuestra página web bajo una URL canónica, o lo que es lo mismo, que sólo podamos acceder a una dirección unívoca.

Un ejemplo sería que al entrar en www.emezeta.com y a emezeta.com sólo una de las dos direcciones prevalezca. Con el siguiente código se puede conseguir (prevalece con www):

RewriteCond %{SERVER_NAME} ^sitioweb.com$ [NC]
RewriteRule ^(.*)$ http://www.sitioweb.com/$1 [R=301]

Muchos spammers se «inventan» que vienen (referer) del sitio web al que están atacando, para que el servidor crea que es un usuario legítimo. Claro que, si tenemos esta característica canónica, parece que casi todos los spammers se olvidan de incluir el «www». Por lo tanto, si un usuario viene de otra página debe tener www, en caso contrario (no se puede dar), es un spammer.

RewriteCond %{HTTP_REFERER} "^http://sitioweb.com/" [NC]
RewriteRule .* /malware/?ident=canonical-spam

El falso agente

Un descuido común en varias redes de botnets es el especificar la previa cadena User-Agent: como agente de usuario. Probablemente se trate de un error de programación en ciertos bots, pero sin duda, podemos utilizarlo para detectar spam bots.

RewriteCond %{HTTP_USER_AGENT} "^User-(A|a)gent: "
RewriteRule .* /malware/?ident=fakeuser-spam

Agentes malignos

Uno de los filtros más sencillos pero, sorprendentemente, de los más potentes y efectivos es el bloquear accesos simplemente por su Agente de Usuario (User Agent). Pero ojo, hay que ser muy selectivo y sólo bloquear a los agentes que se esté completamente seguro de que son spam bots.

Por ejemplo, lwp-request (comando de UNIX), WWW-Mechanize o libwww-perl (módulos para Perl) y Jakarta Commons-HttpClient (extensión Jakarta) son algunos de los sistemas que, aunque no fueron concebidos para crear este tipo de malware, los hacen un sistema muy sencillo (y frecuente) para crear spam bots.

RewriteCond %{HTTP_USER_AGENT} "^(Java|lwp-request|WWW-Mechanize|libwww-perl|Attentio|ePochta_Extractor|Jakarta Commons-HttpClient)/"
RewriteRule .* /malware/?ident=badagent-spam

Sistema antispam CSS

El ya famoso sistema antispam del campo oculto por CSS ha resultado ser una auténtica y efectiva solución para el spam en blogs, que podemos combinar perfectamente para registrar los bots bloqueados por este sistema.

Para registrar estos accesos de spam bots, deberemos hacerlo desde PHP, ya que modrewrite no sirve para capturar variables GET / POST.

Esto puede plantear un problema, ya que no se puede hacer un include de un fichero PHP con variable GET por parámetro, como haciamos con ident. Sin embargo, existe una pequeña triquiñuela que podremos utilizar:

$_GET = array();
$_GET['ident'] = 'css-antispam';
include($_SERVER['DOCUMENT_ROOT'] . '/malware/index.php');

Como se puede ver, podemos modificar a nuestro antojo el array asociativo $_GET que conservará los cambios para la inclusión.

Resultados

Y ahora viene lo interesante. Después de menos de una semana de pruebas, los resultados son bastante tentadores, así que los muestro a continuación:

# wc -l spam.log
2476 spam.log

2.476 accesos de spam bloqueados.

# cat spam.log | cut -d" " -f1 | sort | uniq -c | sort -n
49 dot-spam
250 canonical-spam
593 savecom-antispam
718 badagent-spam
866 mail-antispam

Por las categorías anteriormente descritas. En mi caso he diferenciado varios formularios de otros (savecom para los comentarios y mail para el envío de email).

# cat spam.log | cut -d" " -f2 | sort | uniq -c | sort -n
44 2008-09-17
377 2008-09-18
417 2008-09-22
488 2008-09-19
571 2008-09-21
579 2008-09-20

Los accesos de spammers separandolos por días. Vemos que corre alrededor de una media de 500 peticiones de spam diarias, teniendo en cuenta que muchos de los rangos de IP que reiteraban fueron bloqueados por iptables.

# cat spam.log | cut -d" " -f4-5 | sort | uniq -c | sort -n | tail -10
35 94.102.49.14 -
36 89.179.91.33 -
49 206.71.157.116 -
58 162.114.40.33 ldyddy1.ky.gov
59 200.63.42.136 -
63 94.102.49.34 -
64 85.12.25.66 -
76 67.212.189.146 server2.yourdomain9.com
118 65.98.62.90 muk.nameserver5.info
621 94.100.29.250 -

Aquí los accesos de spammers más frecuentes, agrupados por IP y hosts. Este apartado es bastante interesante, puesto que se puede comprobar que la mayoría de spammers tienen servidores web instalados sin configurar o con posibles vulnerabilidades. Probablemente sus dueños no saben que están infectados.

Mi intención posterior es crear un script que permita crear informes acerca de las peticiones mas frecuentes de spam y se envíen al email abuse de su ISP de forma automática. Con esto no sólo estaríamos evitando el spam en nuestro servidor, sino ayudando a reducirlo y prevenir a los «zombies».

# cat spam.log | cut -d" " -f6 | sort | uniq -c | sort -n | tail -10
42 Spain
51 Poland
66 China
78 Russian_Federation
80 Korea,_Republic_of
87 Netherlands
88 Japan
106 Germany
556 United_States
868 -

Finalmente, se puede añadir más información acerca de los spam bots que en el ejemplo superior. Por ejemplo, con ayuda del sistema de geolocalización para Apache puedo saber el pais de origen de los spam bots.

Escrito por Manz, el , en webmasters. Comentarios recibidos: 12.

12 comentarios de lectores
mark2877
mark2877
1

muy buen articulo, en verdad esto de los bot si es un fastidio que solo te dan dolores de cabeza, y claro con las pc tambien las hacen muy lentas....

  • 1
ajmacias
ajmacias
2

Ole! Genial el articulo! Solo una cosilla... He usado "RewriteCond %{REQUEST_URI} !^/malware/.*" como condicion adicional y evitar un bonito error 500 al aparecer esto en el log de errores de apache: "Request exceeded the limit of 10 internal redirects due to probable configuration error." De este modo, me queda asi: RewriteCond %{REMOTE_HOST} ^\.$ RewriteCond %{REQUEST_URI} !^/malware/.* RewriteRule .* /malware/?ident=dot-spam ¿Es correcto? No se... me da que es una chapucilla de las mias... :)

Manz
Manz
3

Cierto. Detalle importantísimo que se me olvidó comentar. Dentro de la carpeta malware hay que desactivar las redirecciones de ModRewrite para que no se quede en un bucle infinito (ya que los codigos modrewrite del artículo se aplican a la carpeta raiz y a sus subdirectorios). @ajmacias: Lo haz hecho correctamente, gracias por el apunte porque tienes toda la razón. Lo que hay que hacer es editar el fichero .htaccess de la carpeta malware y escribir: RewriteEngine off Con esto evitarás las redirecciones dentro de esa carpeta. La solución que aportas es otra manera que soluciona perfectamente el problema. Por cierto, ajmacias, comentanos tus impresiones, si utilizas además el método antispam del campo oculto y que tal te van los resultados del método antispam de este artículo.

ajmacias
ajmacias
4

Vaya... no se me ocurrió meter otro .htaccess :-S Pues es sistema antispam de CSS lo implemente hace muucho tiempo... Creo que muy poquito tiempo despues de leerlo por aqui. Efectividad? Hasta hoy dia 100% libre de spam en comentarios. Evidentemente el tráfico de mi web no es el que puedas tener tú, pero aún así el método funciona sin problemas. Ya os contaré que tal queda el spam.log, aunque yo necesitaré más tiempo para que salga algo! ;)

Diana Rodriguez
Diana Rodriguez
5

Buen día, José Román. Muy bueno, y útil, esta entrada. Me viene como anillo al dedo para un tema que me tiene ocupada y preocupada. Saludos, Diana

ajmacias
ajmacias
6

Bueno... el sistema, de momento, funciona "de arte". Lo que más abunda en mi caso es la categoria de "badagent", destacando sobre todo "libwww-perl/5.812" y "libwww-perl/5.805". También hay algún que otro "Jakarta Commons-HttpClient/3.0", pero estos son muchos menos. Lo más curioso que he pescado ha sido en la categoría "canonical", identificado como: Mozilla/5.0 (compatible; MSIE or Firefox mutant; not on Windows server; +http://ws.daum.net/aboutWebSearch.html) Daumoa/2.0 Me ha hecho gracia eso de "MSIE or Firefox mutant"...

Manz
Manz
7

El spam que proviene de agentes que utilizan las librerias de acceso web via perl son muy frecuentes. Una cosa importante es que dentro del recurso canonical, la mayoría suele ser mecanismos automatizados y robots, aunque no tiene porque ser spam obligatoriamente. No obstante, un flujo masivo de accesos suele indicar que se trata de un sistema spammer. Saludos,

mario garcia
mario garcia
8

necesito comprar un servidor para mi empresa y no se mucho de computacion, por favor manden a mi mail ofertas. gracias

villanueva
villanueva
9

genial muy bueno me sirve

alberto
alberto
10

Estoy interesado en reducir el tráfico malicioso a mi blog y me interesaría aplicar la solución que aquí se propone, pero no se cómo hacer la "redirección a una carpeta llamada malware con la variable GET ident seteada a una determinada cadena" ¿Dónde y como coloco el script? ¿tengo que reflejarla ruta del script en las líneas que se incluyen en el archivo .htaccess? Muchas gracias y felicidades por el blog, se aprende mucho, pero cuando uno llega con ciertas limitaciones se da cuenta de que hay muchas lagunas de conocimiento que rellenar.

Marcs
Marcs
11

No entiendo la primera parte del code: if (isset($_GET['ident'])) { $log = fopen($_SERVER['DOCUMENT_ROOT'] . "/malware/spam.log", 'a+'); $msg = $_GET['ident'] . ' ' . date('Y-m-d H:i:s') . ' ' . $_SERVER['REMOTE_ADDR'] . ' ' . $_SERVER['HTTP_USER_AGENT'] . "\n"; fwrite($log, $msg); fclose($log); } header("HTTP/1.0 404 Not Found"); exit(0); no dejo este codigo, creo un nuevo index.php? donde lo dejo en la carpte malware? lo mismo que el anterior no se donde dejar este codigo (Sistema antispam CSS): $_GET = array(); $_GET['ident'] = 'css-antispam'; include($_SERVER['DOCUMENT_ROOT'] . '/malware/index.php');

monica hernandez
monica hernandez
12

bueno yo tengo un chat en el formato tinychat y hay un peruano que nos pone spam dia y noche ya no nos deja chatear empaz quisiera ayuda para saber como eliminar eso plisss

Publica tu opinión

Si lo deseas, puedes utilizar el siguiente formulario para publicar tu opinión o responder a alguna de las existentes:

Previsualización

Aquí se previsualizará su comentario. Revise que sea correcto antes de publicarlo.