Captchas al alcance de todos

Joel Ibaceta
joelibaceta
Published in
4 min readDec 20, 2018

--

Los captchas surgen como respuesta a la necesidad de evitar la automatización, validando que quien interactúa sea un humano y no un script o bot (una version automatizada del test de Turing).

Pero con la difusión de herramientas que hoy nos permiten abstraer la parte matemática y teórica, sobre algoritmos para el reconocimiento de patrones, visión computarizada, redes neuronales entre otros, no es extraño imaginar que un desarrollador cualquiera con un poco de imaginación pueda burlas captchas.

Por esto hoy en día, diseñar un challenge de este tipo ya no es una tarea trivial sino que deben considerar alternativas o en su defecto acompañarse de otros métodos.

Me preguntaba, ¿Cuántos están conscientes de esto? ¿Cuántos sitios en producción usan captchas sin la complejidad necesaria para representar un challenge real?

Para responder esta interrogante me propuse construir una pequeña solución usando únicamente herramientas de fácil acceso, que no requieran skills técnicos avanzados que nos permita vulnerar captchas no muy elaborados.

1. Elegir un sitio web

No es difícil encontrar hoy un sitio web que implemente captchas sin mucha ciencia, para este caso encontré un portal peruano con un captcha que se veía poco complejo y cuyo patrón se repite con pocas variantes en varios sitios gubernamentales de pais.

2. Obtener la imagen

En esta etapa decidí implementar un plugin de chrome, el cual permite inyectar fácilmente codigo javascript en cualquier sitio web con solo declararlo en el archivo manifest.json.

Podemos extraer la imagen usando un elemento canvas y obtener un string en base64 con el contenido y posteriormente enviarlo a algún servidor que se encargara del procesamiento de la imagen.

var img = document.getElementById("captcha_image");

var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var imageData = canvas.toDataURL();

3. Limpiar la imagen

Una vez recibida la imagen desde el servidor podemos limpiar un poco la imagen con el fin de poder eliminar elementos extraños y poder procesarlo con un OCR genérico, una lógica simplificada se reduce a identificar los pixeles con un color dentro de un rango en especifico descartando todo lo demás, en este caso, por ejemplo, solo considerar los caracteres en rojo.

from PIL import Imagedef process_image(image_path):    im = Image.open(image_path)
pix = im.load()
w, h = im.size

for i in range(w):
for j in range(h):
r,g,b,a = pix[i, j]
if r <= g or r <= b:
pix[i, j] = (255, 255, 255, 255)
new_name = image_path.replace('png', 'tiff')
im.save(new_name)

4. Usar un OCR generico

Es cierto que podríamos entrenar un modelo para mejorar la precisión de un OCR sobre la fuente y el rango limitado de caracteres para nuestro captcha, pero decidí probar con Tesseract como OCR en su configuración por defecto.

tesseract imageToSave.tiff stdout --oem 3 --psm 8

Como podemos ver los resultados son bastante aceptables.

5. Automatizar el proceso

Para poder hacer esto de forma automática, implemente un pequeño servidor flask que reciba la imagen enviada por la extension de chrome, procesando el captcha con tesseract y devolviendo la respuesta final hacia la extension para manipular el DOM completando la caja de texto con el resultado del captcha.

Como podemos ver, todo va bien y el desarrollo no toma mas de unos minutos con la ayuda de google y un poco de imaginación, es tecnología que esta muy cerca de cualquier usuario curioso, veamos unos cuantos sitios mas.

--

--

Joel Ibaceta
joelibaceta

CTO at Kwema Inc. #developer #traveler #investor #packtauthor #fintechexpert #entrepeneur Github: https://github.com/joelibaceta, Instagram: joelibaceta