Pull to refresh

Решение MintEye CAPTCHA в 23 строки кода

Reading time 2 min
Views 49K
Original author: jwandrews
Как заядлый читатель HAD я был заинтересован этим постом, описывающим способ взлома аудиокапчи MintEye. Графическая версия также выглядела довольно интересно, так что я подумал, что будет забавно взломать и её.

Вот один из примеров графической капчи MintEye:



Для решения нужно всего лишь подвигать слайдер и выбрать неискажённый вариант изображения. В комментариях на HAD было несколько довольно наивных на мой взгляд предложений решения капчи, основанных на поиске прямых линий. Однако, подобные варианты не сработают с примерами, подобными указанному выше (т. е. содержащим малое количество прямых линий).

После некоторых раздумий я нашёл хороший, надёжный и, на удивление, простой способ разгадывания капчи. Вот вся его реализация на Python:

import cv2
import sys
import numpy as np
import os
import matplotlib.pyplot as plt
 
if __name__ == '__main__':
 
    for dir in range(1,14):
        dir = str(dir)
 
        total_images = len(os.listdir(dir))+1
        points_sob = []
 
        for i in range(1,total_images):
            img = cv2.imread(dir+'/'+str(i)+'.jpg')
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 
            sob = cv2.Sobel(gray, -1, 1, 1)
            points_sob.append(np.sum(sob))
 
        x = range(1,total_images)
        res = np.argmin(points_sob)+1
        print res
        plt.plot(res,points_sob[res-1], marker='o', color='r', ls='')
        plt.plot(x, points_sob)
 
        plt.savefig(dir+'.png')
        plt.show()


(Обратите внимание, что большая часть кода относится к открытию изображения и построению графика. Такие функции, как автоматический разбор изображений и возврат готового результата оставим спаммерам как домашнее задание).

Суть метода в следующем: чем больше изображение «скручено», тем длинее границы. Это можно заметить на картинке, представленной выше, но есть и более наглядный пример:



Обратите внимание на увеличение длины чёрного прямоугольника. Для того, чтобы использовать это, нам нужно посчитать сумму длин границ изображения. Простейший способ сделать это — взять производную изображения (в предложенной выше реализации используется оператор Собеля) и сложить результаты (рекомендуется к прочтению статья о том, как работает оператор Собеля). Затем мы просто выбираем изображение с наименьшей «длиной границ» — оно и будет верным ответом.

Результаты впечатляют, 13 из 13 мною скачанных капч были решены верно этим способом. Эти графики показывают номер изображения на оси Х и «длину границ» на оси Y. Красной точкой отмечен верный ответ.


Интересно, что зачастую абсолютно неискажённое изображение на графике отображается как пик. Это обычно значит, что мы промахнулись с верным ответом на одну картинку влево или вправо (что, впрочем, принимается MintEye как корректный ответ). Происходит это обычно потому, что неискажённое изображение кое-где выглядит чётче и границы выделяются точнее, что влияет на конечную сумму длин.

В завершении хотелось бы сказать, что данная CAPTCHA по своей архитектуре не устойчива ко взлому. Простое «скручивание» изображения всегда может быть легко замечено вышеописанным методом вне зависимости от исходного изображения.
Tags:
Hubs:
+94
Comments 51
Comments Comments 51

Articles