На самом деле правильнее назвать статью «как накрутить себе баллы в конкурсе, чтобы выиграть целый холодильник RedBull». У нас, кстати, в офисе уже стоит такой холодильник с напитками.



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

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

Теперь надо надеть солнцезащитные очки, включить vpn, всевозможные прокси и т.д.

Перейдем к делу


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

http://redbull.ru/work
Будем отслеживать запросы в браузере, после этого попробуем эти же запросы отправить, но уже с измененными значениями.



Первым делом идет запрос на старт игры:

https://rb-prjct-crtns-gamebackend-eu.herokuapp.com/api/high-scores/games/8970c40a-98f0-4395-85c8-66177fb38af0/runs

При этом в ссылке замечаем id = 8970c40a-98f0-4395-85c8-66177fb38af0.
Пару раз обновляем страницу в браузере, открывает с другого ip и в другом браузере, этот параметр не меняется, предполагаем, что это константа-идентификатор игры.

Еще замечаем, что в параметрах заголовка типа данных

accept: 
application/vnd.api+json

В ответ на этот запрос получаем ответ:



{
    "data":{
        "attributes":{
            "finished_at":null,
            "game_day":114,
            "game_week":17,
            "score":null
        },
        "id":"4f89d56d-884e-42e8-909d-d1e7547cc1d8",
        "links":{
            "self":"https://rb-prjct-crtns-gamebackend-eu.herokuapp.com/runs/4f89d56d-884e-42e8-909d-d1e7547cc1d8"
        },
        "relationships":{},
        "type":"runs"
    },
    "included":[],
    "links":{
        "self":"https://rb-prjct-crtns-gamebackend-eu.herokuapp.com/runs/4f89d56d-884e-42e8-909d-d1e7547cc1d8"
    }
}

В ответе можно заметить разные атрибуты и еще один id = 4f89d56d-884e-42e8-909d-d1e7547cc1d8, который судя по всему является нашим персональным идентификатором игры.

Начинаем игру.



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



По завершению игры мы где-то в рейтинге, но мы не первые, что нас сильно огорчает. Пока что.
Смотрим в консоль и видим, что отправились еще 2 запроса, но один из них на получение статей, другой на получение рейтинга игроков. Полезного тут мало, запоминаем рейтинг первого места – 61454667.

Нажимаем на кнопку сохранения результата.



Отправился еще один запрос на url

https://rb-prjct-crtns-gamebackend-eu.herokuapp.com/api/high-scores/games/8970c40a-98f0-4395-85c8-66177fb38af0/runs/4f89d56d-884e-42e8-909d-d1e7547cc1d8/submit

с параметрами

{
    "data":{
        "id":"8970c40a-98f0-4395-85c8-66177fb38af0",
        "type":"runs",
        "attributes":{
            "score":11041900
        }
    }
}

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



На следующем этапе открывается страница с формой, которая подгружается в iframe. Замечаем, что в ссылке участвует наш сессионный id:
https://redbull.jotform.com/93071907238864&runid=4f89d56d-884e-42e8-909d-d1e7547cc1d8&runscore=11041900&redirect=https://maze.redbull.com

После отправки формы, получаем подтверждение.



Теперь повторим все те же самые запросы, но уже не через браузер.

Я буду использовать Postman.

Отправляем запрос на

https://rb-prjct-crtns-gamebackend-eu.herokuapp.com/api/high-scores/games/8970c40a-98f0-4395-85c8-66177fb38af0/runs




Получили ответ:

{
    "data": {
        "attributes": {
            "finished_at": null,
            "game_day": 114,
            "game_week": 17,
            "score": null
        },
        "id": "f95dad7c-eecf-4d3a-88e9-a32661a484e4",
        "links": {
            "self": "https://rb-prjct-crtns-gamebackend-eu.herokuapp.com/runs/f95dad7c-eecf-4d3a-88e9-a32661a484e4"
        },
        "relationships": {},
        "type": "runs"
    },
    "included": [],
    "links": {
        "self": "https://rb-prjct-crtns-gamebackend-eu.herokuapp.com/runs/f95dad7c-eecf-4d3a-88e9-a32661a484e4"
    }
}

Самое важное тут

id = f95dad7c-eecf-4d3a-88e9-a32661a484e4

Теперь формируем ссылку для получения рейтинга. Нам нужен будет наш сессионный id и результат, который будет больше текущего рекорда 61454667. Возьмем для эстетики первый цифры числа 2*pi, как раз чуть больше рекорда.

Отправляем запрос

https://rb-prjct-crtns-gamebackend-eu.herokuapp.com/api/high-scores/games/8970c40a-98f0-4395-85c8-66177fb38af0/runs/f95dad7c-eecf-4d3a-88e9-a32661a484e4/leaderboard?score=62831853&filter[interval]=none



В ответе видим, что мы уже первые в списке, теперь сохраним результат.

Отправим запрос на

https://rb-prjct-crtns-gamebackend-eu.herokuapp.com/api/high-scores/games/8970c40a-98f0-4395-85c8-66177fb38af0/runs/f95dad7c-eecf-4d3a-88e9-a32661a484e4/submit

В этом запросе важно еще прописать атрибуты заголовков.





Супер! Все прошло ок, получили подтверждение результата. Теперь необходимо отправить контактные данные, чтобы с нами связались RedBull.

Для этого просто в браузере открываем ссылку с формой с нашим сессионным id.

https://redbull.jotform.com/93071907238864&runid=f95dad7c-eecf-4d3a-88e9-a32661a484e4&runscore=61454667&redirect=https://maze.redbull.com



Заполняем форму.

Отправляем.



Получаем подтверждение!

Конкурс уже закончился, он действовал до 31 января 2020.

P.S. На момент публикации розыгрыш завершен, во время проведения акции мы в ней не участвовали, на победу не претендовали. Все описания носят только информационный характер. Никакие коммерческие и иные ценности этими действиями не преследовались.