reCAPTCHA: fácil para humanos, ¿difícil para bots?

Si comentáis en blogs como éste veréis que, desde finales del año pasado, Google utiliza un nuevo captcha al que llaman NO CAPTCHA reCAPTCHA que la mayoría de las veces se presenta como un simple checkbox en el que basta con hacer sólo un click para demostrar que no somos un robot:


Partimos de la base de que varios estudios demuestran que actualmente la IA es capaz de resolver el clásico texto distorsionado el 99,8% de las veces, así que había que evolucionar sí o sí. Por ello ahora reCAPTCHA no sólo usa texto distorsionado, si no que añade un buen número de técnicas de riesgo -antes, durante y después- para diferenciar hombres de máquinas.

¿Es posible que se haya mejorado la seguridad de estos captchas y que incluso sean más efectivos sin tener que escribir los clásicos (a veces casi ilegibles) caracteres distorsionados? Eso es lo que aseguran con la nueva API y es que, aunque pudiera parecer sencillo, como comentamos detrás de ese modesto checkbox dicen que hay una alto grado de sofisticación...

Para ponerlo a prueba y medir su efectividad real he empezado escribiendo un bot muy sencillo en Python basado en el reconocimiento de patrones con NumPy y OpenCV que vi en una entrada, muy útil para hacer trampas buscando a Wally/Waldo por cierto.

A grosso modo lo que hace es una captura de pantalla, busca en ella el patrón de la imagen "No soy un robot" y dirige el cursor (después de un movimiento aleatorio) al checkbox, hace click y repite el proceso con el botón "Publicar".

Disculpar mis sucias manos de programador de Python pero he buscado ante todo la rapidez para ver los resultados:
import win32api
import time
import Image
import ImageGrab
import os
import sys
import numpy as np
import argparse
import cv2
import imutils
import random
import time
import math

# captura pantalla
img=ImageGrab.grab()
saveas=os.path.join('ScreenShot.jpg')
img.save(saveas)

# carga imagenes
puzzle = cv2.imread('ScreenShot.jpg')
waldo = cv2.imread('checkbox.png')
(waldoHeight, waldoWidth) = waldo.shape[:2]

# encuentra el patron "No soy robot" en la captura de pantalla
result = cv2.matchTemplate(puzzle, waldo, cv2.TM_CCOEFF)
(_, _, minLoc, maxLoc) = cv2.minMaxLoc(result)
topLeft = maxLoc
botRight = (topLeft[0] + waldoWidth, topLeft[1] + waldoHeight)

# mueve el raton aleatoriamente
x, y = win32api.GetCursorPos()
for i in range(100):
    x = int(x+math.sin(math.pi*i/100)*5)
    y = int(y+math.cos(i)*100)
    win32api.SetCursorPos((x,y))
    time.sleep(.05)

#ve a las coordenadas
import autopy
x, y = topLeft
c, d = botRight
a = int(c + (x-c)*0.9)
b = int(d + (y-d)*0.1)
autopy.mouse.smooth_move(a,b)    
    
import win32con
def click(x,y):
    win32api.SetCursorPos((x,y))
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
    
# haz click en el checkbox    
click(a,b)
time.sleep(5)

# repetimos el proceso, me dió pereza def una función :P
waldo = cv2.imread('checkbox2.png')
(waldoHeight, waldoWidth) = waldo.shape[:2]
result = cv2.matchTemplate(puzzle, waldo, cv2.TM_CCOEFF)
(_, _, minLoc, maxLoc) = cv2.minMaxLoc(result)
topLeft = maxLoc
botRight = (topLeft[0] + waldoWidth, topLeft[1] + waldoHeight)
import autopy
x, y = topLeft
c, d = botRight
a = int(c + (x-c)*0.9)
b = int(d + (y-d)*0.1)
autopy.mouse.smooth_move(a,b)    
click(a,b)

He de reconocer que los resultados ciertamente me desconcertaron un poco: algunas veces Recaptcha detecta la actividad del bot:


pero otras muchas *y sólo con este tonto script* puedo publicar comentarios de forma automatizada:


Podría sacar el Camtasia y poneros un vídeo para que veáis los resultados, pero prefiero que lo probéis vosotros mismos y compartáis vuestras impresiones.

Eso sí, podéis joderme el blog llenándolo de comentarios de spam o ser decentes y probarlo en uno de pruebas obteniendo una key y escribiendo un formulario sencillo:
<html>
  <head>
    <title>Google recapcha demo - Codeforgeek</title>
    <script src='https://www.google.com/recaptcha/api.js'></script>
  </head>
  <body>
    <h1>Google reCAPTHA Demo</h1>
    <form id="comment_form" action="form.php" method="post">
      <input type="email" placeholder="Type your email" size="40"><br><br>
      <textarea name="comment" rows="8" cols="39"></textarea><br><br>
      <input type="submit" name="submit" value="Post comment"><br><br>
      <div class="g-recaptcha" data-sitekey="=== Your site key ==="></div>
    </form>
  </body>
</html>

A partir de ahí la habilidad e imaginación de cada uno...
 
Por ejemplo con iMacros en Firefox y batch power XD:

VERSION BUILD=8890130 RECORDER=FX
TAB T=1
SET !USERAGENT "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+"
URL GOTO=http://www.hackplayers.com/2010/02/insecure-magazine-24-febrero-2010.html?m=0
WAIT SECONDS=10
url goto=javascript:window.scrollBy(0,500)
FRAME NAME="comment-editor"
TAG POS=1 TYPE=TEXTAREA FORM=ID:commentForm ATTR=ID:commentBodyField CONTENT=hola
TAG POS=1 TYPE=SELECT FORM=ID:commentForm ATTR=ID:identityMenu CONTENT=%ANON
TAG POS=1 TYPE=INPUT:BUTTON FORM=ID:commentForm ATTR=ID:postCommentSubmit

start /B "" "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"  -private imacros://run/?m="break_recaptcha.iim" -loop 3
timeout /t 30
"d:\Python27\python.exe" "C:\temp\recaptcha_breaker.py"
timeout /t 10


Feliz beta testing!

14 comentarios :

  1. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  2. ¿Puedes poner un zip con el código y las fotos que usas? Concretamente la que almacenas en waldo ya que lo otro es un screenshot.

    s2

    ResponderEliminar
    Respuestas
    1. son simplemente los patrones de las imágenes a detectar:

      http://4.bp.blogspot.com/-4_15JiMVQvU/VQKb9O-EyjI/AAAAAAAAmXc/VKYi6DbYYgY/s1600/checkbox.png
      http://3.bp.blogspot.com/-gnIa8lAlnQg/VQKb_952FoI/AAAAAAAAmXk/bhtJOjPVa8g/s320/checkbox2.png

      Eliminar
  3. Esto ayuda en algo al ponerlo en la consola o no aporta nada al tema?
    document.URL + '": "' + document.body.innerHTML.match(/k\=[a-zA-Z0-9-_.]{20,40}/)[0].replace("k=","")

    ResponderEliminar
  4. Como ejecuto ese script en Chrome?

    ResponderEliminar
    Respuestas
    1. puedes hacer que el .bat abra al navegador Chrome, ejecute la iMacro de turno para escribir el comentario que quieras y por último llamar al script de Python que pongo arriba...
      Saludos,

      Eliminar
  5. Hola lo he probado y me da este error " File "C:\temp\recaptcha_breaker.py", line 57
    SyntaxError: Non-ASCII character '\xf3' in file C:\temp\recaptcha_breaker.py on
    line 57, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for
    details " Alguna idea que pueda ser?

    ResponderEliminar
    Respuestas
    1. has editado el fichero? parece que tienes un carácter raro en esa linea...

      Eliminar
  6. Hola que tal se podria usar esto para el facebook? porque seria inclusive mas facil, son solo letras y numeros

    ResponderEliminar
  7. me sale este error como lo soluciono?: Traceback (most recent call last):
    File "leavebusterlol.py", line 26, in
    (waldoHeight, waldoWidth) = waldo.shape[:2]
    AttributeError: 'NoneType' object has no attribute 'shape'

    ResponderEliminar