«Оцифровываем» каптчу единого реестра сайтов, защищающего людей от информации

  • Tutorial
Совсем недавно открылся портал Единого государственного реестра сайтов. Отдельно от всего прочего мне приглянулась очень слабая каптча, и я решил её побороть.

Подобными вещами я уже занимался, правда, не в таком масштабе. Если вам интересно, как получить КПД распознавания в 57% используя только GNU/Bash, imagemagick и Tesseract-ocr, добро пожаловать под кат.

Нижеследующая инструкция может быть легко модифицирована под любые другие подобные слабые каптчи.

Вступление


Распознавание самих картинок каптч можно разделить ровно на два этапа:

  • Подготовка картинки. Для этого я буду использовать imagemagick
  • Распознавание символов. В этом случае я выбрал Tesseract, но на более простых каптчах (без поворотов, без разрывов) можно использовать ocrad, к примеру.

Получение картинок и отправление результатов легко совершается при помощи curl (или wget, но с ним я не подружился).

Подготовка картинок


В ImageMagick есть встроенный язык Fx для создания спец-эффектов. Так как на каптче реестра буквы всегда черные, самый простой вариант скрипта, убирающий всё нечерное, будет выглядеть так:

convert file.png -colorspace cmyk -fx 'k * (k >= 1.0)' file.ppm


Выполнение занимает десятую секунды, что допустимо. Но качество картинки — нет, так что нужно пройтись по ней еще раз. Можно положиться на то, что если буква была задета линией, то в таком месте должны быть закрашенные пиксели-соседи сразу с двух противоположных сторон:

convert file.ppm -colorspace cmyk -fx 'k || (p[-1].k && p[+1].k) || (p[0,-1].k && p[0,+1].k)' out.ppm


Чем мы жертвуем еще половиной секунды. Как окажется позже, это увеличит процент успеха с 1% до 22% (на 100 контрольных картинках).

Распознавание символов


Тут всё еще проще. Травим tesseract на картинку, забираем результат из файла. При желании, можно научить его шрифту каптчи как отдельному языку, но овчинка выделки не стоит.

  tesseract out.ppm result -psm 8 nobatch digits 2>/dev/null
  res=$(cat result.txt | sed -e 's/[^0-9]//g')

Отработка в реальных условиях


Как я уже сказал выше, такая комбинация дала правильный ответ на 22 из 100 тестовых картинок. Но тесты — не интересно, и я решил проверить скорость работы в реальных условиях.

Главный скрипт
#!/bin/bash
c=$(curl -c cook.txt http://zapret-info.gov.ru/ | iconv -f cp1251 | grep capcha | sed -e 's/"/\n/g' | grep services)
url="http://zapret-info.gov.ru$c"

r=work01

#get
curl -b cook.txt "$url" > "$r.png"

#prepare
convert $r.png -colorspace cmyk -fx 'k * (k >= 1.0)' $r.png
convert $r.png -colorspace cmyk -fx 'k || (p[-1].k && p[+1].k) || (p[0,-1].k && p[0,+1].k)' $r.png

#exterminate
tesseract $r.png $r -psm 8 nobatch digits
res=`cat $r.txt | sed -e 's/[^0-9]//g'`

#check
if [ "$(echo $res | wc -c)" -ne 9 ]; then
  echo fail && exit
fi

#send
code=$(echo $c | sed -e 's/[^0-9]//g')
fin=`curl -b cook.txt -d "act=search&secretcodeId=$code&searchstring=ya.ru&secretcodestatus=$res" 'http://zapret-info.gov.ru/'| iconv -f cp1251`

if echo "$fin" | grep -q 'не значится'; then
  echo succ
else
  echo tesfail
fi

rm $r.png $r.txt cook.txt
Обертка
#!/bin/bash
score=0
all=0

while [ "$score" -lt 41 ]; do

  r=`bash per.sh 2>/dev/null`
  [ "$r" = 'succ' ] && let score++
  let all++

  echo "$score/$all; $r"
done

Строка запуска
time bash tt.sh | tee -a log.txt


Результаты, статистика


Вышеуказанный набор скриптов производит 41 успешную проверку на наличие ya.ru в реестре. Небольшая статистика по нему:

Успешно подобрано: 41
Всего каптч: 218
Время работы: 5 минут 4 секунды (5m4.178s)
КПД: 19%
КПД с учетом заведомо неправильных решений, которые не отправлялись на проверку: 57%
Максимальный КПД во время работы: 33%
Минимальный КПД во время работы: 12%


Пути улучшения

  • Одну картинку можно получить множество раз, получая разные каптчи с одним текстом. Это можно использовать.
  • Используя нормальные и проверенные способы можно получить очень хороший КПД.
  • Или просто научить Tesseract шрифту каптчи. Сам шрифт похож на Arial, но тессеракт постоянно путает 3 и 8, 1 и 7.
  • Оптимизировать получение информации: значительная часть времени работы скрипта уходит на получение страниц и картинок с сервера.
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 48

    +1
    Я не могу понять, зачем столько усилий? Не рекапче сидят тыщи китайцев, процент почти 100.
      +18
      Не спортивно же :)
        +2
        Далеко не 100 и медленно :)
          0
          На моих выборках они обычно 99 процентов отгадывают (хотя да, тупят). Как плюс — не нужно под каждую капчу писать дешифратор.
          +1
          На рекапче никто не сидит, сидят на антигейтах и подобных сайтах :)
            +1
            Я об антигейте (конечно не рекапча). :)
            0
            рекапча? Может быть Pixodrom ( pixodrom.com )?
            +6
            Также можно скриптом завалить сайт заявками используя гугл в качестве генератора случайных урлов.
            UPD. мб сделать? кто что думает?
              +1
              Могут по ip заблокировать, надо над прокси подумать еще. Ну и над самими заявками, чтобы сайты побольше были да загружались подольше. Кстати, они же вручную проверяют… Им же случайно могут попасться порноссылки и даже ссылки на вредоносные сайты. Как они с этим борются интересно)
                0
                Можно использовать Tor. Да и листы паблик-прокси достать не такая уж и проблема.
                  +1
                  И как альтернативный вариант — вебсервер с js-кой, что будет выполнять эти действия и опубликовать ссылку. Кто-то да воспользуется. В реестре не обрадуются.
                +3
                Генератор не интересно. Интересно отправлять ссылки на реальные страницы. В этом случае не будет возможности различить стукачество от шумоизоляции, т.е. кому-то там придётся идти и читать всё, что прислали. А это куда эффективнее, чем засирание базы, ибо в условиях перегрузки люди не прекращают обработку новых запросов, а начинают халтурить с существующими.

                В принципе, отправка результатов поиска гугла по inurl:a, inurl:b и т.д. — неплохая стратегия.
                  +6
                  Вообще-то я и имел ввиду отправку реальных урлов полученных через поиск гугла. По запросу «сайт» например.
                  p.s. Существуют сервисы типа этого (http://www.randominio.com/ru) что по клику перенаправляют на случайную страницу. Это ещё круче и проще, чем поиск гугла.
                  • НЛО прилетело и опубликовало эту надпись здесь
                      +1
                      Смс-подтверждение можно купить на стороне. Где-то в комментах на хабре была ссылочка :)
                      Плюс ко всему прочему, остро встаёт вопрос передачи данных. Если передавать открыто… ну, сами понимаете. Если передавать хеш, то возможны коллизии, и может получиться неразбериха. Палка о двух концах в общем.
                    +1
                    Можно по этим спискам пройтись просто =)
                    panel.reghouse.ru/ru_domains.gz
                    panel.reghouse.ru/su_domains.gz
                      0
                      Ну, тогда придётся в любом случае привлекать поиск, чтобы иметь не только главные странички, но и случайные странички с этого домена (например, случайное сообщение на форуме). Используя только поиск гугла, можно будет иметь в спам-списке ещё и сайты с буржундии)
                        +1
                        чтобы получить случайную страничку с домена, в 100 раз проще загружать индексную страничку с самого домена и выбирать рандомную ссылку с неё, чем бороться с капчей и баном гугла.
                          0
                          Хм. И то правда — про бан гугла я благополучно забыл -_\\
                      +3
                      Как-то так и закроют хабр, ведь это подстрекательство на кибер-терроризм.
                        0
                        Вкину свои 5 копеек. Встала тут недавно задача голосовалку обмануть. Правда она была без капчи зато позволяла голосануть 1 раз с IP адреса. В общем вот вам однострочник на шеле, может сгодится кому:
                        while read line; do echo $line; curl http://voteurl.ru/vote/path/ -d "postKey1=postValue1&postKey2=postValue2" -x $line -o ./output.txt ; done < /home/name/proxy-list.txt
                        Прокси серверы брал отсюда
                          0
                          Круто, спасибо. Кинул в избранное, буду пользовать в будущем).
                        0
                        Ну все теперь…
                          +3
                          UnixWay!
                            +1
                            И в главном скрипте вторую строку лучше вот такой сделать
                            c=$(curl -c cook.txt http://zapret-info.gov.ru/ | iconv -f cp1251 | grep capcha | sed -n 's/.*src="\(.*\)".*/\1/p')
                              +15
                              В конце концов они замучаются и сделают белый список вместо черного. Вот тогда реально весело будет.
                                0
                                Я удивлен, если честно, что они с этого не начали.
                                  0
                                  А что с презумпцией невиновности тогда делать? По такому принципу можно всех садить в тюрьму, а за хорошее поведение выпускать!
                                  Они, конечно могут, я, лично не особо удивлюсь...
                                  0
                                  Возможно что суть в том, что для того, чтобы составить тот самый белый список, нужно время. И немало времени. Результат же нужен уже сейчас, посему, самый простой способ прекращения доступа к «неподходящим» ресурсам — тупо их блочить. А если не подготавливать такой список заранее то это будет сродни банальному отрубанию кабеля. Если приобщить народ к таким действиям (как сейчас) в виде заявок и прочего, то в первые часы (если не минуты) ресурс просто ляжет. Люди будут массово слать просьбы разлочить их любимый форум ветеринаров, вики скейтеров, ещё-что-нибудь и т.д. и т.п. Как по мне, так геморрою будет по самое небалуйся. Посему, проще сделать то, что сделано.
                                +2
                                Можно повысить кдп до 99%, так как по одному урлу(типа zapret-info.gov.ru/services/capcha/?i=123) отдаются одни и те же цифры(так как, судя по всему, сессия генерируется на странице, а не из картинки). Несколько раз запрашиваем, распознаём, выбираем по большинству.
                                  0
                                  Я об этом написал. 99% не быть, т.к. в большем количестве случаев оно путает 9 и 3, 1 и 7, повторения при таком методе ухудшают результаты
                                  0
                                  Интересно, а есть зависимость между текстом капчи и параметром i в урле?
                                    0
                                    i строго зависит от phpssid. Нельзя получить каптчу без phpssid или неправильным i. После получения каптчи i аннулируется
                                      0
                                      Что вы имеете в виду под «получение капчи»? Отправка серверу ответа на капчу? Ибо так-то ничего не аннулируется. В течение весьма долгого времени можно невозбранно запрашивать капчу снова и снова, и она будет возвращаться с одинаковым текстом внутри, и размещен он при этом будет по-разному, как и писалось выше.
                                        0
                                        После отправки, да
                                      0
                                      Конечно есть! По значению параметра i они производят сравнение того, какой код ввел пользователь, и какое значение кода на самом деле. в параметре i просто идентификатор кода хранится(не сам код!)
                                      0
                                      > Минимальное КПД
                                      КПД — это коэффициент, поэтому «минимальный», «максимальный».
                                        –1
                                        Спасибо, но на будущее: о таком пишут в личку
                                          +5
                                          Это не опечатка, а ошибка. Поэтому вполне ещё кому-нибудь пригодится.
                                        +3
                                         res=$(cat result.txt | sed -e 's/[^0-9]//g')
                                        

                                        Useless cat. Почему сразу-то не сделать так:
                                         res=$(sed -e 's/[^0-9]//g' result.txt)
                                        
                                          +1
                                          Как думаю, так и пишу, поэтому такая фигня и получается :)
                                          +1
                                          Попробовал увеличить картинку при перед прогоном через Tesseract.

                                          Случаев, когда совсем распознать не получилось становится сильно меньше, но общий результат от этого не меняется. И работать начинает заметно дольше.

                                          Жаль.
                                            +1
                                            Вот и начались первые попытки взлома данного занимательного ресурса. Думаю это далеко не последний случай. Ждемс. Ждемс.
                                              0
                                              Или просто научить Tesseract шрифту каптчи. Сам шрифт похож на Arial, но тессеракт постоянно путает 3 и 8, 1 и 7.

                                              Может быть, стоило решить эту проблему, прежде чем публиковать статью? Все же явно видно, что 3\8 и 1\7 очень сильно отличаются:
                                              Скрытый текст

                                                0
                                                Тессеракту таки нельзя указать шрифт, да и повороты его путают. Да, можно специально обучить, но это лень :)
                                                +1
                                                Статья про обработку изображений без картинок — не лучшая идея.

                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                Самое читаемое