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



Промо было сделано в виде игры, суть которой заключалась в отгадывании точки на карте по изображению с Google StreetView и получение за это все очков, количество которых пропорционально точности ответа. На все про все дается 6 минут. Также между раундами предлагается половить\покидать подарки и полетать на аэроплане за дополнительные очки. Шесть минут можно увеличить до десяти, правильно ответив на вопросы викторины. За хорошие результаты дают порядочное количество миль.

Просканив директории(для успокоения души) и не найдя ничего интересного(кроме торчащего в Интернет phpmyadmin), я приступил к анализу самой игры.

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

for i in {0..50}; 
  do torify curl 'http://mission2017.aeroflot.ru/ajax/round' --data 'val1=49&val2=9&game=563058&round=4974078&atype=map' & done;

Однако, эту уязвимость быстро закрыли.

2) Мини-игры реализовывали всю логику на своей стороне. И отправляли на сервер только итоги. Соответственно данные запросы можно было модифицировать и пролетать сотни тысяч км на своем аэроплане.

3) Викторина до конца промо была уязвима для Replay атак. Так что можно было накручивать себе время на игру. Минус этого метода в том, что по логике создателей, невозможно набрать более 10 минут времени, поэтому результат выбивался бы из ровного списка десятиминутников.

4) Но все вышеперечисленное — это хаки, которые можно отследить и наказать за них. Значит настало время писать бота! Скрипт игры представляет из себя неплохой необфусцированный код, с довольно ясными именованием функций и переменных. Примечательно, что в ответе на запрос к /ajax/round приходили верные координаты. Это обстоятельство позволяло замапить каждый url панорамы на координаты.

map = {"https://www.google.com/maps/embed/v1/streetview?pano=_EjgB69lOpQheNB4ldZWsA&key=AIzaSyAdpt2jitUXkLd8NtkNQ_Ee6THUA_DZ-K0" : {lat: 40.62, lon: 22.94},
 "https://www.google.com/maps/embed/v1/streetview?pano=oIMBbAJeLJfwiwNtgiVl-g&key=AIzaSyAdpt2jitUXkLd8NtkNQ_Ee6THUA_DZ-K0" : {lat: 22.27, lon: 114.16},
 ...
}

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

Стоит отдать должно разработчикам(а может быть модераторам), у них был неплохой антифрод и все сомнительные участники банились. Я не смог выяснить все параметры по которым производился анализ на фрод, но два из них мне известен: скорость и точность ответа.

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

Первые три уязвимости чисто логические, недостаточно проверок и тестов. Но остается проблема ботоводства, которую надо решать. Вот те минимальные меры(практически калька с блога), которые бы отсекли бОльшую часть ботоводов и сделали бы мир чище:

1) STO — Security Through Obscurity, отсекает ленивых и школьников. Обфускация и шифрование — наше все!
2) Плохая идея возвращать участнику координаты верной точки в чистом виде. Решить проблему можно по разному: возвращать результат в виде изображения или маски над ним, преобразовывать в другую систему координат с меньшей точностью.
3) Добавить больше клиент-серверного взаимодействия, например нажатие клавиш, перемещение курсора, клики. Данная мера усложнит написание ботов для мини-игр и добавит данных для проведения обратного теста Тьюринга.

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

P.S. Все действия произведенные мной носят исследовательский характер, а выводы надеюсь послужат назиданием разработчикам промо.
Поделиться с друзьями
-->

Комментарии (11)


  1. darii
    16.01.2017 03:35
    -23

    Учитывая, что неофициальная рыночная цена 1 мили Аэрофлота колеблется от 50 до 65 копеек (в зависимости от объема заказа), спасибо за статью. И передайте наши искренние поздравления финалистке Ольге В.

    P.S.Задание на призовую игру.
    1. На какие статьи бюджета доходов и расходов следует отнести измеряемый материальный ущерб, причиненный ПАО «АЭРОФЛОТ-РОССИЙСКИЕ АВИАЛИНИИ» (ОГРН 1027700092661) с целью получения выгоды?
    2. Дайте правовую оценку действиям топикстартера. Назовите повод и основание к возбуждению уголовного дела в данном случае. Определите, в форме дознания или следствия будет проводиться предварительное расследование?


    1. mwambanatanga
      16.01.2017 08:18
      +6

      Топикстартер никуда не летал на эти «бесплатные мили». Ущерба причинено не было. А вот юзеру darii вполне могут нанести ущерб в репу и в карму. Так сказать, в качестве меры пресечения.


      1. fryday
        16.01.2017 08:29
        +3

        Более того, меня и нет в топе. Спасибо команде модераторов :)

        Стоит отдать должно разработчикам(а может быть модераторам), у них был неплохой антифрод и все сомнительные участники банились. Я не смог выяснить все параметры по которым производился анализ на фрод, но два из них мне известен: скорость и точность ответа.


      1. darii
        16.01.2017 14:59
        +7

        Парсер сожрал теги <irony> и первый коммент заминусовали. Ну, бывает. Но все равно «я просто не понимаю, как ты не понимаешь». Придется раскрыть тему совсем подробнее.

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

        Напоминаю историю, уже освещавшуюся на Хабре. Примерно 2 года назад некто Егор Х. по приколу нашел race condition на сайте Starbucks и честно сообщил о ней Старбаксу по адресу InformationSecurityServices@starbucks.com (в отличие от автора этой статьи, который судя по всему, сразу написал на Хабр). Несколько месяцев не было никакой реакции, а затем Старбакс начал вяло преследовать Егора на основании, цитирую, что последний совершил «fraud» и «malicious actions». Насколько мне известно, кроме хабровчан и Брюса Шнайера, «спасибо» Егору никто так и не сказал.

        По роду деятельности, мне часто приходится сталкиваться с юристами бэк-офисов некоторых крупных бизнес-структур, в том числе Аэрофлота. Я хотел бы воздержаться от ярких оценочных суждений, но опыт общения с этой публикой научил меня, что автор не только нашел на сайте Аэрофлота ряд небольших уязвимостей, но прежде всего поставил сам себя в уязвимое положение. Причем уязвимого положения можно было бы легко избежать, например, предварительно связвшись и согласовав свои действия с Аэрофлотом (а если не хотелось с ними связываться — хотя бы опубликоваь статью не по настоящим именем, а под псевдонимом, и также не указывать в своем профиле ссылки на социальные сети и т.д).

        Почему я утверждаю, что публиковать топик в том виде, в каком он опубликован — напрасный необоснованный риск, даже если про уязвимость больше не актуальна? При поверхностном рассмотрении действительно может показаться, что топикстартер никуда не летал на эти «бесплатные мили» и ущерба причинено не было. Но всего лишь одного заявления от Аэрофлота хватит на то, чтобы испортить автору нервы на целый год. А для этого достаточно, всего лишь навсего какой-нибудь маркетолог или даже SMMщик в Аэрофлоте посчитал предполагаемый ущерб и потрудился обвинить в нем автора публикации. Не верится? Почитайте судебные решения по ст. 273. УК РФ.

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


        1. fryday
          16.01.2017 16:05
          +1

          С тегом действительно не хорошо вышло.

          При публикации я ориентировался на отсутствие проблем автора статьи о предыдущем промо(@MadJeck)? на основании его последующих коментов. Ну и на минорсть уязвимостей и на отсутствии какого либо влияния на систему и итоговую расстановку сил.

          Учитываю нынешнюю судебную практику, в дальнейшем действительно стоит быть поосторожнее. Спасибо!


  1. leoismyname
    16.01.2017 08:10

    Добавить больше клиент-серверного взаимодействия, например нажатие клавиш, перемещение курсора, клики. Данная мера усложнит написание ботов для мини-игр и добавит данных для проведения теста Тьюринга.

    Это как?


    1. fryday
      16.01.2017 08:38
      +1

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

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


      1. leoismyname
        16.01.2017 10:19
        +1

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


        1. fryday
          16.01.2017 10:26

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


  1. ShinRa
    16.01.2017 08:39
    +1

    сарказм

    Скрытый текст
    russian hackers


  1. ddd66
    16.01.2017 15:38
    +1

    Еще вот такой вариант был:

    $(".map-opener").click(function() {
       var jqxhr = $.ajax( "https://maps.googleapis.com/maps/api/streetview/metadata?pano=" + Game2.leftPano.pano + "&key=xxx" )
          .done(function(data) {
             Game2.rightMap.setOptions({
                center: {
                   lat:  parseFloat(data.location.lat),
                   lng:  parseFloat(data.location.lng)
                   },
                zoom: 7,
                draggableCursor: "pointer",
                disableDefaultUI: true,
                minZoom: 2
             })
          })
       return false;
    })
    

    При нажатии на кнопку «послать самолет», карта сразу открывалась в нужном месте. Если не сильно спешить, то от реального человека поведение неотличимо.