Нам поступало немало вопросов о том, как же все-таки нужно было проходить квест «Да я тебя по IP вычислю!», который мы сделали совместно с «Авито». Квест, увы, более не активен, да и этот материал подзадержался. Однако мы верим, что интерес еще жив, поэтому расскажем вам о нашем увлекательном эксперименте.
Коллеги из «Авито» обратились к нам с просьбой найти среди нашей аудитории программистов, которые умеют работать с MongoDB, Redis, PHP и геоданными. Изначально мы планировали сделать обычный тест, но все получалось слишком просто — такой стек не проверить стандартным количеством вопросов. В какой-то момент Николай, наш программист, которому совершенно не улыбалось придумывать тестовые задачи, предложил сделать отбор в виде квеста — это интереснее и веселее. В общих чертах набросали сценарий, утвердили — и понеслась!
До конца должны были дойти только те, кто владеет всеми технологиями из стека (либо люди, готовые быстро изучать новое). Проблема заключалась в том, что последние шаги могли отпугнуть своей сложностью и необходимостью писать код. Нужно было максимально увлечь игроков, чтобы даже самым ленивым врожденное любопытство не дало остановиться.
Решено было делать игру максимально реалистичной, давая игроку погрузиться в атмосферу взлома, почувствовать себя если не хакером, то как минимум начинающим пентестером. На просьбу дать подсказку у нас был самый действенный ответ:
Программист Николай, как поклонник творчества Филипа Дика, решил сделать всю игру отсылкой к умению этого автора играть с реальностью, что в итоге вылилось в увлекательную забаву, озадачившую многих наших читателей (об этом мы расскажем ниже в разделе «Игры с реальностью»).
Вас встречает окно телеграма, в котором довольно дерзкий тролль сообщает о намерении вычислить вас по IP.
На сообщения тролль отвечает крайне редко и странно, подсказок не дает, хотя иногда троллит вас, скидывая рикролл или забавно отвечая.
Несмотря на то, что квест представлял из себя окно чата, болтать с троллем не было нужды — он всего лишь принимал ответы и давал инструкции по прохождению. А вот что действительно стоило сделать, так это внимательно рассмотреть ссылку, которую он прислал. В ссылке пряталось слово «redirect», да и сама она перенаправляет на картинку.
К разочарованию любителей rarjpeg, изображение было фотографией Филипа Дика (концепт!) с десятком фильтров. Даже в exif на всякий случай было оставлено послание о том, что это не подсказка. Зато при переходе в корень сайта пытливому взору наших читателей открывалась следующая картина:
В подобной ситуации многие веб-программисты рефлекторно полезут в код страницы — и окажутся правы, ведь невнимательный тролль забыл вырезать ссылку на консоль управления своим хакерским сокращателем ссылок. Кстати, довольно многие дошли до этого шага и, видимо, решили остановиться, рассматривая чудесные белые буквы на черном фоне.
По приглашению консоли многие сразу опознали Redis, присутствующий в стеке «Авито». Те же, кто не имел опыта работы с этой чудесной Nosql-субд, могли загуглить порт и, заодно, мануал, потому что придется немного покомандовать.
Итак, логичная последовательность действий в чужой redis-консоли (перед тем, как сдать баг по багбаунти, само собой):
> KEYS *
1) log:0xface8d
> GET log:0xface8d
(error) ERR wrong moon phase or incorrect reality for this command
По меньшей мере необычно. Предыдущая команда сработала, да и выглядит это как Redis, однако на get прилетает отлуп с несуществующим, но невероятно концептуальным кодом ошибки. Что же, можно предположить, что здесь иной тип данных, пробуем работать с этим как с хэшем:
> HKEYS log:0xface8d
1) 314159265358
2) 979323846264
> HGET log:0xface8d [hkey]
# ну или
> HVALS log:0xface8d
Восхитительно, это же база ip-логгера! Кажется, в качестве ключей хэша используется таймстэмп времени посещения, а в значениях лежат ip-адреса посетителей.
Адресов у нас два, то есть столько, сколько людей прошло по ссылке. Один из адресов, само собой, наш, а вот второй принадлежит нашему троллю, который, вероятно, проверял редирект.
Тот, кто к этому моменту уже понял пользу Убика, в курсе, что тролль испугается, если узнать, в каком он городе. «Вычислить по ip»-lite, так сказать. Тем же, кто не нашел подсказки, пришлось выяснять это путем проб и ошибок.
С помощью сервиса вроде ip2location.com можно было определить, что тролль находится в Будапеште. Штош, сообщим ему об этом.
Тролль не врет, по указанной ссылке действительно лишь ошибка 403. Однако, наиболее внимательные игроки могли заметить, что favicon у сайта отображается, а значит доступ к файлам в директории веб-сервера есть, просто он неправильно настроен, либо индексные файлы удалены. В такой ситуации первым делом стоит посмотреть /robots.txt, не увидеть там ничего полезного, после чего начать перебирать всевозможные имена файлов. Что удивительно, повезти должно примерно с первого раза: стоит указать несуществующий файл в адресной строке, как браузер предложит что-то скачать.
Это же данные для коннекта к какой-то базе Mongo! Более того, отсюда не видно, но в этом файле имеется некий алгоритм, который надо применить к данным из этой базы. Чтобы получить результат, достаточно написать скрипт, который подключится к базе и выполнит необходимый запрос. Результатом запроса станут координаты, которые ждет тролль.
Вот и все! Координаты таинственных заказчиков, кстати, указывали на офис «Авито» в Москве, ведь именно благодаря им появился этот «тест специально для тебя», о котором говорил тролль (концептуально настолько, что аж поверить сложно!).
Но подождите, мы всегда найдем чем вас удивить, мы ведь N+1. Дело в том, что у нашего квеста осталась одна веселая тайна. Все самое интересное всегда творится за кулисами, верно?
«Авито» нам полностью доверяли, дав свободу творчества. Мы очень ценим подобный подход, потому что только в этом случае можно сделать «как для себя», прорабатывая каждую мелочь. Мы старались сделать так, чтобы интересно было всем, включая тех, кто зашел просто из любопытства.
Игра не ограничивала действия, а плавно предлагала свои правила. Например, про Убика можно было узнать не только из книг. Каждый, просмотревший код на странице игры, видел такой комментарий прямо перед окном отправки сообщения:
Мы старались сделать все максимально реалистичным. Бот «печатал» сообщения лишь немногим быстрее реального человека, длительность его «набора» зависела от длины сообщения.
Еще один пример — консоль Redis. Мы сообщали каждому пользователю ip-адрес со случайным значением последнего октета, чтобы иметь возможность отследить неполадки; запоминали время посещения пользователя, делая вид, что тролль побывал на странице немногим раньше.
Эмуляция не была бы до конца достоверной, ведь игроки могли использовать маски, а вместо HVALS использовать HGET. За время работы в N+1 мы повидали от наших читателей немало логических ходов, поражающих своей изощренностью и изяществом. Проработать все варианты так, чтобы иллюзия не разрушилась, было бы довольно сложно, поэтому команда из консоли после парсинга обращалась к реальной базе Redis. Да, набор команд был ограничен, а общение шло через API языка, но игроки получали именно то, что ожидали.
Мы парсили текст сообщений, предусмотрев все варианты написания Будапешта как кириллицей, так и латиницей. Мы предусмотрели ответы настолько, что прошли тест Тьюринга...
Стоп, что?!
Возможно вы не знали, но во многие наши нестандартные тесты и игры мы добавляем разные забавные детали, отсылки и пасхалки. И этот раз не стал исключением.
Нашим великолепным программистом была создана система, которая пересылала от 10 до 20 процентов сообщений, изначально отправленных троллю, в специальный редакционный чат. Более того, редакция имела возможность ответить на эти сообщения — в этом случае они появлялись в чате так, будто их написал сам тролль.
Игроки были явно озадачены подобным. Их можно понять — мы привыкли, что робот может отвечать, но не привыкли к энтропии в его ответах. И совершенно непривычным кажется чатбот, который действительно
отвечает
на вопросы, понимая суть, проявляет инициативу, троллит с учетом контекста, а иногда и замолкает, будто обидевшись. Наш искусственный интеллект, обрабатывающий ответы, выглядел примерно так:
Сейчас можно признаться — иногда мы старались сделать вид, что с игроком действительно разговаривает робот: применяли шаблонные фразы, старались давать одинаковые ответы на повторяющиеся вопросы. А иногда давали волю креативу, беседуя, играя в города, помогая, подкалывая и отвечая на подколы. В чате творилось форменное безумие, но это было круто.
Оформление телеграма было скопировано с оформления телеграма нашего программиста с точностью до пикселя (ну почти). Вот настолько мы бываем дотошны. Кстати, линуксоиды, тут лежит emerald, в котором можно задать разные темы для темного и светлого оформления окон. Это ли не чудо?!
Нас почти поймали на нашу же удочку, скинув ip-логгер в чат к боту. Ссылка пробилась в редакционный чат, а телеграм запросил превью. Игрок очень удивился настоящему ip телеграма, а Николай кинулся делать ссылки безопасными. Это еще раз подтверждает наш тезис о том, что невозможно предусмотреть всего, если имеешь дело с пользователями N+1.
На ip-адресах тролля не было серверов, мы проверили. Что любопытно, судя по сообщениям и обсуждению в соцсетях, некоторые особо рьяные хакеры кинулись натурально взламывать последний IP в списке нашего псевдо-логгера. Кто-то даже подобрал пароль к роутеру. Мы не стали говорить ребятам, что этот ip принадлежит им, поскольку знаем, как дороги бывают маленькие победы.
HTML-код страницы игры был изучен вдоль и поперек. Особое внимание игроков привлёк meta-тег с именем «author», который указывал на меня. Тег ставится автоматически при создании любой статьи, никто про него не помнит, поэтому я очень сильно удивился, когда в ВК стали приходить десятки писем с просьбой дать подсказку к квесту. Узнав об этом, Николай предложил название (концептуальное, конечно же) для поста с прохождением; оно действительно прекрасно подходит!
Троллю трижды предлагали деньги, чтобы он сам сказал свой IP. Деловой подход!
Мы ни на секунду не забывали о безопасности пользовательских данных и старались снизить до нуля вероятность реального взлома. Из-за этого игра была раскидана по пяти серверам, два из которых были внутри виртуалок, запущенных на третьем сервере. Добавьте сюда вебсокеты, приправьте проксированием запросов и специфическими параметрами доступа, доведите до максимального приоритета — и получите по-настоящему злого админа.
Почти каждый день с момента завершения квеста меня просили рассказать о прохождении, однако мы случайно грохнули сервера с игрой, поэтому актуальные скриншоты пришлось делать в dev-окружении и искать в личной переписке.
За время жизни игры в чат было отправлено более 20 тысяч сообщений. Но это не точно, поскольку лог сообщений был на одном из серверов.
А вот это вот нас настолько удивило, что... Впрочем, лучше посмотрите сами.
Это был невероятно весёлый проект, в котором поучаствовали тысячи людей. Мы пообщались с вами устами тролля, а вы, надеемся, получили удовольствие от игры с реальностью.
Спасибо команде «Авито» за сотрудничество и помощь с MongoDB. Надеемся, что следующие проекты будут еще круче! Спасибо всем, кто общался с троллем и отдельный респект тем, кто прошёл игру до конца — мы делали все это ради вас.
P. S. Прочтите «Убик»!