Hacker l'antispam Mail In Black

antispam

Aujourd'hui, on va parler d'une solution antispam qui s'appelle MailInBlack.

Préambule

D'abord (là, c'est le graphiste qui parle), je voulais saluer le travail de communication. Le nom est génial, le logo très bien pensé et le design du site superbe. Maintenant, on va voir si le produit est à la hauteur de la com.

Comment ça marche ?

J'envoie un mail à Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.. Mon mail est intercepté par le MIB qui me renvoie un mail me dirigeant vers une page d'authentification. Il y une image avec un texte en couleur que je dois rentrer dans le formulaire. Une fois que je valide le formulaire, le mail est transmis à John et mon email est mis sur une liste blanche. C'est un peu lourd pour l'utilisateur mais sur le papier, à priori c'est efficace.

Le Hack

On me demande parfois ce que je pense de cette solution, et je réponds en général que ce doit être facilement contournable. Le problème, c'est qu'il faut me croire sur parole.
Ici, je démontre comment pourrait s'y prendre un spammer pour créer un robot capable de "lire" l'image. Pour ça on va utiliser python.

Un peu de HTML pour commencer

Pour l'algorithme, il nous faut :

  • Récupérer la page HTML
  • Parser la page à l'aide de beautifulsoup
  • Récupérer l'image
  • Lire l'image
  • Appliquer un masque à l'image
  • Enregistrer cette nouvelle image
  • "Lire" le texte avec un OCR

Le code

#import urllib
from bs4 import BeautifulSoup
import dryscrape
import os
import base64
import cv2
import numpy as np
import pytesseract

#To begin, we could read the bounced email and find the links

#variables :
url='file:///home/fred/Documents/programs/scripts/MainInBlack/Authentification MailInBlack anti-spam.html'

## Work only if no javascript is used
#html = urllib.request.urlopen(url).read()

#use of dryscrape to get through the javascript problem
session = dryscrape.Session()
session.visit(url)
html = session.body()

#Parse the result as HTML
soup = BeautifulSoup(html,'html.parser')

# Looking for div with class = image
div=soup.find('div',{'class':'image'})

# Getting the image tag and decoding it
image=div.find('img')
src=image['src'].replace('data:image/PNG;base64,','')
dataImg = str.encode(src) #Encode string to binary
with open("captcha.png", "wb") as fh:
fh.write(base64.decodebytes(dataImg))

#Read the image use HSV and apply mask
img = cv2.imread('captcha.png',1)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
#Use mask to get only the colored text
mask = cv2.inRange(hsv, (0,100,100), (255, 255, 255))
dst1 = cv2.bitwise_and(img, img, mask=mask)
#Write the image to file
cv2.imwrite("word.png", dst1)

# Read the image and OCR with pytesseract
img2 = cv2.imread('word.png')
text = pytesseract.image_to_string(img2)

print(text)
# To go further we'll have to make the robot to put the text in the form and to validate the form

 

Je voulais juste montrer qu'avec moins de 50 lignes de code on pouvait venir à bout de ce type d'antispam.
Mon propos n'est pas de dire que le MIB fait mal son travail. Je trouve juste que leur solution est un peu légère et demande à être amélioré. Ils pourraient déjà faire choisir des objets dans des images comme le fait google.

Le code ainsi que le fichier HTML sont disponibles sur github