Lo primero y PRIMORDIAL es analizar lo que se tiene al enfrentarse a un captcha… hay de muchos tipos, FORMAS, sabores y COLORES. Principalmente los captchas con “formas” son los mas difíciles de abordar y donde se requiere la IA. Al enfrentarnos a captchas tenemos que tener en cuenta los siguientes factores que dependiendo de cada uno de ellos sera como se aborde el reto:
- Tipografia
- Colores
- Ruido
- Forma
- Angulos y posiciones
El captcha en cuestion es el siguiente:
El reto es limpiar la imagen…en este punto ustedes se preguntaran…¿Por que carambolas limpiar la imagen? Pues esto es por que muchos programas de OCR son mas precisos al tener una imagen limpia…
El captcha contiene una “vulnerabilidad” en la elección de colores la cual lo hace sumamente fácil de limpiar…¿Pueden verla?…Exacto…usan un fondo único y las letras no contienen este color…Osea: EL fondo es de color negro y las letras no contienen el color negro…
¿Y? – Fácil…¿Qué pasaria si…? Realizamos un programa que CONVIERTA TODO EL COLOR NEGRO EN BLANCO Y TODO LO QUE NO SEA NEGRO EN NEGRO… De este modo obtendríamos una imagen con fondo blanco y letras negras (O en teoría eso se quiere)
Shell Script para limpiar la imagen
Normalmente para esta tarea haría un script en PHP, pero descubrí/invente una forma para hacerlo desde bash…Y se las quiero compartir. Es por ello que lo haré desde bash…Por que muchos creen que para hacer esto es imposible en bash, ya que no hay una librería que lo haga…Y es cierto, pero nos apoyaremos de Imagemagick y todo el poder de bash.
El simple script que realice para esta tarea es el siguiente:
Brevemente explicare que hago:
Obtengo el tamaño de la imagen y lo guardo en variables:
1
2 3 |
pixelaje=$(convert -identify $image /dev/null | awk '{print $3}')
let px_x="$(echo $pixelaje | cut -d"x" -f1 | tr -d "\n")" let px_y="$(echo $pixelaje | cut -d"x" -f2 | tr -d "\n")" |
Creo un archivo de texto con la configuración que Imagemagick requiere para convertir un archivo de texto con pixeles a una imagen…La primera linea le dice de cuanto por cuanto sera la imagen y el valor máximo del color que se usara.
1
|
echo "# ImageMagick pixel enumeration: $px_x,$px_y,255,srgb" >
$txt_out |
Empiezo a recorrer la imagen.
1
2 |
for ((y=0;y<$px_y;y++));do
for ((x=0;x<$px_x;x++));do |
Obtengo el valor RGB del pixel.
1
|
rgb=$(convert "$image"[1x1+$x+$y] txt: | grep "(.*)" -wo |
cut -d ")" -f1 | tr -d "(" | tr -d "\n" | tr -d " "| tr "," " ") |
Quizás esta sea la linea mas importante del programa, y el truco que se
hace para obtener los pixeles de una imagen en bash. Así que la
explicare un poco mas.
convert $image[1x1+$x+$y] txt: Esta
linea lo que hace es decirle que obtenga de la imagen, el pixel que esta
en la posición ($x,$y) y que me muestre 1×1 solo un pixel y al final le
decimos que nos muestre el valor como texto.
Lo demás es solo para limpiar y dejar solo los valores RGB para que al final nos quede algo asi:
Y ya eso lo pasamos a variables independientes y claro las declaramos de tipo numérico.
1
2 3 |
let r=$(echo $rgb | awk '{print $1}')
let g=$(echo $rgb | awk '{print $2}') let b=$(echo $rgb | awk '{print $3}') |
Hacemos una comprobación diciendo que si el valor de R o G o B es mas
grande que “100″ (Osea que no es tan obscuro para llegar al negro Lo
pintemos de negro en la coordenada dada…De lo contrario se pintara de
blanco.
1
2 3 4 5 |
if [[ $r -gt 100 || $g -gt 100 || $b -gt 100 ]];then
echo "$x,$y: $black" >> $txt_out else echo "$x,$y: $white" >> $txt_out fi |
Donde por cierto los colores $black y $white valen segun imagemagick esto;
1
2 |
black="( 0, 0, 0) #000000 black"
white="(255,255,255) #FFFFFF white |
Al final se convierte el archivo .txt creado a una imagen .pnm (Se usa
este formato ya que el programa de OCR requiere este formato).
1
|
convert $txt_out captcha_clean.pnm
|
Y por ultimo se Usa el programa gocr para obtener las letras de la imagen.
1
|
cracked=$(echo $(gocr captcha_clean.pnm))
|
Y voila!!!
Captcha Cracked!!! No que los bots no podían leer la imagen?? ¬¬
El codigo lo pueden ver en mi Pastebin AQUÍ!!!
Este CÓDIGO SOLO ES DE EJEMPLO!!! Esto igualmente como dije, se puede
realizar de un modo mas rápido con PHP…Dejo un código de ejemplo…
Y bien para terminar modifique un poco el script de arriba, para hacerlo generico…llegando con:
Al cual se le pasa como parametro una imagen y se le definen los colores
que se quieren discriminar…con esto el la limpiara y la intentara
decodificar…Ej:
Este captcha se quiso “crackear” sin limpiarlo y este es el resultado NEGATIVO:
Y con captcha-cracker-neobits.sh
BASH + IMAGEMAGICK + gocr == PWNED!!!
Notas Finales:
- Y bueno con esto demuestro que con bash podemos seguir haciendo cosas hermosas…Obviamente, en “producción” esta no es ni por cercana la mejor opción…Ya que es lento…
- PHP es un excelente lenguaje para manejor de imagenes…pero son mas rapidos los lenguajes compilados.
- Tesseract es otro programa PODEROSISIMO para OCR
- Este ejemplo es completamente demostrativo, ya que con lo tardado de la limpieza, no sirve para hacer un bot malicioso (Ese nunca fue mi proposito)
Espero haya gustado este nuevo post Y sin mas…
Saludos!
FUENTE:
http://news-technology-learning.blogspot.com/2013/05/saltandose-captchas-con-shell-scripting.html?showComment=1369830772831#c8713352826960060827
No hay comentarios:
Publicar un comentario