Humansnotinvited: разгадываем капчу на bash

в 15:47, , рубрики: bash, you're a human, капча, машинное обучение, ненормальное программирование, обработка изображений

Приветствую, дорогой читатель!

Многие из Вас встречались с капчей — автоматическим тестом Тьюринга. Она позволяет отделить реальных людей от различных ботов. В последнее время очень популярной стала reCAPTCHA от Google Inc. На ней Вы должны выбрать изображения, содержащие некие объекты, к примеру, автомобили. Относительно недавно появился сайт, который делает ровно наоборот: отделяет ботов от людей.

Сайт приветствует пользователей предложением пройти капчу, состоящую из размытых квадратов:

Humansnotinvited: разгадываем капчу на bash - 1

В случае неуспешной попытки, Вы увидите сообщение:

You're a human.
You are not invited.


Правда нескольким пользователям Reddit все же удалось пройти капчу.

Приступаем к обучению

Если обратить внимание, то у капчи на сайте весьма ограниченное число тем (того, что надо найти на картинке), а также небольшая база изображений. Вероятно, можно скоррелировать картинку к той или иной теме, то есть чем чаще картинка попадалась в сочетании с этой темой, тем больше вероятность того, что на ней изображен интересующий нас объект. Давайте свяжем имена файлов изображений с темой. К счастью, имена у файлов каждый раз разные, поэтому определять попадалась ли нам такая картинка раньше, не можем. В таком случае будем их сохранять и сравнивать между собой. Сравнивать можно не сами картинки, а hash-суммы к ним, так как при равенстве картинок hash-суммы тоже совпадут.

Сперва скрипт скачивает страницу с изображением:

wget http://www.humansnotinvited.com/ &>/dev/null

Определяет тему изображения:

TYPE=`grep "value="[a-zA-Z0-9 ]+"" index.html -o | grep ""[a-zA-Z0-9 ]+"" -o | sed "s/"//g"`

Получает url изображений капчи:

CAPTCHAS=`grep "img src=".*?alt=""" index.html -Po | grep "captcha/image.php.*?&id=[0-9]" -Po`

Скачивает капчи и приписывает им уникальный номер. Сразу выводит привязку md5sum к теме:

j=0
for i in $CAPTCHAS
do
    wget http://www.humansnotinvited.com/$i -O $j.jpg &>/dev/null
    WHERE=`md5sum $j.jpg | cut -c 1-32`
    echo $TYPE";"$WHERE
    let "j=j+1"
done

Удаляет ненужные файлы:

rm index.html
rm *.jpg

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

Весь код

#!/bin/bash

for i in `seq 0 1000`
do

wget http://www.humansnotinvited.com/ &>/dev/null

TYPE=`grep "value="[a-zA-Z0-9 ]+"" index.html -o | grep ""[a-zA-Z0-9 ]+"" -o | sed "s/"//g"`

CAPTCHAS=`grep "img src=".*?alt=""" index.html -Po | grep "captcha/image.php.*?&id=[0-9]" -Po`
j=0
for i in $CAPTCHAS
do
    wget http://www.humansnotinvited.com/$i -O $j.jpg &>/dev/null
    WHERE=`md5sum $j.jpg | cut -c 1-32`
    echo $TYPE";"$WHERE
    let "j=j+1"
done

rm index.html
rm *.jpg

done

Запускаем и пишем в таблицу full, которая затем понадобится для разгадывания капчи:

./createTable.bash > full

Разгадываем капчу

Полученная таблица будет иметь два набора непрерывных значений, между которыми будет значительный разрыв. По этому разрыву проходит граница, ниже которой элементы входят в множество неверных ответов, выше — множество верных ответов. Для ~1000 запусков граница равна 80-100 повторениям.

В качестве ответа, сервер принимает POST-запрос на www.humansnotinvited.com/ajax/sendCaptcha.php и возвращает JSON.

Пример POST-запроса

capthcaData[0][id]:4
capthcaData[0][token]:$1$adig2JKH$m9NKp.98MT8N5A8c.SEaw0
capthcaData[0][active]:false
capthcaData[1][id]:7
capthcaData[1][token]:$1$R8hAbOML$SERl/oIWWTGimhb5ywioG0
capthcaData[1][active]:false
capthcaData[2][id]:1
capthcaData[2][token]:$1$5M/tB252$iQm9NjRu1qNKcSC2wF/u4.
capthcaData[2][active]:true
capthcaData[3][id]:3
capthcaData[3][token]:$1$kn.4h2yQ$7nmRt19MKrtv/3sytU1Tj1
capthcaData[3][active]:false
capthcaData[4][id]:2
capthcaData[4][token]:$1$hv4Ku.BF$CDyWe7tHQXA1gt4ru7j.11
capthcaData[4][active]:true
capthcaData[5][id]:5
capthcaData[5][token]:$1$TzUr8bR9$vfbdKyNuebod8hRmNRxN51
capthcaData[5][active]:false
capthcaData[6][id]:8
capthcaData[6][token]:$1$QLT/VbgI$lNYNOnSiXyk905WbB9zPH1
capthcaData[6][active]:false
capthcaData[7][id]:9
capthcaData[7][token]:$1$1A3.rD88$lxrUf.VdCFyEJnNzir1wz1
capthcaData[7][active]:true
capthcaData[8][id]:4
capthcaData[8][token]:$1$Pf5m5yjV$PypMZUid/smpNx/qBKMRv1
capthcaData[8][active]:false
category:spiders

Подход при решении капчи очень похож на подход при создании таблицы. Но теперь мы считаем md5sum не для добавления в таблицу, а для поиска изображения в таблице. Параллельно этому выводим POST-запрос. TOKEN — имя изображения, WHERE — md5sum изображения, ID — порядковый номер.

j=0
for i in $CAPTCHAS
do
    wget http://www.humansnotinvited.com/$i -O $j.jpg &>/dev/null
    ID=`echo $i | grep "id=[0-9]+" -o | grep "[0-9]+" -o`
    TOKEN=`echo $i | grep "image_name=.*?&id" -Po | sed "s/image_name=//; s/&id//"`
    WHERE=`md5sum $j.jpg | cut -c 1-32`
    echo "&capthcaData[$j][id]=$ID"
    echo "&capthcaData[$j][token]=$TOKEN"
    if [[ $( grep "$TYPE;$WHERE" full -c ) -gt 100 ]]
    then
        echo "&capthcaData[$j][active]=true"
    else
        echo "&capthcaData[$j][active]=false"
    fi
    let "j=j+1"
done

Весь код

#!/usr/bin/bash

rm *jpg
rm index*

wget http://www.humansnotinvited.com/ &>/dev/null

TYPE=`grep "value="[a-zA-Z0-9 ]+"" index.html -o | grep ""[a-zA-Z0-9 ]+"" -o | sed "s/"//g"`

CAPTCHAS=`grep "img src=".*?alt=""" index.html -Po | grep "captcha/image.php.*?&id=[0-9]" -Po`
j=0
for i in $CAPTCHAS
do
    wget http://www.humansnotinvited.com/$i -O $j.jpg &>/dev/null
    ID=`echo $i | grep "id=[0-9]+" -o | grep "[0-9]+" -o`
    TOKEN=`echo $i | grep "image_name=.*?&id" -Po | sed "s/image_name=//; s/&id//"`
    WHERE=`md5sum $j.jpg | cut -c 1-32`
    echo "&capthcaData[$j][id]=$ID"
    echo "&capthcaData[$j][token]=$TOKEN"
    if [[ $( grep "$TYPE;$WHERE" full -c ) -gt 100 ]]
    then
        echo "&capthcaData[$j][active]=true"
    else
        echo "&capthcaData[$j][active]=false"
    fi
    let "j=j+1"
done

echo "&category="$TYPE

Запускаем:

 wget http://www.humansnotinvited.com/ajax/sendCaptcha.php --post-data `./gotcha.bash | tr -d "n" | cut -c2-`

Кто же проходит капчу?

В качестве ответа сайт возвращает список IP-адресов, которые успешно прошли капчу. Капча была успешно пройдена с 3022 уникальных IP.

Страна Число IP
Россия 1072
США 450
Япония 307
Украина 162
Великобритания 104
Франция 98
Другие страны 829

Географическое распределение ботов, которые успешно прошли капчу. Данные по принадлежности IP к стране брались на dev.maxmind.com. Часть IP была отнесена базой к Europe (8IPs) и Asia/Pacific Region (1IP). Они были добавлены к Denmark и Papua New Guinea, соответственно. Так же Hong Kong (6IPs) был отнесен к China. (Картинка кликабельна)

Humansnotinvited: разгадываем капчу на bash - 2

Рост суммарного количества IP некоторых стран относительно номера по списку:

Humansnotinvited: разгадываем капчу на bash - 3

Полезные ссылки:

Автор: Fulgur

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js