Guzei.com

О защите форм гостевых и форумов от спама

Описание методов защиты форм расположенных на сайтах от спама на реальных примерах

Статьи

© 2006-09-25, Игорь Гузей (Guzei.com)

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

Проблема

Спам в гостевых, форумах, каталогах...

Источник проблемы

Попадание в нежелательные списки. Это может происходить двумя вариантами:

  1. Робот-сканер проанализировал поля формы и внёс её в спамерскую базу данных. Это может случится абсолютно с любой гостевой независимо от её посещаемости. Смысл в том, что даже, если книгу мало кто читает из людей, то её всё равно читают поисковые системы и повышают индекс цитирования заказчику спама. Основной признак - текст сообщений одни ссылки на другие сайты.
  2. Человек проанализировал поля формы и внёс её в спамерскую базу данных. Предположу, что робот-сканер даёт отчёт хозяину о формах, которые он не смог пройти и человек их проходит вручную, т.е. опять же риску подвержены абсолютно все, но, логика подсказывает, что ручная обработка всех форм невозможна, а значит человеку нужны приоритеты. Продолжая мыслить логически, предположу, что человек выбирает формы находящиеся на сайтах с высоким индексом цитирования и игнорирует (просто из-за нехватки времени) формы находящиеся на сайтах с низким индексом цитирования.

Атака

  1. Человек, работающий по заранее сформированной базе данных форм рассылает спам с помощью программы даже не зная, какие и где поля заполняются.
  2. База данных имеет только адрес формы и каждый раз робот заполняет реальную форму.
  3. Человек-спамер каждый раз посылает реальную форму.

При этом защита от роботов в виде изображение может преодолеваться либо через распознавание образов либо, используя человека "в тёмную". Например, при необходимости ввести число изображённое на картинке робот может взять эту картинку и вставить её на другую страницу с очень большой посещаемостью, где для совершения действия потребовать ввода кода, а полученный от человека код использовать для отсылки формы.

Варианты защиты

Это то, что я думаю про них до анализа статистики.

  1. Проверять referer. Пустая трата времени. Все спамеры правильно заполняют это поле.
  2. Скрытое поле. Можно использовать hidden поле, которое иногда менять вручную. Просто, но требуется доступ к коду скрипта. Эффективность очень низкая, но всё же иногда помогает. Один из моих очень старых скриптов защищён именно таким образом. За 6 лет внутренний счётчик дошёл до 9 и недавно сбил очередную волну спама, правда всего на два дня. Похоже, что от такого способа пора отказываться.
  3. Переименование скрипта. Просто для скрипта из одного файла. Надо переименовать скрипт, например из guest_book.php в gb.php, изменить внутри 1-2 строки и поправить ссылки на сайте. Способ вроде дурацкий, но очень эффективный. На практике этот способ спас одну гостевую, для которой скрытое поле не помогало. Уже больше года новых покушений нет, хотя в том единственном случае спама было по 20 сообщений за день. Думаю, что эффективность этого способа в том, что в спамерсой базе данных хранятся адреса форм, а, если адреса нет, то и спама нет. Ещё из недостатков этого способа можно отметить то, что гостевая на некоторое время перестанет находится не только спамерами, но и через поисковики и через внешние ссылки. Но всё же способ может применяться для личных гостевых на которые всё равно никто ссылок не ставит (ссылку ведь надо ставить на головную страницу, а не на гостевую книгу), а нахождение через поисковики почти безразлично. Кстати, если бы моя гостевая состояла бы из двух файлов - один для чтения, другой для формы с добавлением новых записей, то и переименовывать надо было бы только файл формы, а уж на него ни поисковики, ни друзья ссылок ставить не должны.
  4. Просить ответ на простой вопрос. Защитит от роботов-сканеров. Защитит от роботов-спамеров. Главное, чтобы ответ нельзя было подобрать тупым перебором параметров находящихся в скрипте. Хорошая автоматическая защита для личных малопосещаемых гостевых на которые человек-спамер просто не будет тратить своё время. От робота защитимся, но, если человек не поленится (см. п.2 вариантов атаки), то всё равно придётся вручную менять вопрос и ответ, что становится практически равным п.2 или 3 вариантов защиты. Вот такой код я только что добавил в одну атакованную форму:
    Пожалуйста, введите здесь третье слово из этого предложения: <INPUT NAME=w>
    Если спам рассылает робот, то он должен споткнуться. Спамер быстро научит робота? А я так же быстро придумаю другой тест. И кому надоест раньше? Если результат для спамера важен, то мне, а, если спамеру почти всё равно, то ему. Этот способ годится и для защиты от роботов-сканеров и от роботов-спамеров конечно же только как самый первый и самый слабый рубеж обороны для соответствующих объектов. Смотрим практический результат. Очередная атака. Поле W заполнено (т.е. защита изменением его значения не помогла бы), но оно заполнено так же как и остальные - рекламой и форма не приняла его. На некоторое время защита сработала. На какое? До тех пор, пока форму не проверит человек. Произойдёт ли это?
  5. Генерация простого кода подтверждения. Просто в реализации. Можно обойтись без графической библиотеки на сервере. Спамеру придётся использовать алгоритм распознавания, что в простом случае не составляет никакого труда. Главное придумать свой код, а не брать готовый. У программ распознавания образов (ORC) есть одно слабое место - им требуется настройка на объект, а это ручная работа. Вот тут то и будет сидеть надежда, что человеку будет лень возиться с вашим проектом.
  6. Генерация сложного кода подтверждения. Можно потратить много времени на придумывание сложного кода. Требуется графическая библиотека на сервере. Серьёзная защита за серьёзные усилия. Но всегда надо исходить из того, что абсолютной защиты от распознавания всё равно не добиться.

Реальная статистика

  1. На адреса http://www.guzei.com/soft/guest_book/?id=73, 74, 128 была поставлена защита: Пожалуйста, введите здесь третье слово из этого предложения: <INPUT NAME=w>, если логическая контрольная переменная вводится не верно, то выдаётся диагностика, что надо ввести слово "здесь". Каждая посылка формы записывалась в лог.

    1) Дата.
    2) Книга.
    3) Referer.
    4) Порядок полей в присланной форме. Должен быть тот же, что и в форме на сайте.
    5) Контрольная переменная вшитая в скрипт. Её не должно быть вообще, т.к. была удалена.
    6) Логическая контрольная переменная - W (см. выше).
    7) Комментарий.
    1234567
    2006-09-25 73полныйданетошибкаВместо слова "здесь" было введено слово из самого объявления. Повторно форма не послалась.
    2006-09-28 73полныйданетпустоПовторно форма не послалась.
    2006-09-29 73полныйданет4Похоже, что кто-то просто баловался.
    2006-09-29128нетнет8нетДаже юзер агент пуст.
    2006-09-29128неткраткий8нет
    2006-09-29 73неткраткий8нет
    2006-09-29 74неткраткий8нет
    2006-09-29128неткраткий8нет
    2006-09-29 74неткраткий8нет
    2006-09-29 73неткраткий8нет
    2006-09-30128,74,128,73,128,128,74,73,74краткий, 8, нет, нет. Всего 9 попыток.
    2006-10-011 попытка.
    2006-10-0211 попыток + прикол. Судя по подписи девушка из Италии хотела через доску объявлений передать привет. Сначала в логическое контрольное поле она ввела "?", потом "sovsem" (третье слово из собственного текста), потом "3dec", потом ничего не ввела, потом наконец-то прочитала диагностику и ввела правильное слово "здесь", но вместе с кавычками. На этом она сдалась и дурацкий привет, который я всё равно бы стёр, не прошёл.
    2006-10-0311 попыток + одно законное объявление было введено со второй попытки.
    2006-10-043 попытки.
    2006-10-0511 попыток + одно законное объявление было введено со второй попытки. В первой попытке человек опять использовал третье слово из собственного текста. И ещё один человек пытался разметить резюме на доске объявлений (128) вместо специального раздела для них (73). В своих попытках он дважды не заполнял логическое поле, потом написал слово "введите" (первое, а не третье) и только с четвёртой попытки ввёл правильно слово. Напомню, что после каждой попытки диагностика писала ему открытым текстом что надо сделать.
    2006-10-0614 попыток + один раз поле UA было пустым.
    2006-10-0717 попыток.
    2006-10-0812 попыток + прикол. Кто-то написал "ПРИВЕТ!КАК ДЕЛА?ДОКТОР." и опять в качестве логической переменной использовал третье слово из своего текста.
    2006-10-0911 попыток.
    2006-10-1014 попыток.
    2006-10-1111 попыток. Одна из них была посылка формы с усечённым количеством полей, встроенной контрольной переменной 5, полным реферером и другим UA.
    2006-10-1214 попыток.
    2006-10-1317 обычных + 2 с КП=5, верным реферером и UA = Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) + 1 баловство без заполнения полей.
    2006-10-1411 обычных + 2 с КП=6, верным реферером и UA = Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1). Судя по тексту спама - из России.
    2006-10-158 обычных + 1 с КП=6, причём набор полей формы был послан и по GET и по POST одновременно.
    2006-10-1611 с КП=8 и 1 с КП=6 как и выше.
    2006-10-1773нетнетнетошибкаТаких было 2 попытки. UA=User Agent: Mozilla/5.0. Думаю, что это был робот-сканер. Интересно, что поля referer не было, зато его полное правильное значение было передано по POST.
    Плюс 16 обычных попыток с КП=8
    2006-10-1811
    2006-10-195 + 1 попытка без UA и одна блокировка принять одно единственное слово "Привет".
    2006-10-2017 + 1 неудачная попытка с незаполненным полем логической контрольной переменной. Причём само объявление было рекламным и всё равно было бы стёрто.
    2006-10-218 + 1 попытка с использованием 10-го слова из своего текста в первой попытке и правильного слова во второй + корректная попытка заброса рекламного объявления с предложением обмена баннерами и кучей ссылок на английском языке.
    2006-10-228 + 2 попытки с верным длинным реферером и произвольными UA.
    2006-10-237 + 2 как вчера.

    У всех IP различные.
    Т.к. в большинстве случаев
    User Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1
    предполагаю, что это один и тот же спамер - программа - база данных. У всего этого же спама был сокращённый реферер.
    У всех! спамеров нарушен порядок следования полей или их количество.

    Количество удачных/неудачных записей с первой попытки от людей - 16/7.

    Похоже, что логический вопрос оказался плохим, т.к. многие поняли его не так, как было задумано.
    Поставлю другой вопрос:
    "А и Б сидели на трубе, А упала, Б пропала. Что осталось на трубе?"
    Как известно из классики жанра роботы-исполнители выгорают при попытке ответить на этот вопрос и только роботы-вершители способны его пройти.

  2. На форме по адресу http://www.guzei.com/radio/design/ изначально стоял контроль длины поля входящих переменных. Если поле слишком длинное, то стоп и диагностику в мыло. С 2006-10-20 на мыло стали поступать сообщения о срабатывании защиты. Несмотря на то, что все поля помечены как MAXLENGTH=255 или меньше спамер это игнорировал.
    20-го не прошли 3 попытки, 21-го - 19, 22 - 15, 23 - 19
    И это несмотря на то, что ни одна запись не была принята робот долбит и долбит.
    На этот раз все поля были заполнены в правильной последовательности и в нужном количестве, IP все разные, Referer везде верный, а User Agent был очень разнообразен.

  3. Ещё одна атакованная форма: http://www.guzei.com/people/add.php
    Вообще то, это почти брошенный проект на который и ссылку то найти очень сложно, но атака имеет следующую статистику:
    начиная с дня 2006-09-29 по вечер 2006-10-24 было 150 попыток ни одна из которых не была удачной, но спамерам это почему-то всё равно.
    Итак:
    Подавляющее большинство попыток (но не все) было с правильным полем referer, разнообразие UA было минимальным, практически у всех попыток было правильное количество полей и их правильная последовательность вместе с новой логической переменной. Ни в одной из попыток логическая переменная не заполнялась осмысленно. Очень много полей было недопустимо длинного размера.

  4. Последняя атака случилась на новую гостевую книгу http://guzei.com/radio/guest_book.php у которой форма для добавления записи выделена в отдельный скрипт http://guzei.com/radio/add_guest_book.php
    За четыре для было послано более 80 спамерских сообщения. Ни одно из них не оказалось на сайте, но и в этом случае спамеров это не остановило.
    Статистика:
    Поле referer было всегда верным, UA был разнообразен, все поля были в нужном количестве и в правильной последовательности. Практически в каждой попытке длина хотя бы одного из посылаемых полей была больше, чем значение MAXLENGTH указанное в форме.

Уточнённые варианты защиты

После анализа статистики к выше перечисленным методам защиты добавляю ещё один - тщательный анализ входящих переменных.

Методы не требующие обслуживания:

  1. Анализ поля User Agent.
    Само поле анализировать бессмысленно, а просто наличие этого поля даёт слишком малый эффект.
    Вывод: использовать не буду.
  2. Анализ поля Referer.
    Значение типа http://www.guzei.com/soft/guest_book/index.php?id=xxx верно при первой посылке формы, а сокращённое значение http://www.guzei.com/soft/guest_book/index.php тоже верно, при повторной посылке формы.
    Вывод: использовать не буду.
  3. Тщательный анализ входящих переменных: Количество полей по GET и по POST, их правильная последовательность, максимальная и минимальная длина поля или точное количество символов в поле, диапазон значений числовых полей и дат. Что интересно, подобный анализ так и так требуется ещё и для защиты от взлома базы данных.
  4. Ответ на простейший вопрос.
  5. Простое изображение.
  6. Сложное изображение.

Методы требующие обслуживания:

  1. Внутренняя переменная. В большинстве случаев нет смысла, хотя иногда может помочь.
  2. Переименования скрипта. Очень эффективный метод, т.к. полностью исключит форму из спамерской базы данных на корню.

На не требующих обслуживания пунктах 3 и 4 пока и остановлюсь дабы посмотреть дальнейшую статистику.

Прошли сутки, спама нет. На новый вопрос люди стали отвечать без ошибок, а роботы до ответа на вопрос даже не прорываются через п. 3.

И вообще о защите

  1. Всё, что видит глаз видит и робот.
  2. Всё, что может распознать человеческий мозг может или сможет распознать компьютерный мозг.
  3. На всё надо время.
Из чего состоят усилия защищающегося:
  1. Разработка.
  2. Установка.
  3. Обслуживание.
Из чего состоят усилия атакующего:
  1. Нахождение.
  2. Вскрытие.
  3. Обслуживание.

Абсолютной защиты нет и быть не может. Задача состоит в том, чтобы придумать способ защиты, который требует минимум усилий (времени) от защищающегося и максимум у атакующего, т.е. довести защиту объекта до уровня "Джо неуловимый".

Дополнительно

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

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

п.3.2.2(2) из http://www.securitylab.ru/contest/239642.php - показывает, что любая защита может быть пройдена.

Удаление (очистка, сброс) сессии при удачном вводе для исключения её повторного использования.

Желание сократить время разработки за счёт установки стандартного скрипта чревато следующим проколом. Защищающийся думает, что защита разработанная умными людьми вполне достаточна для его скромного объекта. Так оно и будет до тех пор, пока этим же алгоритмом не начнёт пользоваться столько сайтов, что у спамера возникнет желание его вскрыть для получения доступа ко всем сразу. Защита должна быть индивидуальной! Даже простейшая индивидуальная защита будет эффективнее сложной, но используемой многими.

Ссылки по теме:

  1. captcha.ru
  2. ocr-research.org.ua
  3. demiurg.livejournal.com/70914.html
  4. securitylab.ru/contest/239642.php
  5. - тут показывается вскрытие captcha с сайта предыдущей статьи :).
  6. : PWNtcha - captcha decoder : Cайт проекта по взлому CAPTCHA. С примерами CAPTCHA-алгоритмов с разных сайтов и описанием их уязвимых мест (англ.)
  7. - Breaking a Visual CAPTCHA
  8. : The CAPTCHA project
  9. The UC Berkeley Computer Vision Group
  10. - The Vision and Media Lab, Simon Fraser University
  11. Shape Matching and Object Recognition
  12. Detecting Natural Image Boundaries