Как стать автором
Обновить

Взлом капчи LostFilm (php)

Время на прочтение 4 мин
Количество просмотров 16K
Решив скачать очередную серия Хауса я заглянул на LostFilm и обнаружил, что теперь на сайте, чтобы скачать нужно регистрироваться.
Только я решил зарегистрироваться, как на глаза мне попалась их новомодная капча:


Капча показалась мне довольно простой (хоть и не лишена она дольки оригинальности).

Итак, капча представляет собой изображение с тремя фигурами и надписью.
Фигуры отображаются в случайном порядке, без каких либо искажений или изменений положения по осям (меняется только тип фигуры и порядок). Всего фигур четыре: круг (circle), квадрат (square), треугольник (triangle) и крестик (x).


Под фигурами выводится надпись, на которой указано какую из фигур необходимо выбрать.

Всё это «чудо» располагается в файле login.bogi.ru/captcha.php, выводится стандартной phpGD библиотекой, размеры файла 170x95px, тип PNG.

Регистрация происходит по отправке GET HTTP запроса (в данном случае XHR, но это никакого значения не имеет, т.к. проверки на подмену нет):
bogi.ru/auth/registration?first=FIRST_NAME
&last=LAST_NAME
&nick=NICK
&email=EMAIL
&password=PASSWORD
&sex=1
&captcha=1
&sid=
&ajax=1
&target=http%3A%2F%2Flostfilm.tv%2F

Больше всего нас интересуют поля email, password, captcha и sid.

Через sid передаётся идентификатор капчи по которому и ведётся проверка подлинности.
В параметре captcha указывается номер фигуры 1, 2 или 3.

Полный путь к картинке капчи будет выглядеть так:
login.bogi.ru/captcha.php?sid=a0vxd4rgs0gsz5gh38gan903sac

image

Получим картинку из исходного кода страницы регистрации, например из скрытого поля sid:

$reg = "/name=\"sid\" value=\"([^\/]+)\"/";//<input type="hidden" name="sid" value="7cf6e89e9ee5dd19cdae1328208198" />
preg_match($reg, $site_html, $sid);
$sid = $sid[1];


Получив изображение, можно переходить к его разбору.
Для начала я разделил всё изображение на две области:
1) Фигуры
2) Надпись



Так как ни фигуры, ни надпись не искажаются и не меняют свое положение, легко составить их матрицы для каждого случая (4*2 = 8 матриц).
Например, так:
for($x=0; $x<$width; $x++)
{
    for($y=0; $y<$height; $y++)
    { 
        
        $color[$x][$y] = imagecolorat($img, $x, $y);
        //sign
        if($y > 70)
        {
            $sign[$x1][$y1]  .= ($color[$x][$y]==2147483647?0:1);
            $y1++;
        }
        //FIGURE 1
        if($y > 10 && $y < 40 && $x > 20 && $x < 50)
        {
            $figures[0][$f0x] .= ($color[$x][$y]==16777215?0:1);
        }
        
        //FIGURE 2
        if($y > 10 && $y < 40 && $x > 70 && $x < 100)
        {
            $figures[1][$f1x] .= ($color[$x][$y]==16777215?0:1);
        }
        
        //FIGURE 3
        if($y > 10 && $y < 40 && $x > 120 && $x < 150)
        {
            $figures[2][$f2x] .= ($color[$x][$y]==16777215?0:1);
        }

    }

    if(count($sign)){$x1++; $y1=0;}

    if($x > 20 && $x < 50) $f0x++;
    if($x > 70 && $x < 100) $f1x++;
    if($x > 120 && $x < 150) $f2x++;
}


Здесь я делаю матрицы для 3 фигур ($figures) и матрицу для надписи ($sign). Фоновые цвета (у фигур белый, у надписи прозрачный) я заменяю на 0, остальные — 1.
В итоге получаются матрицы наподобие такой:


Остаётся дело за малым, нужно составить банк матриц для всех фигур и надписей, а затем сравнивая разобранные изображения с заранее сохраненными матрицами можно будет установить номер фигуры, а следовательно — разгадать капчу.

Код сверки довольно простой:
if($sign == $signs['x']) 
{
    if($figures[0] == $drawings['x']){$result = 1;}
    elseif($figures[1] == $drawings['x']){$result = 2;}
    elseif($figures[2] == $drawings['x']){$result = 3;}
    else{$result = 0;}
}
elseif($sign == $signs['circle'])
{
    if($figures[0] == $drawings['circle']){$result = 1;}
    elseif($figures[1] == $drawings['circle']){$result = 2;}
    elseif($figures[2] == $drawings['circle']){$result = 3;}
    else{$result = 0;}
}
elseif($sign == $signs['square'])
{
    if($figures[0] == $drawings['square']){$result = 1;}
    elseif($figures[1] == $drawings['square']){$result = 2;}
    elseif($figures[2] == $drawings['square']){$result = 3;}
    else{$result = 0;}
}
elseif($sign == $signs['triangle'])
{
    if($figures[0] == $drawings['triangle']){$result = 1;}
    elseif($figures[1] == $drawings['triangle']){$result = 2;}
    elseif($figures[2] == $drawings['triangle']){$result = 3;}
    else{$result = 0;}
}


Здесь, $signs — матрицы надписей, $drawings — набор матриц фигур, $sign — текущая надпись, $figures — набор текущих фигур.

В результате получаем номер картинки (или 0 если не удалось разобрать).

Всё что осталось — отправить запрос на регистрацию:
$regURL = "http://bogi.ru/auth/registration?first=TestBot&last=Bot1a&nick=bot".substr(uniqid(), 0, 5)."&email=bot".substr(uniqid(), 0, 5)."@gmail.com&password=qwerty123&sex=1&captcha=".$result."&sid=".$sid."&ajax=1&target=http%3A%2F%2Flostfilm.tv%2F";
$data = file_get_contents($regURL);


В ответ получаем
callback({"error":0,"text":""});
Что значит «Ура! Регистрация пройдена успешно».

Хотел бы заметить, что эта капча крайне не надёжна, легко взламывается даже неопытным программистом за короткое время, и использовать её, если вы хотите оградить свой сайт от ботов и спамеров разумеется не стоит.

P.S. В общем, на «взлом» этой капчи ушло около часа, на разбор одной картинки (вместе с парсингом и регистрацией) уходит около 5 секунд. На всякий случай, отчёт о проделанном я отправил в тех. поддержку LostFilm, а затем отправился смотреть 10 серию Хауса.
Теги:
Хабы:
+56
Комментарии 81
Комментарии Комментарии 81

Публикации

Истории

Работа

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн