
Lata de Spam
Si ya has pasado por varios intentos de compartir el spam en tu Blog te puede merecer la pena gastar algo de tiempo en leer este artículo que es necesariamente largo.
Haré un repaso general previo y luego comento en detalle mi última aventura defensiva, que espero termine mejor que las anteriores.
Empiezo comentando los recientes problemas con Geo Captcha:
Me las prometía muy felices después de instalar hace poco el Geo Captcha. Supuestamente bloquea los intentos de accesos por países. Además de un sistema captcha normalito, permite ir añadiendo a una lista los países que generan problemas. Lo que me ha resultado más útil ha sido su sistema de login que va registrando todos los intentos de acceso, (los que tienen éxito y los que no) Una excelente idea que muchos otros plugins antispam deberían copiar, porque la realimentación es imprescindible. Los spamers se adaptan a cada obstáculo y sus víctimas no podemos esperar encontrar un remedio definitivo y milagros. Lo suyo es estar preparado para adaptar la defensa a los nuevos tipos de ataques y eso requiere adquirir información de cada ataque.
Gracias al registro que ofrece Geo Captcha he podido verificar que alguien desde España intentó repetidamente insertar un comentario sin conseguirlo. Es decir su sistema de log me permitió darme cuenta de que Geo Captcha da falsos positivos antispam, lo cual me hizo buscar otro plugin anti-spam inmediatamente.
Ya sé que resulta un poco cínico mandar a paseo el captcha y pedir a otros que copien esta buena idea que me permitió descartarlo, pero es lo que acabo de hacer. (Soy así de majo).
Tengo que decir que conozco algunos plugins anti-spam muy efectivos, pero además de efectivos tienen que gustarme a mí (Además de majo, caprichoso que es uno).
Akismet o Automattic Kismet:
Es posiblemente el sistema más eficaz, pero funciona como un servicio de filtrado de spam. El filtro funciona mediante la combinación de información sobre el spam capturado en todos los blogs participantes, y luego usa esas reglas de spam para bloquear el spam futuro.
Akismet es ofrecido por Automatic, (la empresa que emplea a la mayoría de los principales desarrolladores de WordPress).
Akismet se inició el 25 de octubre de 2005. Al parecer, ha capturado más de diez mil millones de comentarios spam y de pings a partir de marzo de 2009. Si eres sensato usarás este sistema que a mí no me dio la gana usar, sólo porque no me gusta depender de un servicio para esto.
Situación actual del problema del spam:
Los spamers son una poderosa industria y hacen uso de gran cantidad de servidores repartidos por muchos lugares distintos a fin de que no puedan ser bloqueados por dirección IP. Los sitios que envían spam suelen corresponder a países donde pueden operar sin grandes problemas con la ley, pero curiosamente el pais que más spam envía es EE.UU., aunque la cosa podría cambiar: EE.UU inicia campaña contra los servidores de SPAM.
Se trata de un problema que nunca ha sido abordado seriamente, se le ha permitido crecer, y ahora es una poderosa industria.
Según SOPHOS el ranking sería el siguiente:
| Position |
Country |
Percentage of spam relayed |
| 1 |
United States |
|
| 2 |
China (including Hong Kong) |
|
| 3 |
South Korea |
|
| 4 |
Poland |
|
| 5 |
Germany |
|
| 6 |
Brazil |
|
| 7 |
France |
|
| 8 |
Russia |
|
| 9 |
Turkey |
|
| 10 |
United Kingdom |
|
| 10= |
Italy |
|
| 12 |
India |
|
| Others |
35.0% |
Los captchas tradicionales en los que hay que leer algo con letras distorsionadas o contestar a una pregunta formulada con texto, son en mi opinión más vulnerables que los que presentan otro tipo de imágenes mucho más variadas. Por ello, he decidido confíar (de momento) en Captchas basados en reconocimiento visual de imágenes.

Animal Captcha
Animal Captcha:
Son muchos los sistemas anti spam que llevo ensayados y hace algún tiempo, me interesó un captcha basado en imágenes que se llama Animal Captcha. No está disponible en forma de plugin para WordPress, razón por la cual no lo instalé. En la página de este captcha hice alguna sugerencia para mejorar el sistema que en principio me parece muy interesante.
Te muestra una foto de un animal (en la actual versión parece que han decidido mostrar dos) en la cual se ha realizado algún cambio que altera el color de alguna zona para impedir que un análisis del histograma de la imagen permita identificarla.
Para un robot antispam cada imagen es en realidad única lo cual lo hace muy robusto pero si el número de imágenes es limitado el sistema resulatará abordable por fuerza bruta, razón por la cual sospecho ahora manejan combinaciones de dos animales.
Un humano reconocerá la imagen sin problemas identificando al animal, pero un sistema automático no será capaz de hacer algo así. Los buscadores de imágenes de Google trabajan en el reconocimiento de imágenes, pero de momento los resultados son mediocres, y los spamers tampoco van a conseguir en un plazo razonable grandes adelantos en identificación de imágenes.
Animal captcha tiene el inconveniente de los sinónimos o de las definiciones incompletas, porque para una imagen puede haber varias palabras.
El sistema admite sinónimos y para una imagen tu puede poner ‘mono’, ‘simio’, pero alguien puede poner Mandril.
Para un jabalí podrían poner: cerdo, puerco, gorrino, marrano, guarro, cocho, cochino, cuino, o cualquiera de las anteriores seguida de la palabra ‘salvaje’.

Captura de pantalla de NotCaptcha
NotCaptcha v1.1:
Ahora tengo un nuevo sistema, que parece prometedor por varias razones. Se llama NotCaptcha. A pesar de lo que pudiera deducirse por su nombre, sí es un sistema captcha.
Usa imágenes y esto permite personalizar el captcha fácilmente actualizando la galería de imagenes que usa, y dificultar la labor de los spamers.
Este sistema (NotCaptcha) aparece con dos sistemas de representación visual bastante distintos dependiendo de que tengas habilitado el uso del JavaScript en el navegador o no. El caso es que en cualquiera de ambos casos el nivel de dificultad para un spamer será el mismo.
Puedes comprobarlo tú mismo aquí antes de que me canse de este captcha y lo cambie.
Es broma, seguro que este captcha me durará toda la vida. (Me suicido si este también falla).
Acabo de instalar (NotCaptcha) y a diferencia de Animal captcha no pide identificar nada. Hace que un humano identifique cual es la posición correcta de una imagen que puede aparecer girada.
Considero que este captcha tiene varias vulnerabilidades (supongo que todos las tienen), pero lo que me interesa de un sistema así, es que es fácilmente mejorable y cada cual puede hacer distinto tipo de mejoras. No sé si es muy prudente compartir mis estrategias antispam, pero de momento estoy muy satisfecho con lo logrado y no me resisto a compartirlo. A fin de cuentas basar la seguridad de algo en un secreto es muy poco ambicioso. Donde esté un buen algoritmo que se quiten los secretos.
Tuneado de NotCaptcha:
La principal vulnerabilidad que encuentro a NotCaptcha es que a la imagen en posición normal se la aplican giros con ángulos que delatan cual es la posición original. Los ángulos de giro a partir de la posición correcta son: 0, 60, 90, 135, 180, 225, 270, 300.
Es decir, la imagen la imagen girará 30 grados salvo antes y después de la posición correcta, en cuyo caso gira 60 grados. Puede que la intención fuera lograr que las imágenes que están giradas casi en posición correcta no se confundan con la posición correcta, pero todos los ángulos de giro han de ser idénticos para no dar pistas al spamer que lo único que necesitaría sería calcular cuanto va girando la imagen en cada caso.
Quede claro que mi osadía sacando faltas a un excelente programa no me convierte en experto programador en php, pero también me he atrevido a retocar los fuentes.
El problema señalado es fácil de solucionar:
Busca en el plugin el fichero ‘lib/notcaptcha_config.php’. Si no lo has hecho ya, debes editar la clave que aparece y poner cualquier otra.
# $notcaptcha['notcaptcha_key'] = “sdlkhg9238450ehfjksdf“; # change as password for coding data
Más abajo sustituye los ángulos de giro, que vienen como:
# $notcaptcha['notcaptcha_angles'] = array(0, 60, 90, 135, 180, 225, 270, 300);
A) Puedes usar igualmente ocho giros:
$notcaptcha['notcaptcha_angles'] = array(0, 45, 90, 135, 180, 225, 270, 315);
B) o puedes añadir un giro más (no hay espacio en la plantilla para un décimo usando un navegador sin javaScript):
$notcaptcha['notcaptcha_angles'] = array(0, 40, 80, 120, 160, 200, 240,280,320);
Otro parametro importante que conviene tocar es el tamaño con el cual se visualizarán las imágenes que generalmente será menor que el tamaño de las imágenes de la galería, yo lo he aumentado a 60.
# NOTCAPTCHA image size
$notcaptcha['notcaptcha_imagesize'] = 60;
Tal y como viene NotCaptcha en su versión 1.1 las posiciones de cada imagen son ocho y el número de imágenes que hay que voltear son tres.
Esto frente a un ataque por fuerza bruta representa 8³ = 512 intentos. Son bastantes, pero un atacante puede optar por hacer repetidos intentos intentando adivinar con algún sistema imperfecto. En ese caso necesitará muchos menos intentos. Supongamos que de cada imagen en lugar de necesitar un promedio de 8 intentos le baste con cuatro. En este caso el número de intentos totales que necesitaría para reventar el captcha sería 4³=64. ¡Sólo 64 intentos! (Eso de criticar lo que hacen otros se me da muy bien).
Yo he aumentado el número de posiciones angulares a nueve y he añadido una imagen más a girar . Esto es algo más complicado de hacer y sería entretenido de explicar. Lo que haré será dejar los fuentes modificados, cosa que no podría hacer si este plugin no fuera GPL.
Es decir, con las modificaciones efectuadas por mí, un ataque por fuerza bruta necesitaría 9^4= 6561 intentos. Supongamos que de cada imagen en lugar de necesitar un promedio de 9 intentos le baste con 4,5. En este caso el número de intentos totales que necesitaría para reventar el captcha sería 4.5^4=410 intentos. Tampoco son demasiados intentos para un spamer, así que hay que buscar imágenes que no den muchas pistas.
Por ejemplo: No me parece recomendable usar imágenes con simetría bilateral, ni imágenes con muchos colorines, ni imágenes con silueta reconocible en un fondo plano o transparente, ni imágenes que tengan líneas verticales u horizontales. Cualquiera de estas cosas pueden dar pistas a un programa.
Lo de usar tonos grises queda algo feo, o puede que incluso muy feo, razón por la cual y después de algunas pruebas lo voy a dejar en color. Si me revientan el captcha lo pasaré a grises. Los captchas son generalmente incómodos, hay que ponerse en la piel del usuario pero también en la piel del spamer.
¡Atención! Pasamos a modo paranoico.
Los spamers pueden usar sofisticados sistemas expertos para analizar imágenes, que se basen en histogramas de distribución de colores y otro tipo de cosas. De esa forma terminarían detectando reglas muy eficaces. (Estoy usando ahora colores, y no soy amigo de secretos, pero tampoco es cuestión de dar buenas ideas a los espamers, así que yo sé lo que me digo).
El mejor captcha para mí es aquel que se deja tunear (personalizar y mejorar) y con este estupendo captcha (al cual me permití sacar un montón de deficiencias) me ha sido bastante fácil introducir mejoras.
Para evitar efectos silueta, usaré fotos a las cuales les pongo una máscara dejando una imagen circular sobre un fondo blanco (el fondo puede ser de cualquier otro color). La razón es que un círculo girado, continua siendo un círculo y evitamos dar pistas. Primero recorto la foto en forma cuadrada usando gthumb. Hay que tener cuidado al recortar de que no queden detalles importantes en las esquinas que se perderían al aplicar la máscara circular. Luego aplico la máscara circular usando composite y convert de ImageMagick dentro de un script que me procesa todas las fotos previamente recortadas en cuadro.
Es un script muy simple:
#!/bin/bash
mkdir img_captchas
for I in `ls *.jpg`
do
echo $I
composite -geometry 90x90 -compose over mascara.png $I /tmp/out1.png
# convert -modulate 100%,0%,50% /tmp/out1.png img_captchas/$I
cp /tmp/out1.png img_captchas/$I # en color
done
He comentado la línea de convert que servía para pasar a grises la imagen y la he sustituido por una simple copia del fichero temporal generado por composite. La imagen mascara.png es un png blanco con un circulo transparente en el centro que se superpone sucesivamente a cada imagen. No todas la imágenes son aptas para usarlas en este captcha, pero este sistema permite usar una enorme variedad de imágenes. He usado fotos mías, de las cuales puede que reconozcas alguna porque pertenecen a la colección que salen al azar en la parte derecha de mi Blog.
(Esto último ha sido un comentario que me podía haber ahorrado, porque ahora los espamers disponen de imágenes patrón donde buscar la verticalidad, pero he reflexionado sobre ello y creo que la pista es muy poco valiosa. Tengo muchas fotos, y las pocas que uso aparecen muy recortadas, hay que localizar no solo la foto sino la zona de la foto, y el tamaño del recorte que es siempre cuadrado pero están recortadas a mano con tamaños diferentes).
Para encadenar 12 imágenes en una sola tira he usado nuevamente la utilidad convert en un nuevo script, append_img.sh
#!/bin/bash
encadena_tira (){
NUMTIRA=$1
shift
echo $*
FI=$1
shift
for J in $*
do
FI="$FI sep.png $J"
done
convert +append $FI fotos_${NUMTIRA}_12x90.png
}
ls *.jpg
typeset N=0
for I in `ls *.jpg`
do
let N=N+1
if [ $N -lt 13 ]
then
S1="$S1 $I"
elif [ $N -lt 25 ]
then
S2="$S2 $I"
elif [ $N -lt 37 ]
then
S3="$S3 $I"
elif [ $N -lt 49 ]
then
S4="$S4 $I"
elif [ $N -lt 61 ]
then
S5="$S5 $I"
else #
S6="$S6 $I"
fi
done
encadena_tira 1 $S1
encadena_tira 2 $S2
encadena_tira 3 $S3
encadena_tira 4 $S4
encadena_tira 5 $S5
El script construye la lista de nombres de ficheros a encadenar entre los cuales se intercala una imagen negra de un sólo pixel de ancho a modo de separación entre imágenes tal y como viene la plantilla de NotCaptcha.
La concatenación ocurre en la sentencia ‘convert +append $FI fotos_${NUMTIRA}_12x90.png’
Cometarios finales:
La reacción inicial que provoca este NotCaptcha tuneado por mí, puede ser de rechazo (como la mayoría de los captchas). En el caso de las imágenes que no aparecen derechas muchas veces no se reconocen (penarás ¿que demonios es esto?). Pese a ello es fácil dar con la posición buena al primer intento. Creo que la mayoría de las persona resolverán el captcha a la primera, aunque no podré verificarlo porque no se hace un registro de los intentos realizados como en GeoCaptcha.
EE.UU inicia campaña contra los servidores de SPAM
Si este artículo te ha sido de utilidad dime en el comentario si este captcha te parece demasiado antipático. Si por el contrario no te ha interesado y además odias el maldito NotCaptcha, te recuerdo que el 99,9% de la culpa es del autor original que no he mencionado hasta ahora, y que se hace llamar WebJema. Yo tan sólo me he aprovechado miserablemente de su código cedido gratuitamente a la comunidad bajo licencia GPL, para modificarlo, usarlo, y criticarlo.
Por cierto, querido lector ¿Eres realmente un ser humano?
PD 29-enero-2010:
En vista de que ya no me entra spam pero ha bajado el número de comentarios, he optado por dulcificar al máximo este Captcha haciendo más fácil la vida a mis visitantes.
Creo que ni siquiera lo intentan porque a primera vista parece más difícil de lo que es en realidad, pero no estoy en disposición de discutir eso. Sólo lo van a usar los usuarios que lo consideren aceptable, así que he reducido las imágenes a aquellas que son más obvias, he aumentado el tamaño de visualización de la imagen y he reducido el número de posiciones a seis. Esto me permite mostrar las imágenes con un tamaño mayor. Conservo las cuatro muestras.
He traducido al español el mensaje que informa del fallo en la prueba.
He encontrado un nuevo fallo. Las imágenes no salen de forma completamente aleatoria. Intenté solucionarlo poniendo muchas imágenes en una sola tira de imágenes, para minimizar las coincidencias pero estas continuaban apareciendo con demasiada frecuencia. Analizando el código compruebo que se usa como función aleatoria la función time que devuelve el número de segundos transcurridos desde 1-enero-1970. Algo que agún hacker espabilado que estudie el código puede aprovechar. Un segundo es mucho tiempo y por esa razón salían imágenes segidas iguales, incluso con el mismo ángulo.
Esto se soluciona editando not-captcha.php y situando la instrucción ‘srand(time());’ como primera línea ejecutable y sustituyendo todas las llamadas a la función ‘time()’ por la llamada ‘srand()’.
Si se cambia el tamaño de la imagen sin más se producirá un solapamiento de las mismas. hay que ampliar la anchura de captchablock.
Los tamaños de la imágenes como siempre se cambian en ‘notcaptcha_config.php’ y ahora quedan de la siguiente forma:
#6×97 angles of images & # NOTCAPTCHA image size
$notcaptcha['notcaptcha_angles'] = array(0, 60, 120, 180, 240,300);
$notcaptcha['notcaptcha_imagesize'] = 97;
Todo esto lo comento para el que quiera trastear.
PD 3 de feb-2010 ¡AVISO IMPORTANTE!:
He descubierto un fallo aun más importante. Resulta que desde el navegador Mozilla Firefox (el más usado) no funciona el cursor para girar las imágenes. Me he dado cuenta solo gracias al comentario de Snake al cual ya he agradecido su ayuda.
Yo uso Firefox, pero las pruebas las hacía desde Opera para que no me reconociera como administrador por culpa de las cookies.
He optado por dejar solo el modo de funcionamiento habilitado para navegadores sin JavaScript. En programación el demonio se esconde en los detallitos insignificantes. Ahora supongo que funcionará bien para todo el mundo. A mi hijo le gusta más este sistema que el anterior con el uso del cursor.
No voy a cambiar de sistema porque me parece que la idea es muy buena y admite mejoras. Si me atacan puedo reaccionar buscando imagenes distintas. Los humanos son muy superiores en reconocimiento visual a las mejores máquinas, y eso quiero explotarlo.
Lo que debería hacer ya que he llegado hasta aquí es incluir algún sistema de login para registrar en BD los intentos de comentar, para ayudar al diagnóstico del funcionamiento del sistema de captcha, pero la programación me quita demasiado tiempo. No sé si lo haré.
Esto parece la historia interminable, pero de lo que yo aprenda con ella también pueden aprender los demás.
Lo dicho ¡Maldito spam y malditos captchas!