Русский
Русский
English
Статистика
Реклама

Квест

Как создавался бекенд хакерской игры про уничтожение сервера

20.08.2020 14:16:33 | Автор: admin

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

Всего у бекенда игры было 6 архитектурных единиц, которые мы и разберём в этой статье:

  1. Бекенд игровых сущностей, которые отвечали за игровые механизмы
  2. Шина обмена данных бекенда и площадки на VPS
  3. Транслятор из запросов бекенда (игровых элементов) на ардуино и железо на площадке
  4. Ардуино, которая занималась управлением релешками, получала команды с транслятора и делала фактическую работу
  5. Фактические устройства: вентилятор, гирлянды, торшеры и прочее
  6. Фронтенд сам сайт Сокола, с которого игроки управляли устройствами

Давайте пройдёмся по каждой из них.

Бекенд игровых сущностей


Бекенд был реализован, как spring boot-приложение: оно имело несколько rest-контроллеров, websocket endpoint и сервисы с игровой логикой.

Контроллеров было всего три:

  • Мегатрон. Через GET-запросы отдавалась актуальная страница Мегатрона: до и после включения питания. Через POST-запрос лазер стрелял.
  • Мапинг тильдовских страниц, чтобы они отдавались по имени страницы. У тильды на экспорт выдаются страницы не с оригинальными названиями, а внутренним ID и информацией по соответствию.
  • Контроллер для капчи, чтобы отдавать псевдо-высокозагружающую сервер капчу.

Websocket endpoint использовался для управления гаджетами: лампами, гирляндой и буквами. Его выбрали, чтобы синхронно отображать всем игрокам текущий статус устройства: включено оно или выключено, активно или нет, какой цвет буквы сейчас горит на стене. Для того чтобы чуть-чуть усложнить задачу включения лазера, мы накинули авторизацию на гирлянду и лазер с одинаковым логином и пароль admin/admin.

Игроки могли протестировать его на включении гирлянды и повторить то же самое на лазере.

Нами была выбрана настолько тривиальная пара логин-пароль для того, чтобы не мучить игроков лишним подбором.

Чтобы сделать задачу чуть поинтересней, в качестве идентификаторов устройств в комнате использовались object ID из mongodb.

ObjectId содержит в себе timestamp: два случайных значения, одно из которых берётся на основании идентификатора устройства, а второе на основании pid-процесса, который генерирует его и значение счётчика. Хотелось сделать идентификаторы сгенерированными через равные промежутки времени и с разными pid-процессов, но общим счётчиком, чтобы подбор идентификатора устройства лазера был интереснее. Однако в итоге все запустились с идентификаторами, различающимися только в значении счётчика. Возможно, это сделало этап слишком простым и не требующим анализа структуры идентификаторов objectId.

Транслятор из запросов бекенда


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

Скрипт подключался к очереди RabbitMQ и передавал запросы из очереди на Ардуино. Также на нём была реализована логика параллельного включения света: вместе с некоторыми устройствами на них включался свет, например, при первичной подаче питания на Мегатрон, он подсвечивался сценическим светом. Дизайн света для кинематографичности всей сцены отдельная история про большую работу нашего сопродюсера проекта и художника-постановщика Ильи Серова, и про неё мы расскажем в отдельном посте.

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

Как была устроена логика генерации токена мегатрона


Тестовый выстрел


Каждые 25 секунд генерировался новый токен, его можно было использовать, чтобы включить лазер на 10 секунд на мощности 10/255. Ссылка на гитхаб с кодом Мегатрона.

Затем лазер охлаждался 1 минуту в это время он был недоступен и не принимал новые запросы на выстрел.

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

Для генерации токена использовался алгоритм хеширования MD5. И схема получалась MD5 от MD5 + счётчик + секрет для боевого токена и без секрета для тестового.

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

Боевой выстрел


Боевой режим Мегатрона это 100% мощность лазера в 3 Вт. Этого вполне достаточно на 2 минуты, чтобы пережечь верёвку, которая держала гирю, чтобы разбить аквариум и залить сервер водой.

Мы оставили несколько подсказок на гитхабе проекта: а именно код генерации токена, по которому можно было понять, что тестовый и боевой токены генерируются на основе одного показателя счётчика. В случае боевого токена помимо значения счётчика ещё используется соль, которую почти полностью оставили в истории изменении этого gist, за исключением двух последних символов.

Зная эти данные, можно было перебрать 2 последних символа соли и фактически выяснить, что для неё использовались числа из Lost, переведённые в 16-ичную систему.

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

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

Сервис взаимодействия с капчей


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



Сервис подсчитывал, что отображать в мониторинге как текущую нагрузку: температуру и CPU Fan. Метрики передавались в timebase database и отрисовывались графаной.

Если за последнее 5 секунд поступало более 50 запросов на отображение капчи, то нагрузка росла на фикс + рандомное количество шагов. Расчёт был на то, чтобы 100% нагрузку можно было получить за две минуты.

В самом деле логики в сервисе было больше, чем отобразилось в конечной игре: мы поставили монитор таким образом, что было видно только вращение CPU Fan.

Графану в начале квеста хотели оставить доступной с сайта Сокола. Но в ней были также springboot-метрики по отчёту бекенд-приложения, которые мы не успевали вычистить, поэтому решили закрыть доступ к ней. И правильно ещё в начале квеста некоторые игроки догадались, что приложение написано на фреймворке springboot и даже откопали название некоторых сервисов.

Хостинг и шина обмена данных


Инструмент передачи информации с бекенда на площадку, VPS-сервер на котором было запущено RabbitMQ.

Бекенд и шина данных держались на . Его мощность была сопоставима с компьютером, который вы видели на экране: 2-х ядерная VPS-ка с двумя гигабайтами оперативной памяти. Тариф брали за ресурсы, поскольку пиковая нагрузка планировалась всего несколько дней так и поступают наши клиенты, которые планируют нагружать VPS на короткий срок. Потом оказалось, что нагрузка оказалось выше, чем мы предполагали и фиксированный тариф оказался бы выгоднее. Будете делать квест выбирайте тарифы линейки .

Чтобы защитить сервер от DDoSa, мы использовали Cloudflare.

Стоит сказать, что VPS с честью выдержала всё.

Ардуино, которая занималась управлением релешками, получала команды с транслятора и делала фактическую работу


Это больше тема следующей статью про хардварную часть проекта: бекенд просто присылал запросы включить конкретное реле. Так вышло, что бекенд знал почти все сущности и запросы с него, выглядели как включи эту сущность. Мы делали это для раннего тестирования площадки (пока ещё не собрали все Ардуино и реле), в итоге так всё и оставили.

Фронтенд


Сайт мы быстро создали на тильде, это заняло один рабочий день и сэкономило нам тысяч 30 бюджета.

Изначально мы думали просто экспортнуть сайт и накинуть нехватающую нам логику, но нарвались на terms of use, которые нам это запрещали.

Мы не были готовы нарушать лицензию, поэтому было два варианта: сверстать всё самим или напрямую связаться с Тильдой, рассказать о проекте и попросить разрешения менять код.

Мы выбрали второй вариант и они не просто пошли нам навстречу, а даже подарили нам год бесплатного бизнес-аккаунта, за что мы им очень благодарны. Было очень неловко показывать им дизайн сайта Сокола.

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

Дизайн сайта


История поисков, которая стоит отдельной главы.

Мы хотели создать не просто старомодный сайт, а абсолютно тошнотворный, нарушающий все базовые правила дизайна. При этом было важно сохранить правдоподобность: он должен был не ломать ЛОР истории, демонстрировать претенциозность автора и игроки должны были бы поверить в то, что такой сайт может существовать и даже приводить клиентов. И привёл! Пока шла игра, нам дважды обращались за созданием сайтов.

Сначала дизайн делала я сама, стараясь воткнуть побольше гифок и блестящих элементов. Но мой муж-дизайнер с 10-летним стажем, заглянув через плечо, забраковал его как слишком хороший. Чтобы нарушать правила дизайна, надо их знать.



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

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

Фактические устройства


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

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

Stay tuned!

Остальные статьи про квест с уничтожением сервера


Подробнее..

Спаси котика из-под рояля

21.05.2021 14:10:59 | Автор: admin

Вашему другу нужна помощь. Точнее, не вашему, а гипотетическому. Или даже не другу, а котику хотя котик же не настоящий Чёрт, короче! Наверняка у многих из вас в жизни была такая бывшая, расставание с которой было как закрытие ипотеки: Господи, ну наконец-то!. И вот всё наконец-то закончилось, осталось только забрать свой ноутбук с очень важным NFT-токеном гифки с танцующим котиком. Этот котик дорог вам как память и как произведение цифрового искусства. Но ипотека теперь уже бывшая устроила в отместку целое шоу: протерла ноутбук от пыли, приготовила всё, чтобы залить его жидким азотом и подвесила над ним РОЯЛЬ.

Ну да, вот поэтому у вас вашего друга было такое счастье и чувство свободы от расставания с этой эксцентричной!

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

А 28 мая в 12.00 (МСК) ноутбук будет заморожен и расплющен силой гравитации и роялем.

Ее манифест смотрите на видео:

Ваша задача:


  1. Получить удаленный доступ к ноутбуку.
  2. Запустить скрипт копирования NFT-токена на резервный сервер RuVDS в Швейцарии (подальше от этой сумасшедшей).
  3. В час Х посмотреть, как упадет рояль, и поздравить себя друга с тем, что эти абсурдные отношения наконец-то закончились.

Первые 3 игрока, которым удалось запустить скрипт копирования получат 1000$, 200$ и 100$.

Подробнее об операции спасения танцующего котика на сайте проекта.

Поможете?


Подробнее..

Котики в NFT революция в цифровом мире или хайповая пирамида?

24.05.2021 14:14:07 | Автор: admin
Коллаж из картинок художника beeple держит сегодня рекорд по стоимости среди всех проданных цифровых NFT-произведений.

NFT одна из самых горячих тем в мире блокчейна. Кто-то уже заработал на них миллионы долларов, кто-то потерял сотни и тысячи. Одни называют NFT революционным изобретением, которое изменит сферы разработки игр и наше восприятие цифровых (нематериальных) объектов. Другие недоумевают, как можно вестись на такой развод и платить мошенникам деньги. Но вне зависимости от того, кто прав, факт остаётся фактом: NFT сейчас на слуху, и их оборот достиг уже очень внушительных сумм.

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

Что за NFT такое?


NFT расшифровывается как non-fungible token, то есть невзаимозаменяемый токен. Идея в том, что есть взаимозаменяемые объекты, которые полностью идентичны друг другу например, один рубль равен другому рублю, а есть невзаимозаменяемые объекты, каждый из которых уникален и неповторим. Скажем, когда вы пришли в магазин и купили новые кроссовки, они в этот момент взаимозаменяемы: полностью идентичный любым кроссовкам того же размера. А когда вы их поносите, то эта пара станет уникальной за счёт невоспроизводимых потёртостей и прочих изменений, то есть кроссовки станут уникальными других таких же во всём мире нет, есть только похожие.

На принципе уникальности держится вся торговля предметами материального искусства. Например, даже если художник нарисует точную копию какой-либо картины, пусть и своей же, это всё равно будут две разные картины, хоть и очень похожие. А электронные объекты обычно взаимозаменяемы Ctrl+C, Ctrl+V, и вот у тебя уже идеальная копия какой-нибудь гифки или песни, попробуй найди два отличия.

В результате придумали NFT это блокчейн, который можно прикрепить к любому нематериальному объекту картинке, видеозаписи, музыкальному файлу, предмету в игре и тем самым заявить, что этот объект уникален и принадлежит только вам. Скопировать такой объект можно, но выдать за свой уже не получится ваш NFT не позволит. Эдакий сертификат уникальности. Прикрутить токен можно не только к цифровому, но и к материальному объекту. За это нужно благодарить смарт-контракты Etherium, именно эта крипта лежит в основе большинства NFT.

Сегодня за цифровые произведения искусства с NFT уже платят десятки миллионов долларов. Рекорд пока что у художника Майка Винкельмана, выступающего под псевдонимом Beeple его коллаж из 5 тысяч изображений на аукционе Christie продали аж за $69 млн. За цифровую картинку с токеном:


Другой известный пример продажа NFT мема с летающим котиком:

Этот мем продали за 580 тыс. долларов. Не спрашивайте, зачем. Мы сами недоумеваем.

Вот ещё: компания Injective Protocol подогрела NFTхайп, купив у Бэнкси картину за $95 тыс., прилюдно сожгла её и привязала к цифровой копии NFT. Теперь этот набор пикселей принадлежит компании, которая объявила его настоящим произведением криптоискусства.

То есть NFT успел стать важным фактором в торговле произведениями искусства разной степени ценности (или сомнительности). Существуют разные электронные площадки, на которых все желающие могут покупать и продавать NFT. И цены на них сильно варьируются. Однако есть важный момент: в NFT хранится не сам цифровой объект, а только его описание и свидетельство собственности. Это уже приводит к забавным ситуациям, когда кто-то покупал токен, причём за вполне себе ощутимые суммы, а сам объект неожиданно исчезал.


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

Большую популярность NFT снискали в мире игр. Токены прикрепляют к различным игровым объектам оружию, доспехам и прочему добру и продают как уникальные объекты, имеющие конкретного владельца внутри конкретной игры. Владельца не авторских прав, а игрового предмета. Некоторые поклонники NFT мечтают о светлом дне, когда токены станут универсальными и можно будет применять в играх предметы из других игр. Купил себе автомат в каком-нибудь шутере, а потом зажёг с ним в фэнтезийной РПГ.

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

Образец дегенеративного криптоискусства, за который кто-то заплатил пару десятков баксов.

А пока что вы можете совершенно бесплатно заполучить классную гифку с NFT, которая скоро может быть безвозвратно уничтожена совершенно варварским способом. Причём уничтожена вместе с хорошим дорогим ноутбуком и отличным роялем. Все подробности тут.


Подробнее..

Музыкальная криптография

26.05.2021 18:20:11 | Автор: admin
Несколько столетий назад когда именно, доподлинно вряд ли известно, возник любопытный метод шифрования информации: с помощью нот. Точнее, с помощью их буквенного обозначения. Как вы знаете, ноты могут обозначаться не только классическими закорючками:


Но и буквами латинского алфавита: A, B, C и так далее. И когда-то, кому-то пришло в голову, что можно вставлять в музыкальные произведения, короткие последовательности нот, которые в буквенном выражении обозначают чьи-то инициалы или даже слова. Этот метод шифрования информации называется музыкальная монограмма.

Есть несколько подходов к созданию музыкальных монограмм. Например, слоговый: гласным буквам в тексте присваивали фонетически схожие названия нот. Считается, что в этом произведении Жоскен Депре, живший в 15-16 веках, закодировал нотами фразу laisse faire moy не мешай мне.

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

Немецкий метод применялся ещё в 18 веке. Во-первых, у немцев иной порядок букв для обозначения нот: до-ре-ми-фа-соль-ля-си у них обозначаются как C, D, E, F, G, A, H. А во-вторых, недостающие буквенные обозначения они получали за счёт фонетического сходства: допустим, нота E могла кодировать как букву s, так и слог es. А в начале 20 века появился французский метод: одна нота могла кодировать сразу несколько букв алфавита в соответствии с простейшей таблицей (в шапке обозначения нот):


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

Здесь во вступлении нотами B-A-C-H закодирована фамилия Ивана Севастьяновича Баха:


Это не находка Листа, а дань уважения, Бах сам часто вставлял эту последовательность в свои произведения. К примеру, здесь:

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

Другой популярный пример: Шуман разбросал по всему своему Карнавалу нотную последовательность A-Es-C-H, которая обозначает его монограмму SCHA и название города ASCH, где он впервые влюбился.

Любопытный образец музыкального шифрования фраза берегись Лядова, записанная Николаем Мясковским в его Квартете для струнных No. 3: B, D, G, A, C, F = B, Re, Gis, La, Do, Fa. Лядов преподавал в Петербургской консерватории музыкальную композицию.

А в Сонате F-A-E, посвящённой скрипачу и композитору Йозефа Иоахиму, зашифрована фраза Frei aber einsam Свободен, но одинок:

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

P.S. Кстати, напоминаем про наш квест: https://royal.ruvds.com/.
Сегодня утром был перерезан второй провод и вероятность преждевременного падения рояля на ноутбук все выше. Сейчас его удерживают всего 3 троса, а тем временем победителя, который прошел бы квест и спас котика, все еще нет!

В эту пятницу 28 мая в 12.00 ноутбук будет залит жидким азотом и на него обрушится рояль массой 500 Кг.


Как подсказывают наши эксперты (главный инженер здания), пережить падение рояля ноутбуку будет очень непросто. Вернее, если дословно, то Петрович оценил ситуацию как ноутбуку ****ц.

Если вы находитесь в ступоре, то вот вам маленькая подсказка. Перечитайте пост выше и посмотрите на клавиши рояля на сайте




Подробнее..

Хроники котика брутфорс рояля, крыса-кун и деанон Оксаны

27.05.2021 18:04:31 | Автор: admin

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

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

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

К исходу вторых суток ребята исчерпали все идеи и сникли, как вялые корнишоны, чаще стали говорить о том, что шибко сложные конкурсы у тамады:









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



Потом пошли идеи позаковыристее:
Как вам варик задеанонить эту е*тую Оксану, подломить ей инсту, вытащить оттуда что-нибудь пикантное и шантажировать ее, что бы отдала нам ноут?
на форумах заказываем пробив сотового номера Оксаны, а к нему пробив координат ближайшей соты, приезжаем на адрес завтра до 12:00, ждём появления звуков болгарки для детекта помещения, устраиваем аварию на электросети и режем оптику, в суматохе проникаем в помещение бригадой в форменной одежде и втыкаем в ноут USB-троян (злоумышленную клавиатуру), но чот приз маловат, жаль. не разгуляешься на килобакс.
Есть вариант лучше! Берём в заложников детей сотрудников ruvds и требуем от них ноутбук
Вот так и выглядит отчаяние: интеллектуалы-айтишники уже готовы опуститься до популярнейших статей УК. \_()_/





Конечно :))

Пришлось быстренько написать пост-подсказку. Правда и это помогло не сильно:
Мы пока не поняли как эту подсказку использовать. Мы в принципе сам смысл поняли, а к чему именно нужно применить подсказку, не поняли.
К вечеру уже обвиняли друг друга:
Классический крыса-кун. У него PuTTy и ssss уже готовы к операции
да он по любому организатор под прикрытием, потом бабки залутает

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

На этом пока всё. Ребята наконец-то немного продвинулись вперёд и бьются над решением следующей задачи. Будем держать вас в курсе новостей.

P.S. Умилили такие цитаты:
Есть какой-то рассказ Neuromancer, фразы из него выдернуты в разном порядке и из них собрали эту новеллу
а ещё клавиши обозначены как do re mi
Похоже на французский
я кажется понял мысль, только поймать не могу


Подробнее..

Финал квеста и победители особенности криогравитационного воздействия на портативные ЭВМ

29.05.2021 00:21:04 | Автор: admin
Это было познавательно. Ноутбук вспучивался и потрескивал под струёй азота. Умер он тихо, без искр, мигания и прочих спецэффектов, настоящий был боец. А котик даже мяукнуть не успел, когда полтонны живой рояльной массы почти перерубили ноутбук пополам.

Операция по спасению танцующего котика закончилась. Удалось ли его спасти и как прошли последние минуты жизни ноутбука и рояля об этом под катом.

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

Вот как это происходило:



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


А NFT-гифка с танцующим котиком погибла, не выдержав столкновения с суровой реальностью.



Однако.


Незадолго до криогравитационной обработки ноутбука, в 10:37, под прикрытием тишины на один из отдалённых серверов прокрался спаситель котика с очень редким и оригинальным ником Александр. Как вы помните, ноутбук уже был хакнут, и злодеи успели слить всю инфу на этот самый сервер. Саша из Екатеринбурга, ты был первым! В 11:04 он ещё раз потоптался на сервере, наверное, что-то забыл скачать.

За Александром в 12:08 в святая святых проник not-alone и занял почётное второе место!


А третьим стал lofarter, он зашёл на сервер в 12:43. В это время ноутбук уже был мертв, но мы, так уж и быть, присуждаем ему третье место!

Ребята, от всей души спасибо вам за то, что танцующий котик выжил! Кто-то из вас переправил его за кордон, подальше от этой взбалмошной дамочки, и тем самым обогатил мировую поп-культуру! Да что там, возможно, и мировое цифровое искусство.

За это мы с большой радостью хотим вручить вам ваши заслуженные призы. Пишите нам.

За сутки до падения рояля было немало интересных моментов. Например, полная неожиданность:



Да, бонусный (9-й) ключ был спрятан под банальным RuVDS, закодированным обычным немецким методом, и все, кто догадался ввести на клавиатуре комбинацию 4 7 1 4 5, получал его в чистом виде. Был ещё один, бонусный, десятый ключ, но подробнее обо всех ключах и прохождении квеста мы расскажем в среду, ждите анонса.

Любопытные версии:






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

Всем, кому это удастся, мы подарим промокоды на скидку в 50 % на подписку журнала Хакер. Это поможет вам к следующему квесту быть во всеоружии :) И заодно в среду мы выложим решения всех загадок и разберём данные нами подсказки.

Подробнее..

Финал рояля разбираем загадки и подводим итоги

02.06.2021 18:06:54 | Автор: admin
Котика разбили, рояль спасли точнее, наоборот: котика скачали с сервера, роялю поломали ножки, но в целом он бодрячком. И сегодня был последний день, когда все желающие могли попробовать свои силы в скачивании NFT-гифки с танцующим котиком, хотя ноутбук уже пять дней как двинул лапти за печь. А теперь мы вскрываем все карты и рассказываем обо всех загадках и их решениях.

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

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDMyK0W5OMnzJFszo5ClCVbqAQ6s1NWYeast+WjIyWF7

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


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

Для надежного сохранения измененного SSH-ключа, хакерская группа разделила его по схеме Шамира на 10 частей, из которых 8 были необходимыми для входа в ноутбук. 9 ключей были распределены среди хакеров, а 10-й, бонусный, мы вставили вне сюжета (об этом ниже). И участникам нужно было решить несколько задач, получая за каждую из них по фрагменту правильного приватного ключа. Сами задания были в виде случайных промашек хакеров.

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

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

Задание 50n1c4h0


Часть ключа:
ssss-01-5dc6284446d3f3ae3d2b9e12167a118708f08686474e6471d178703938e3bc043796c79f72853a2cd77d2e956e41490b9b961a526f4911527bfe14c24f0022ce31a52f5fc118ca1dd1c1f0

Категория задания: crypto, re
Гуглим ник, в итоге находим фотоальбом (проиндексированные во время квеста ссылки на него на Pinterest или Juxtapost) и сайт https://50n1c4h0.netlify.app/ по одной из фотографий в фотоальбоме, рекомендующей использовать этот сайт:


Сайт протектор для защиты конфиденциальных данных. Внутри него доморощенная 16-битная виртуальная машина с байткодом, немного накрытая обфускатором. Программа для этой машины реализация поточного шифра RC4 с ключом 4c524338f5169e91e0cc05971f5b9b6e (hex). На фотографии из фотоальбома показан результат работы протектора над искомой частью ключа (из QR-кода декодируем:

6efb5c8eaf511770715681cac161b49f45ad9c12837ae41b35639653fcbc03e55e16a5d4953ba1fee6f8d4a3606b0751fd6d6a0b8e14200f4ed78943d4553d0bebfabcb8c0e30fa3580ab08899edbadd878b6e7c033febf6679558d1511c74f8d9ca54ef4c646a08f1bfeefe1a3b7884d3f2c94ee14649dcdc11591b8a8b0a005c80a8ce4b7c3dde988d59065ec574ad194fdc204137fc6748994942237e).

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

Можно было пойти и другим, криптоаналитическим путём: заметив, что выходной байт шифротекста зависит только от позиции и значения входного байта и не меняется (например, байт 0x41 на позиции 1 будет всегда преобразован в 0x39, байт 0x42 в 0x5F и т.д.), можно было побайтово подбирать входные данные под известные из QR-кода выходные, таким образом также получив искомую часть ключа, байт за байтом.

Задание GemmadohA


Часть ключа:
ssss-02-8e8425381bc24f44cbdefdae711d91c0a733350e949827f66a0ee00a5301afc3f68aad0a69e1b3d93465e70db0675089dd27fd993efe39bc881ad00b19d6055b856e9853af0b681213cb81

Категория задания: почти pwn
Мы не могли оставить в стороне прошлый квест (подробнее о нём читайте тут) и решили использовать сайт студии Сокол как дань уважения тем участникам, которые дни и ночи пытались спасти деньги из пасти прожорливого шредера.

Заходим на сайт https://ooosokol.ru/ (намёк на этот проект был в сообщении хакеров). Видим, что сайт уже взломал хакер GemmadohA. Также он оставил там веб-шелл (есть в комментарии в странице дефейса, чтобы не забыть). Логин и пароль для веб-шелла:gemmadoha:gemmadoha, почти как классический admin:admin.

Хакер также создал на взломанном сервере себе аккаунт. Приватный ключ от него с сервера не убрал (/home/gemmadoha/.ssh/id_rsa), поскольку генерировал на нём же. Читаем веб-шеллом приватный ключ, заходим на сервер ooosokol.ru по SSH.


Видим, что хакер всё еще висит (подсказка что если хакер всё ещё на сервере, он же только недавно его взломал в Discord) по SSH (с IP 194.87.236.30), что-то копается в файлах. Для него висит сокет агента SSH в /tmp, это можно обнаружить, просто поискав все файлы, владельцем которых является хакер (а чтобы не тратить зря время на попытки повышения привилегий, в Discord была дана подсказка то, что вы ищете не на этом сервере).

При помощи команды:

SSH_AUTH_SOCK=/tmp/ssh-5j3MjI6mby/agent.23577 ssh gemmadoha@194.87.236.30

используем его SSH-агент против него самого (хакаем хакера, в Discord была дана подсказка hack the hacker) и заходим на его же сервер. В домашней папке лежит очередной secret.txt.

Задание thereane777


Часть ключа:
ssss-04-44ed995def2ab783d02fdd783c528a347f29adc494130b65827721002fe47d0b5d3f29cf55620b596c49f23652cb4648cb3c7b5c605d5a9e2f0f3c46f32894c9980d028a7e7b33f8c8c48b

Категория задания: misc
Гуглим ник, попадаем в темы на хакерских форумах, где зарегистрирован этот хакер.

В описании профиля хакера указана ссылка на Яндекс.Диск для полезной информации: https://disk.yandex.ru/d/kQ9MPqO3anRiTA

На диске среди всяких полезных программ (клиенты ICQ) находится запароленный архив icons.zip. Пароль от него: v1pPGOuPS8HXFrS (длинный и неподбираемый). Без знания пароля видно, что в архиве два файла .png (картинки) и интересный файл secret.txt.

Задание решается без знания пароля по малоизвестному, но всё же все еще актуальному методу zip known plaintext attack при помощи программы bkcrack (наследница pkcrack). Именно для реализации этой атаки в архиве лежат две случайные PNG-картинки (их содержимое участникам неизвестно, да это и не требуется, однако найти в интернете их тоже можно), поскольку их заголовок, первые 16 байт которого одинаковы для любого PNG-файла, и является достаточным (там достаточно всего 12 байт, причем даже необязательно последовательных) для проведения атаки.




В результате получаем ZipCrypto-ключ dd8d62b4 83fed681 6761bbc1, при помощи которого открываем архив и получаем содержимое файла secret.txt, в котором лежит искомая часть ключа.

Задание y4n4naby5


Часть ключа:
ssss-05-9b5f9fef9cf5d85d206ed65b4a645888f6409b79c956309a2f1860daa0c4d8cd23113fdcee5fa5575ff7e9398d061eed52c62eee743f77c569c861fb1ade55a2149dc05a9f2e4f2e18bad5

Категория задания: forensics
Гуглим ник, находим (во время проведения квеста находилась) тему на форуме с просьбой о помощи по вскрытию Wi-Fi сети с именем DIR-615 y4n4naby5 (видимо Wi-Fi искомого хакера). В сообщении приложен дамп трафика, который необходим для подбора пароля к Wi-Fi сети (четырёхкратное WPA-рукопожатие).

В теме на форуме выложен дамп трафика Wi-Fi сети, и в дампе информации даже больше, чем необходимо для подбора пароля. Пароль же подбирается по старому, очень известному (он даже включен в самый известный пентестерский дистрибутив Kali Linux) и применяемому при первом же удобном случае при практически любых подборах словарю RockYou. Этот пароль fireheart79 (был успешно подобран участником форума). Подбор займет не более часа на современном процессоре (никакие видеокарты не нужны) при помощи того же hashcat.

Знание пароля также позволит и расшифровать ненужный WiFi-трафик при помощи того же Wireshark, и увидеть, что за данные передавал хакер. Кроме мусора (обмен данными с серверами Alibaba и Google) можно заметить интересное подключение по протоколу FTPS (FTP поверх SSL/TLS) к серверу soclose.numbers.com (такое имя не зарегистрировано, это и не важно, а IP вообще подделан на один из IP Google). TLS, как известно, шифрованный протокол, однако параметры без каких-либо дополнительных специальных настроек (сервером был vsftpd, а клиентом andftp) оказались такими (TLS 1.2 без использования выработки общего секрета по схеме Диффи-Хеллмана), что для расшифровки трафика из дампа нужен лишь приватный ключ сервера (если задействовать схему Диффи-Хеллмана, то это было бы невозможно без дампов памяти клиента или сервера). Параметры ключа сервера (RSA-2048) подобраны так (p и q близки друг к другу), чтобы быть подверженными атаке по методу факторизации Ферма. На это есть намек в имени сервера (so close numbers). Атака выполняется мгновенно при помощи той же RSACtfTool, и дает

p = 133205738301055492415292455053957573761950370019465363197330018804911429748841372623440097998280840848577224963374030102174633719338576372412863025595291812898461741802590180711710007911941796139236802646966981084378380345280502967196789430710224184344783160032007107024729298554505470658071546418304653261811

q = 133205738301055492415292455053957573761950370019465363197330018804911429748841372623440097998280840848577224963374030102174633719338576372412863025595291812898461741802590180711710007911941796139236802646966981084378380345280502967196789430710224184344783160032007107024729298554505470658071546418304653247279

А соответственно и приватный ключ:

-----BEGIN RSA PRIVATE KEY-----MIIEoAIBAAKCAQEAjI7G8TjcvnASyKj8jlnIC8mj2BjCISJRKa91xVC2ATA6dgJQVq12wxCJ/4tvG/GHv4mtTF3T5EASTUD+KSIjGPxakcXFEF13VfNS6C0TwyBH5+yZ/f5AdzTPDqF2ScZQ1J461NVOscZN9eXU5JGO/b+NpP/QZ2Od4E3WBTfP1zpBSAnoVOLs3TjWSAfW1AY6uEBS2NKT0VMRSya2u57ZdPkC2+pH1NG9GW6CR4KR2RVT2vdFCOEyMNSixhklBdVNNIHkZYQH0NMt4FUfY5bE9W6wBvUtzIEVqNXCQv3IC6tmPYIgvy8FquGNln1mFr7+H4TMaoIlz4LYdK2UwtBanQIDAQABAoIBAHTRZT6uh6gu9S2YZO7aZ4yEdYvwZ8eqAdKnZTYssleigbP6kFK5sG7GnCqq9BlBUBU8k69Ye/bD2XIjhhkhqhHmClAFEpdbVwc0R793V2lgtuJmnkWevm1UkpISV4FRNXTAXRzue4z8x2aLMbkV0MXMIij0A30qKdh2WF3V2QOCx9dLjuL5AZ6B4keOYz3mKbp1fzU/xWzEgSaJqBtcf4qZcj/c3Kov+3i3/WDXu4phCYVi/JpBok0zTKiMLFJ+xqISabd8yZJb5hViVSu9YRyu4H1rg3N6a5Ukdgp56F3kW4sur6KsftQmLShdgGctF+SBF7ZiKcfkT9oXtQ0guvECgYEAvbD27ue9r5qmuBX4WdqtbM6tEGm5q914wKnpbTb1ZNp2fzoSU3ticfpUpxvsFQy8P8SB0Lv6sTzC6wfPhGVMnXa4HE5NrZ4jtXdk1dxaC/TvaYGeHpTj/fGARDDRXBlbXVFgnPnC3EOUATWD5obWtaJg5HOSZwMFJB1ehPWc+/MCgYEAvbD27ue9r5qmuBX4WdqtbM6tEGm5q914wKnpbTb1ZNp2fzoSU3ticfpUpxvsFQy8P8SB0Lv6sTzC6wfPhGVMnXa4HE5NrZ4jtXdk1dxaC/TvaYGeHpTj/fGARDDRXBlbXVFgnPnC3EOUATWD5obWtaJg5HOSZwMFJB1ehPWcwy8Cf0Kv9CAJWKZjuDj/gFAWkOGvxyf+A0holAsnsOi0aZELPJ19zPOMbQ+k8h3NszGzSHsimoDHlVq6Acye8lWZR1YUZqWM4cIn1mX1k32b+gw6D/EHoI8fyQd935oZj4DRaU1lTpHhPKAzIdVK+xQQU2uHqoimGNIePbB0osYbkxUCgYBwECTBnNx96pJFvIz8oGjGGA873AnZk7xrrbV+VPKCA2Hv5aG/+et9xFLQanl9Mgngbjn206bVoDzS1slswN+TQvifmE7hm8Qix4clpMj5uVja7r03+eP7OPn6zxBQJZbJOXMnKZJJyA6e7DuhK9WadnRhYjmCa9FUtZkKWYOj9wKBgCzJOfLSMgROqzznGTesCXueTI0NnecG7WvZehtRc0LHEAiC12e9YvCqj7AoJsZBfec+IGk2vX8AunUKvYUZL2J7WfCyp57Kj1YgnEyikTVPsOEwjb5lALK1FwITxTH7xPD8OVIW0eQPvmhczoMKYPQG0mtZk+QkPr9dv0YcvwNB-----END RSA PRIVATE KEY-----

С ним расшифровываем TLS-трафик (снова тем же Wireshark) и получаем содержимое заливаемого по FTPS файла secret.txt, в котором лежит искомая часть ключа. То есть выполняем два шага: взломать WPA и взломать TLS.



Задание m0x143y


Часть ключа:
ssss-06-ad1a38b7f24f17489ef204207f7c3b8cf17032b316d5cb9d123619d209676ad6e7ba567c33ac41376876265a70f45f73a991cb6e9100b0df4b8b102a51a147dc6d641cf8bbbecd07321e0b

Категория задания: forensics
Гуглим ник, находим (во время проведения квеста находилась) тему на форуме с просьбой проверить ошибку при открытии тома TrueCrypt:




В сообщении на форуме написано, что возникает проблема при открытии определенного TrueCrypt-тома. Дан скриншот ошибки и ссылки на файлообменники, на которых лежит сам контейнер и дамп памяти для отладки проблемы. Пароль на контейнер длинный и неподбираемый: uBocLXywprQ9VJ6jxpYP. Однако есть дамп памяти, и, например, при помощи volatility-плагина truecryptmaster можно извлечь мастер-ключ TrueCrypt-а (truecryptsummary выдаст, что том был смонтирован и пути к нему, а truecryptpassphrase не выдаст ничего, потому как дефолтная настройка TrueCrypt не кешировать пароли).

Он будет вот таким:

Container: \??\C:\Users\m0x143y\Documents\encrypted.tcHidden Volume: NoRemovable: NoRead Only: NoDisk Length: 66846720 (bytes)Host Length: 67108864 (bytes)Encryption Algorithm: AESMode: XTSMaster Key0xfffffa801b57f1a8  84 2c 3d a3 24 7d 9a 37 d6 53 7e ac 1f 3c 2c 7f   .,=.$}.7.S~..<,.0xfffffa801b57f1b8  de 61 85 de 81 a9 84 2a 4d 3c d9 57 df 81 c7 29   .a.....*M<.W...)0xfffffa801b57f1c8  8f 56 fc e1 80 4e cf 2a ce 44 5b 9f a6 10 6f 98   .V...N.*.D[...o.0xfffffa801b57f1d8  15 e2 50 1f 49 38 f0 a9 62 a7 96 4a db d3 53 9f   ..P.I8..b..J..S.


Адрес KDBG для volatility 0xf80002a45120, профиль подойдет Win7SP1x64_23418 (т.е. volatility --kdbg=0xf80002a45120 --profile=Win7SP1x64_23418 -f mem.raw truecryptmaster). Затем при помощи, например, MKDecrypt можно по полученному мастер-ключу (без знания пароля, он уже не нужен) дешифровать контейнер в сыром виде. Для чего? Искомый файл secret.docx (сделано так, чтобы он не попал целиком в память в MFT и не сильно упростил решение из-за малого размера) удален из контейнера (подсказка там уже нет ничего важного в рояле), как и обещано в сообщении (и в Discord была дана подсказка а была ли там важная информация?), там лежит только всякий мусор (пентест-программы и пустые кошельки Monero). Однако с сырым расшифрованным контейнером и практически любой программой восстановления данных с FAT-разделов, например, R-Studio, photorec или DMDE, удаленный из криптоконтейнера файл с частью ключа восстанавливается.



Задание 3r1or0l3r


Часть ключа:
ssss-07-7931b90aace8673aa4d6162c3e729b7c89152de5e9bed9ab9fb9ff8eb1fbe8307bd985f728de99123980abee36d0495fbad93cf52d990a9a0fdbb82b62c7b141f3642e051dfa8112b56833

Категория задания: stego
Гуглим ник, находим его творчество: https://textbin.net/hzbmlkhzjg

Текстовая стеганография по методу цепей (о чем была дана подсказка в Discord связанные одной цепью и текст связан, неслучаен, имеет смысл в видео) Маркова: An Approach for Text Steganography Based on Markov Chains (подсказка в Discord 1409.0915). Реализация этой идеи: http://jthuraisamy.github.io/markovTextStego.js/

В текста творчества (первая глава киберпанк-романа) есть очевидным образом находимые имена собственные, например, McCoy Pauley или Bobby Quine, взятые из первой известной книги в этом жанре: Нейромант Уильяма Гибсона. В качестве специфичного корпуса текста для цепей Маркова использована первая глава этой книги (о чем есть намек в названии повести, да и других слов и предложений кроме как из первой главы там нет), свободно доступная здесь.

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



Задание VenchamoSs


Часть ключа:
ssss-08-6fe2d9b400840e44d5f20e15043cc4739ed97879110790350dd2e5e67f0b56b6e11607bb9e99f0cb1c57ede4d309e9f85363168f2ff1d2f316c9c89a8179110a759140a911075a0547f908

Категория задания: osint
Находим (это же osint) хакера на том же github: https://github.com/VenchamoSs.

На гитхабе указан второй ник a.k.a. welAnty. В понравившихся репах gpg, а значит хакер пользуется и интересуется PGP/GPG-решениями. Находим хакера на keybase.io (известный сайт, где пользователи GPG обмениваются приватными ключами), там есть публичный ключ с email welanty@forexrobotexperts.now.im. А также указание не использовать старый ключ с ID 0xF6B246D4. Если поискать по этому ID на самом известном и старом сайте для обмена ключами, то можно найти тот самый старый ключ с email eukx@forexrobotexperts.com. По нему в утечке ANTIPUBLIC (входит и в Collection #1, самая крупная компиляция утечек за последние несколько лет) есть пароль N4syZRJ843.Заходим по паролю на SSH (единственный открытый на сервере сервис) welanty@forexrobotexperts.now.im, забираем часть ключа.

Задание -velashic-


Часть ключа:
ssss-09-be6c314465393225739da1e65200657df7d4a15e66e606c9619ef51a88d5b4015353ac2f089f3dfcd3f86757e89e404dfc2552fe59218310f94b8834d7a82d47b68669aa31eb0860a95d26

Категория задания: osint, forensics
a href=www.google.com/search?q=%22-velashic-%22>Гуглим ник, находим тему на форуме Cyberforum в разделе про Arduino. Там всё описано: хакер просит помощи, по своей некорректно работающей Arduino и прилагает дамп USB-трафика, поскольку подозревает, что она слишком китайская и при заливке прошивки что-то идет не так. Код прошивки должен играть песню группы Metallica Master of Puppets. В дампе помимо заливки прошивки на Arduino попало также и общение с USB-флешкой (распространенная ситуация, поскольку USB-интерфейсов в Wireshark меньше, чем USB-портов на компьютере, ведь их количество соответствует не портам, а USB-хабам на материнской плате). С флешки считывается файл с той же песней для прослушивания, а также записывается запароленный архив secret.7z. Во время извлечения видим, что происходит запись в NTFS-раздел на флешке, а в NTFS есть концепция fixup, поэтому не забываем поправить (о чем была дана подсказка в рояле) 2 байта по смещению 142 (попали на границу сектора) с 0600 на 708f по таблице USN/USA (Update Sequence Array) FILE-записи. Пароль к архиву угадывается из очевидного интереса хакера группа metallica (также есть и в известном словаре RockYou), в архиве лежит secret.txt с искомой частью ключа.




Задание chyrgerillll


Часть ключа:
ssss-10-132faac795e60a0f9457167c3db3f1b1efd25cdd5049329e68fd43ce884e606d17fb14e70c897bd3308aaa213443952522c95b2e3c29d68dca9611a12e6f3d8a660113370c2f6753fc0643

Категория задания: crypto, re
Находим github-аккаунт с единственным репозиторием: https://github.com/chyrgerillll/mymnemonicgen В репозитории лежит реализация генератора мнемонических фраз, использующихся для запоминания доступа к криптокошелькам в голове по стандарту BIP39. Этот стандарт используется практически во всех криптовалютах и практически во всех реализациях их кошельков, далеко не только в Bitcoin. Генерацию приватных ключей для кошельков из этих мнемофраз описывает стандарт BIP44, также используемый большинством реализаций криптокошельков, о чем есть намек в репозитории. Seed-данные из энтропии, сохраненной в мнемофразе, для него вырабатываются по BIP32 (список всех трёх стандартов в первой подсказке из видео). Пример того, как всё это генерируется, можно увидеть вот здесь: https://iancoleman.io/bip39/ (последняя подсказка, данная в Discord; также подсказан использованный стандартный путь генерации m/44/60/0/0/0).

Там же, в репозитории, есть и адрес кошелька в тестнете Ropsten криптовалюты Ethereum, для приема донатов на продолжение разработки генератора. На нем лежит несколько тестовых эфиров. В репозитории также есть и намек на то, что требуется для выполнения задания: попробовать сломать сгенерированный этой доморощенной реализацией генератора кошелек и дать знать об этом автору (или и вовсе увести тестовые эфиры). Необходимый для связи email хакера (chyrgerillll@rambler.ru) можно узнать, склонировав репозиторий к себе и посмотрев, как он засветился в одном из коммитов (также неочевидная и частая проблема пользователей git).

Генератор использует стандартный питоновский ГПСЧ (вихрь Мерсенна), в качестве seedа к нему текущее время. Оно берётся из транзакции с пополнением средств (и подбирается 30 секунд, поскольку время на компьютере хакера могло быть не идеально правильным, о чем была дана подсказка в Discord всего 60 000 вариантов). Таким образом восстанавливается состояние ГПСЧ (seed 1621586183221, 21.05.2021 08:36:23.221 GMT) и получается искомая seed-фраза try process bubble call spell peanut pear valve boring stumble inject turn, а по ней и приватный ключ (0x702ca34414cc046ed2f63857a098b166541c3f477d7679a19e51de901d0df471), дающий доступ к кошельку.

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


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


Интересный факт: актриса не собиралась ломать гипсовый череп, но настолько вжилась в роль, что сделала это весьма экспрессивно, удачно оживив видео. Хорошо, что количество черепов по привычке зарезервировали по схеме N+1, и мы смогли записать еще пару дублей.

Так вот, мы решили взять этот забавный момент, зациклить и зашифровать в него подсказку. Закодированное в аудио RTTY-сообщение (на что в Discord были даны подсказки по поводу того, что звук похож на звучание старого модема или даже скорее телетайпа) можно было декодировать например с помощью известной в узких радиолюбительских кругах программы Fldigi:


Сообщение таким образом давало подсказки по заданиям для хакеров 3r1or0l3r и chyrgerillll.

Результат выполнения заданий победителем


Если собрать полученные при решении заданий части ключа в программе ssss (реализует разделение секрета по схеме Шамира, намек на эту программу содержится в тексте всех частей), то участник получает ссылку (зашифрованную pastebin): https://0bin.net/paste/YrFxYqMg#ZVK78BWtOhtncw3-xwJe9dw5rGBOboTBOJhEaop8tge

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

Бонусный ключ (10-й).


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


На сайте на клавиатуре у нас были такие вот надписи:


Для того, чтобы набрать RuVDS, надо было проиграть на рояле такую вот последовательность:

4 7 1 4 5

Результатом этого будет сообщение, которое приходит в Telegram того, кто проиграл эту мелодию:
Поздравляем! Ты вскрыл одну из 8 частей для раскрытия секрета (SSH-ключа)!
Вот она: ssss-11-2ff9228ea4b6b1fe9361a28e506ca2d35699652cc2a5838d185b075ebe9b60ce4d6e1345f6a0ebe55f5a097218265bb35a3fea2632cc569a5bb6f377591138c0d80daa96420be7150d183a



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

Хозяйке на заметку: термин лор произошёл от английского слова lore, что в контексте квестов означает знание, предание.

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


Кроме того, мы следили в Discord за тем, как участники проходили квест, и подкинули им дополнительные подсказки. Если участники догадывались проиграть на рояле закодированные ники хакеров, то получали такие сообщения через Telegram-бота:

1 5 5 1 5 1 2 3 (-velashic-, задание 9)

Молодец! Вот тебе подсказка по нику -velashic-:

проверь целостность извлеченного архива.

6 1 3 2 5 4 4 или 6 3 4 (m0x143y)

Молодец! Вот тебе подсказка по нику m0x143y:

Перед выкладыванием в интернет по своей проблеме он ведь сказал что там уже нет приватной инфы



Победители и призы


Мы уже объявили имена победителей, успевших скачать котика. Но после падения рояля у участников было ещё пять дней, чтобы решить все задания, уже только из спортивного интереса. И мы поздравляем еще раз всех, кто не опустил руки и тоже добрался до гифки с котиком!

Добравшиеся до конца
Александр
not-alone
lofarter
Герман
Ильдар

А ещё, по результатам голосования в Discord мы решили наградить участника not-alone за огромную помощь в совместном решении задач: мы дарим ему сертификат на 200 долларов для аренды виртуального сервера в любом из 11 дата-центров RUVDS, а также ящик нашего фирменного пенного Smart Admin.
Всем победителям добравшимся до конца, мы дарим промокод на 50% скидки на Хакер.

За получением призов необходимо обратиться к @Johurn.

И напоследок хотим поделиться некоторыми забавными цитатами участников:







Еще немного забавных картинок из дискорда:



И теперь точно в завершение: помним, любим, скорбим.



Подробнее..

Как организовать трансляцию на 5 суток (почти) без разрывов?

07.06.2021 16:20:09 | Автор: admin
Недавно закончился наш слегка безумный спецпроект с роялем, падающим на танцующего котика. Пять суток подряд мы показывали с трёх камер висящий рояль и его клавиши с помощью сервиса потоковых трансляций Facecast и устройств Evacoder One. Хотим рассказать вам, как это всё было организовано, и поделиться своими впечатлениями.

Почему мы решили не использовать Youtube?


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

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

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


По всем этим критериям мы не стали использовать тот же Youtube: сервис не гарантирует непрерывности трансляции, задержка слишком велика, а настройки и возможности аналитики для нас слишком скудные. Twitch мы даже не рассматривали из-за рекламы, которую вставляют в трансляцию, и мы не были уверены в стабильности вещания. Discord, в котором мы организовали чат участников, вообще не заточен под видеостриминг, да к тому же в нём ограничено количество зрителей.

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

Так выглядела октава рояля на сайте:


А это вид с камеры GoPro, закрепленной на рояле и транслирующей игру участников квеста:


Кроме того, каждый день в 12:00 наша девушка должна была перерезать очередной трос, и это тоже должно быть видно без задержек и с высоким качеством, ведь с каждым перерезанным тросом вероятность того, что рояль упадёт, будет всё выше.

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

Схема работы сервиса выглядит так:


Ключевых компонента два: облачный сервис и устройство-энкодер. К одному или нескольким энкодерам мы подключаем камеры, а сами энкодеры подключаем к сети по проводу, Wi-Fi или через сотовый модем и можно всем показывать. Для просмотра трансляции достаточно браузера, никаких специальных приложений не нужно. Плеер подберёт наилучшие разрешение и битрейт для конкретного устройства, чтобы и качество картинки было наилучшим, и чтобы тормозов не было. Можно также встроить видеопоток в свою страницу, например, страницу митапа или лендинга.


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


Эта модель предназначена для стационарных трансляций из помещений. К такому энкодеру можно подключить через HDMI или SDI одну камеру. Аппарат поддерживает современные видеокодеки Н.264 и Н.265 и передаёт видео с частотой 30 кадров в секунду и разрешением до 4К.

Самое интересное, что к сети Evacoder One можно подключить не только проводом или через Wi-Fi, но и одновременно до 16 сотовых модемов. Устройство объединяет их пропускную способность, и таким образом можно передавать тяжёлые 4К-потоки. При подключении через один 4G-модем с момента поступления сигнала в энкодер до его появления на сервисе проходит 10-30 секунд. Но конечная задержка зависит от интернета у конкретного зрителя. Ещё одна фишка связки сервиса и энкодером буферизация потока: даже если интернет-подключение энкодера временно прервётся, трансляция будет идти непрерывно, и после восстановления подключения произойдёт бесшовное восстановление потока.

На стороне облачного сервиса тоже много интересного. Например, есть restream-сервер и функции разграничения доступа зрителей, чтобы предотвратить пиратские ретрансляции с одного аккаунта. Есть богатые средства аналитики аудитории. Через сервис можно даже продавать билеты на трансляции.

У нас было три вещательные камеры, подключённые к трём Evacoder One: одна камера снимала общий план рояля, вторая снимала его со стороны тросов, а третья камера снимала крупным планом клавиши рояля:





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




Общее впечатления и факапы


Первый факап случился через 20 часов после начала трансляции. Изображение с двух камер GoPro стало дергаться. Мы быстро сообразили, что дело в стабилизаторе камер GoPro 7, который перегрелся и устал. Камеры были установлены на штативах, поэтому стабилизатор там вообще не нужен был и мы его выключили, после чего изображение снова стало стабильным (и, кстати, задержка тоже стала меньше, потому что теперь камерам не приходилось обрабатывать видео для стабилизации и они сразу отдавали его в HDMI).

А второй факап произошел в самый неподходящий момент

Как мы уже писали, Evacoder One поддерживает не только два независимых проводных Ethernet-соединения с интернетом, но и до 16 сотовых модемов. В качестве основного канала у нас была выделенная линия от местного провайдера, стабильно отдающего 250 мегабит в секунду. Второй проводной Ethernet протянуть было нельзя, потому что в здании интернет захватил монополист, не пускающий других провайдеров (думаю, ситуация знакомая для многих организаций). Поэтому в качестве резервного интернет-канала у нас был LTE-модем от Yota. Студия расположена рядом с оборонным предприятием, которое глушит сигналы сотовой связи и LTE-соединение периодически отваливалось. Но через 2-3 минуты сигнал восстанавливался и последующие 4-5 часов вёл себя хорошо, отдавая стабильно 50 мегабит в секунду.

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

Оцените иронию: пять суток трансляция велась без сбоев, и в самый кульминационный момент примерно на 12 секунд подвисло изображение с одной из камер (общего вида, спасибоBuzzardDoc за запись). На записи, которая пришла на сервер, сбоя нет, но, вероятно был небольшой дисконнект между Evacoder One и сервером Facecast из-за сбоя в интернет-соединении, что и вызвало задержку.


Однако это стало предметом для шуток в чате квеста про то, что это был фотошоп и рояль на самом деле не стали ронять, а аккуратно опустили. Хорошо, что мы вели запись еще с 5 камер, и момент падения выложили через пару часов.


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

Поэтому совет: не пренебрегайте резервными интернет-каналами для своей трансляции, создатели Evacoder One не зря предусмотрели их аж 18 штук.

И напоследок немного скриншотов и статистики:


Пики максимума зрителей приходились на 12:00. Всем было интересно посмотреть, как девушка перерезает болгаркой очередной трос.


По статистике трансляции мы отслеживали динамику интереса аудитории:


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





Подробнее..

Рояль, азот и котик как это было

16.06.2021 12:16:05 | Автор: admin
Если кто-то пропустил, то с 24 по 28 мая мы реализовали проект под кодовым названием Рояль, азот и котик. И настало время рассказать о том, как мы всё организовали, с грязными подробностями, скандалами, интригами и расследованиями.

Сразу скажем, что это был, пожалуй, самый смелый и необычный проект для нашей компании.

Итак, наливайте в кружку кофе, смузи или ягер, и устраивайтесь поудобнее: впереди много гик-порно, мужиков с перфораторами и сварочными аппаратами, красивых девушек и, собственно, самого рояля Красный октябрь, который, как и полагается музыкальному инструменту Made in USSR, пережил падение и даже не расстроился (в прямом и переносном смысле). Чего не скажешь о капиталистическом ноутбуке

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


Ок, а куда мы будем ронять этот рояль?


Очевидно, что ронять мы его будем на компьютер или ноутбук, так как речь идет о ситуации, когда под угрозой оказываются данные, хозяин которых не позаботился о цифровой копии в облаке. Чертежи, секретные материалы или резервная копия базы данных 1С: Бухгалтерии потеря этих данных уже обыгрывалась, и не один раз, как в фильмах, так и в страшных снах системных администраторов. Поэтому хотелось найти что-то свежее. И тогда мы схватились за идею, что это будет NFT-гифка с котиком, ценность которой стремительно растет.

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

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

Окей, гугл, как подвесить рояль к потолку?


Да, по этому запросу результатов катастрофически мало, поэтому придется делать всё самим.

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


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

А что с помещением?


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

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

И тут мы вспомнили о нашем друге, Алексее Горове, владельце студии Faraloft, в которой мы снимали уже несколько видео-проектов, и, не особо рассчитывая, позвонили ему. Хабр? Рояль? Жидкий азот? Разбить ноутбук? Ахаха, я в деле! ответил Алексей, и мы в очередной раз поверили в великую силу Хабра.

Оказалось, что он фанат Хабра, у него своя мини-ферма, где майнится крипта, и вообще он не против, чтобы в его легендарной студии произошла еще одна не менее легендарная история. А у него этих историй, поверьте, хватает.

Студия интересна тем, что она находится в бывшем гараже Госплана, спроектированном архитектором Мельниковым.


Сам Константин Мельников писал о своем творении так: Один глаз, смещенный с центра к высокому объёму административного корпуса с узким прорезом трубы, и я обрёл связь формалистического подхода с самой сущностью из мира прекрасного. Вобщем, идеальное место для такого авангардного арт-проекта, Константин Степанович оценил бы.

Ок, а что с роялем?


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

Наконец, нашелся один в Подмосковье (Электросталь), вполне вписывался в бюджет.

  • А он у вас в рабочем состоянии? спрашивали мы.
  • Да, две недели назад настраивали, говорила Валентина Ивановна, его владелица. Будьте с ним аккуратнее, пожалуйста!
  • Ну что вы, Валентина Ивановна! Будем сдувать с него пылинки! отвечали мы, стараясь сохранить благородные интонации в голосе.

К нам в студию он прибыл тщательно упакованный от царапин:


Как только мы его распаковали и перевезли в студию, поняли, что рояль отлично вписывается в интерьер:


Фабрика Красный октябрь (бывшая фортепианная фабрика Беккер) выпускала отличные музыкальные инструменты.
Немного из истории фабрики: В 1947 году на фабрике было создано конструкторское бюро, и в 1950-е о достоинствах инструментов Красный Октябрь заговорили в Европе. Сенсацией стало завоевание ленинградским роялем Гран-при на Всемирной промышленной выставке в Брюсселе в 1958 году, ведь прославленные Блютнер, Бехштейн и Стейнвей его и за конкурента не считали.
И да, качество рояля весьма добротное, после падения у него сломались только педали, две ножки и отлетела одна из клавиш, но при этом он даже не расстроился и на нем можно было продолжать играть:


После окончания проекта владелец студии Faraloft, Алексей Горов, отдал рояль на реконструкцию, так что наш герой еще будет радовать посетителей студии своим великолепным звучанием.

Ок, а как мы его подвесим к потолку?


Первый набросок схемы крепления рояля к потолку выглядел так:

За кадром остались пенные напитки RuVDS, без которых никак нельзя было разобраться.

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



Первый эскиз пианино выглядел так:


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




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

Алексей Горов (владелец студии Faraloft) монтирует строительные леса, без которых до балки было не добраться.


Простите, Валентина Ивановна, мы постарались не царапать ваш рояль

Тросы крепились за специальный поддерживающий каркас из нержавеющего профиля, прикрученного ко дну рояля:


Да, по расчетам рояль мог висеть и на одном из этих тросов. Но шоу у нас длится 5 дней, поэтому и тросов несколько:


С такелажем и консолью не всё получилось сразу. Пришлось поменять болты с 8-миллиметровых на 10-миллиметровые, потому что при тестах их кое-где начало гнуть. А на соединениях тросов пришлось добавить П-образные хомуты, потому что двойные плоские стяжки не справлялись.

Первое тестовое поднятие рояля:


Да, в кадре пусто, потому что многие из нас смотрели фильм Корабль-призрак и на всякий случай отошли подальше. Никто не захотел быть героем сиквела Рояль-призрак.

Чтобы снизить возможный ущерб от отлетающих тросов (в студии большие стеклянные окна), мы закрепили на концах малярные валики:


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


А что, если на рояле можно будет поиграть?


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

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

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

Параллельно мы начали думать о том, как организовать игру на рояле, и собрали на коленке прототип устройства на базе Arduino Nano и Raspberry Pi. В первом варианте у нас зажигались нужные лампочки адресной светодиодной ленты.


В конечном варианте мы добавили плату расширения с реле и два ряда соленоидов на фанерке:


Устройство собрано и готово ко встрече с роялем:


В финальном варианте это выглядело так:


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

Кадр из заставки сериала Мир дикого запада.

На сайте мы разместили клавиатуру, на которой нарисовали и цифры с нотами, что жирно намекало на то, что мы что-то там зашифровали:


Очевидно, что желающих проиграть свою мелодию будет много (за весь проект на рояле было проиграно около 2100 мелодий), поэтому мы реализовали механизм очереди через Telegram-бота. Участник проигрывал мелодию, она записывалась и передавалась ботом через API на Raspberry Pi. Пользователю сразу же после этого приходило первое оповещение с прогнозом времени воспроизведения, а затем, примерно за 20 секунд до того, как будет проигрываться запись, приглашение посмотреть этот момент вживую через трансляцию на сайте:


Участник переходил по ссылке и слушал, как его мелодия проигрывается в какой-то далекой московской квартире:


К слову, рояль играл не переставая, нам пришлось записывать несколько дублей для этого видео, чтобы найти паузу:


А что там с азотом?


Собственно, зачем вообще нужен был азот? Ну, во-первых, это красиво. А во-вторых, современные HDD делаются довольно прочными и вполне себе могут пережить такую незначительную неприятность, как падение рояля. Поэтому мы решили подойти к вопросу уничтожения NFT c котиком основательно и добавить в сюжет жидкий азот. Чтобы наверняка.

Для того, чтобы жидкий азот никуда не разлился, мы купили обычный душевой поддон и заварили у него сливное отверстие:


Резиновая пробка или герметик под действием азота могли бы довольно быстро разрушиться, поэтому Только сварка! Только хардкор!

Жидкий азот приехал к нам в обычной газели внутри которой размещался такой вот агрегат:


Да, судя по всему, одного из участников Дом 2 заморозили, чтобы реанимировать в 2035-м году и придать шоу новое дыхание:


Процесс переливки в жидкого азота в сосуд Дьюара:


В назначенный час мы, как и обещали, залили ноутбук жидким азотом:


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


А вот что стало с ноутбуком после заморозки и встречи с 500-килограммовым роялем:


Диск мы впоследствии вытащили, он действительно был целым, но данные на нем уже не читались, видимо, резкое переохлаждение всё же нарушило целостность печатной платы или микросхем. Ну штош, не самый дешевый способ избавиться от данных. Зато весьма зрелищный!

Итоги проекта и немного статистики:


  • 7635 уникальных посетителей заглянуло на сайт проекта.
  • 10 литров жидкого азота было вылито на ноутбук перед падением рояля.
  • 45 метров троса понадобилось для поднятия и удержания рояля.
  • 4 человека прошло квест до конца.
  • 2340 раз рояль проиграл мелодии участников проекта.
  • 113 раз рояль сыграл мелодию Чижик пыжик где ты был?


Хронология постов по проекту:


  1. Спаси котика из-под рояля
  2. Котики в NFT: революция в цифровом мире или хайповая пирамида?
  3. Рояль над котиком, день первый
  4. Хроники котика: брутфорс рояля, крыса-кун и деанон Оксаны
  5. Финал квеста и победители: особенности криогравитационного воздействия на портативные ЭВМ
  6. Hack the hackers: полное руководство по прохождению квеста
  7. Как организовать трансляцию на 5 суток (почти) без разрывов?
  8. Рояль, азот и котик: как это было <=== Вы сейчас здесь



Подробнее..

Как я делал систему оптического трекинга

20.01.2021 20:22:57 | Автор: admin

Дело было в далеком 2015 году. В продаже только появились очки виртуальной реальности Oculus DK2, рынок VR игр быстро набирал популярность.

Возможности игрока в таких играх были невелики. Отслеживалось всего 6 степеней свободы движений головы вращение (инерциалкой в очках) и перемещение в маленьком объеме в зоне видимости инфракрасной камеры, закрепленной на мониторе. Процесс игры представлял собой сидение на стуле с геймпадом в руках, вращение головой в разные стороны и борьбу с тошнотой.

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

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

Видел я это так:

  1. Берем несколько игроков, надеваем на них VR очки, ноутбук и датчики на руки, ноги и туловище.
  2. Берем помещение, состоящее из нескольких комнат, коридоров, дверей, оборудуем его системой трекинга, вешаем датчики и магнитные замки на двери, добавляем несколько интерактивных предметов и создаем игру, в которой геометрия виртуальной локации точно повторяет геометрию реального помещения.
  3. Создаем игру. Игра представляет собой многопользовательский квест, в котором несколько игроков надевают на себя оборудование и оказываются в виртуальном мире. В нем они видят себя, видят друг друга, могут ходить по локации, открывать двери и совместно решать игровые задачи.

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

Для реализации заявленного функционала, нужно было создать две основные технологии:

  1. костюм, состоящий из датчиков на руках, ногах и торсе, отслеживающий положения частей тела игрока
  2. система трекинга, отслеживающая игроков и интерактивные объекты в 3D пространстве.

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

Система трекинга.


Бюджета на все это, конечно, у нас не было, поэтому нужно было сделать все из подручных материалов. Для задачи отслеживания игроков в пространстве я решил использовать оптические камеры и светодиодные маркеры, закрепленные на VR очках. Опыта подобных разработок у меня не было, но я уже что-то слышал про OpenCV, Python, и подумал, что справлюсь.

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



Соответственно, камеры нужно было закрепить на потолке так, чтобы каждая точка пространства просматривалась минимум двумя камерами (лучше больше, чтобы избежать перекрытия обзора телами игроков). Для покрытия трекингом предполагаемого помещения площадью около 100 кв.м., требовалось около 60 камер. Я выбрал первые попавшиеся дешевые на тот момент usb вебки.



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

Архитектуру я придумал следующую:
На каждые очки вешается акриловый матовый шарик от гирлянды с вклеенным внутрь RGB светодиодом. Одновременно в игре предполагалось несколько игроков, так что для идентификации решил разделять их по цвету R, G, B, RG, RB, GB, RB. Вот так это выглядело:



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

Поиск шарика на кадре

Мне нужно было в каждом кадре, пришедшем с камеры, искать координаты центра шарика и его цвет для идентификации. Звучит несложно. Качаю OpenCV под Python, втыкаю камеру в usb, пишу скрипт. Для минимизации влияния лишних объектов на кадре, выставляю экспозицию и выдержку на камере в самый минимум, а яркость светодиода делаю высокой, чтобы получить яркие пятна на темном фоне. В первой версии алгоритм был следующий:

  1. Переводим изображение в градации серого
  2. Бинаризуем по порогу (если яркость пикселя больше порога, он становится белым, иначе черным). При этом размытое пятно от шарика превращается в кластер белых пикселей на черном фоне
  3. Находим контуры кластеров и их центры. Это и есть координаты шарика на кадре
  4. Определяем усредненный цвет пикселей кластера (на исходном цветном изображении) в окрестности его центра для идентификации




Вроде, работает, но есть нюансы.

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

Во-вторых, разрешение камеры всего лишь 640*480, поэтому на некотором расстоянии (не очень большом) шарик виден как пара пикселей на кадре и алгоритм поиска контуров перестает нормально работать.

Пришлось придумывать новый алгоритм. В голову пришла следующая идея:

  1. Переводим изображение в градации серого
  2. Размываем картинку мощным Gaussian blur ом так, чтобы изображения светодиодов превратились в размытые пятна с градиентом яркости от центра к периферии
  3. Находим самые яркие пиксели на изображении, они должны соответствовать центрам пятен
  4. Так же определяем средний цвет кластера в окрестности центра


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

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

Нагрузочный тест

Подключаю 8 камер к своему десктопу, располагаю их так, чтобы каждая видела светящиеся точки и запускаю скрипт, где описанный алгоритм работает в 8-ми независимых процессах (спасибо питонской либе multiprocessing) и обрабатывает все потоки сразу.

И сразу натыкаюсь на фейл. Изображения с камер то появляются, то исчезают, framerate скачет от 0 до 100, кошмар. Расследование показало, что часть usb портов на моем компе подключены к одной шине через внутренний хаб, из-за чего скорость шины делится между несколькими портами и ее уже не хватает на битрейт камер. Втыкание камер в разные порты компа в разных комбинациях показало, что у меня всего 4 независимых usb шины. Пришлось найти материнку с 8-ю шинами, что было довольно непростым квестом.

Спойлер
Подошли материнки с чипсетом Intel B85, в них поддерживается аж 10 usb шин. Но для работы с 10-ю камерами, нужно перекомпилить OpenCV, т.к. в нем захардкожено ограничение на 8 источников видеосигнала (совпадение?)

Продолжаю нагрузочный тест. На этот раз все камеры подключились и выдают нормальные потоки, но сразу сталкиваюсь со следующей проблемой низкий fps. Процессор загружен на 100% и успевает обрабатывать лишь 8-10 кадров в секунду с каждой из восьми вебок.



Похоже, нужно оптимизировать код. Узким местом оказалось Гауссово размытие (оно и не удивительно, ведь нужно на каждый пиксель кадра производить свертку с матрицей 9*9). Уменьшение ядра не спасало ситуацию. Пришлось искать другой метод нахождения центров пятен на кадрах.

Решение удалось найти внезапно во встроенной в OpenCV функции SimpleBlobDetector. Она делает прямо то, что мне нужно и очень быстро. Преимущество достигается благодаря последовательной бинаризации изображения с разными порогами и поиску контуров. Результат максимальные 30 fps при загрузке процессора меньше 40%. Нагрузочный тест пройден!

Классификация по цвету

Следующая задача классификация маркера по его цвету. Усредненное значение цвета по пикселям пятна дает RGB компоненты, которые очень нестабильны и сильно меняются в зависимости от расстояния до камеры и яркости светодиода. Но есть отличное решение: перевод из RGB пространства с HSV (hue, saturation, value). В таком представлении пиксель вместо красный, синий, зеленый, раскладывается на компоненты тон, насыщенность, яркость. В этом случае насыщенность и яркость можно просто исключить и классифицировать только по тону.



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

Алгоритм такой:
  1. Указываю цвет маркера (например, R красный) и запускаю режим накопления
  2. Беру в руку соответствующий маркер и хаотично вожу им перед камерой, приближаю, отдаляю и тд. Параллельно наблюдаю как на интерфейсе на двумерном графике hue saturation появляются точки
  3. Завершаю режим накопления. Указываю следующий цвет маркера, прохожу еще одно накопление и так далее для каждого цвета.
  4. Вижу, как разноцветные точки на графике разбиты по кластерам, но эти кластеры немного пересекаются. Расстраиваюсь. Запускаю линейную регрессию, в процессе которой программа рассчитывает уравнения прямых, разделяющих кластеры наилучшим образом. Но т.к. облака точек пересекаются, толку с этих уравнений было мало. Понял, что по-модному сделать не получится, поэтому просто вручную на глаз разделил пространство на части вертикальными линиями и в области пересечений сделал мертвые зоны, где неопределившиеся точки будут просто игнорироваться.




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

Трекинг


Я использовал pinhole модель камеры, в которой все лучи падают на матрицу через точку, находящуюся на фокусном расстоянии от матрицы.



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

Для отслеживания 3D координат маркера нужно получить минимум две скрещивающиеся прямые в пространстве от разных камер и найти точку их пересечения. Увидеть маркер двумя камерами не сложно, но для построения этих прямых нужно, чтобы система знала все о подключенных камерах: где они висят, под какими углами, фокусное расстояние каждого объектива. Проблема в том, что все это неизвестно. Для вычисления параметров требуется некая процедура калибровки.

Калибровка трекинга

В первом варианте решил сделать калибровку трекинга максимально примитивной.

  1. Вешаю первый блок из восьми камер на потолок, подключаю их к системнику, висящему там же, направляю камеры так, чтобы ими покрывался максимальный игровой объем.
  2. С помощью лазерного нивелира и дальномера измеряю XYZ координаты всех камер в единой системе координат
  3. Для вычисления ориентаций и фокусных расстояний камер, измеряю координаты специальных стикеров. Стикеры вешаю следующим образом:
    • В интерфейсе отображения картинки с камеры рисую две точки. Одну в центре кадра, другую в 200 пикселях справа от центра
    • Если смотреть на кадр, эти точки падают куда-то на стену, пол или любой другой объект внутри помещения. Вешаю в соответствующие места бумажные наклейки и рисую на них точки маркером
    • Измеряю XYZ координаты этих точек с помощью тех же нивелира и дальномера. Итого для блока из восьми камер нужно измерить координаты самих камер и еще по две точки на каждую. Т.е. 24 тройки координат. А таких блоков должно быть около десяти. Получается долгая муторная работа. Но ничего, позже сделаю калибровку автоматизированной.
    • Запускаю процесс расчета на основе измеренных данных


Есть две системы координат: одна глобальная, связанная с помещением, другая локальная для каждой камеры. В моем алгоритме результатом для каждой камеры должна получиться матрица 4*4, содержащая ее местоположение и ориентацию, позволяющая преобразовать координаты из локальной в глобальную систему.



Идея следующая:

  1. Берем исходную матрицу с нулевыми поворотами и смещением.
  2. Берем единичный вектор в локальной системе камеры, который смотрит из объектива вперед и преобразуем его в глобальные координаты по исходной матрице.
  3. Берем другой вектор в глобальной системе, который из камеры смотрит на центральную точку на стене.
  4. С помощью градиентного спуска поворачиваем исходную матрицу так, чтобы после преобразования эти векторы были сонаправлены. Таким образом, мы зафиксировали направление камеры. Осталось зафиксировать вращение вокруг этого направления. Для этого и измерялась вторая точка в 200 пикселях от центра кадра. Поворачиваем матрицу вокруг главной оси, пока два вектора не станут достаточно параллельны.
  5. По расстоянию между этими двумя точками вычисляю фокусное расстояния в пикселях (учитывая, что расстояние между проекциями этих точек на кадре составляет 200 пикселей).

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

Для визуализации результатов калибровки я сделал 2D интерфейс с картой, на которой скрипт рисует метки камер и направления, в которых они видят маркеры. Треугольником обозначаются ориентации камер и углы обзора.



Тестирование трекинга

Можно приступать к запуску визуализации, которая покажет правильно ли определились ориентации камер и правильно ли интерпретируются кадры. В идеале, линии, идущие из значков камер должны пересекаться в одной точке.

Вот что вышло:


Похоже на правду, но точность явно могла быть выше. Первая причина несовершенства, которая пришла в голову искажения в объективах камер. Значит, нужно эти искажения как-то компенсировать.

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



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



А также вектор коэффициентов дисторсии



который позволяет компенсировать искажения объектива с помощью преобразований координат пикселей.

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

Провожу новый тест трекинга:



Уже гораздо лучше! Выглядит настолько хорошо, что даже вроде будет работать.

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

Вычисление координат маркера

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



Длина отрезка AB тоже пригодится, т.к. она отражает качество полученного результата. Чем он короче, тем ближе друг к другу прямые, тем лучше результат.

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

Параллельно, при разработке костюма с датчиками, я обнаружил странное явление. Все датчики показывали разные значения угла рысканья (направления в горизонтальной плоскости), как будто у каждого был свой север. В первую очередь полез проверять не ошибся ли я в алгоритмах фильтрации данных или в разводке платы, но ничего не нашел. Потом решил посмотреть на сырые данные магнитометра и увидел проблему.
Магнитное поле в нашем помещении было направлено ВЕРТИКАЛЬНО ВНИЗ! Видимо, это связано с железом в конструкции здания.

Но ведь в VR очках тоже используется магнитометр. Почему у них такого эффекта нет? Иду проверять. Оказалось, что в очках он тоже есть Если сидеть неподвижно, можно заметить, как виртуальный мир медленно, но верно вращается вокруг тебя в рандомную сторону. За минут 10 он уезжает почти на 180 градусов. В нашей игре это неминуемо приведет к рассинхрону виртуальной и реальной реальностей и сломанным об стены очкам.

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



Система в целом работала, хоть и с небольшими косяками. Но было принято решение запустить квест, который как раз был близок к завершению нашим gamedev разработчиком, присоединившимся к нашей миникоманде. Была затречена вся игровая площадь, установлены двери с датчиками и магнитными замками, изготовлено два интерактивных предмета:



Игроки надевали очки, костюмы и рюкзаки-компьютеры и заходили в игровую зону. Координаты трекинга отсылались им по wi-fi и применялись для позиционирования виртуального персонажа. Все работало достаточно неплохо, посетители довольны. Приятнее всего было наблюдать ужас и крики особо впечатлительных посетителей в моменты, когда на них из темноты нападали виртуальные призраки =)



Масштабирование


Внезапно нам прилетел заказ на большой VR шутер на 8 игроков с автоматами в руках. А это 16 объектов, которые нужно тречить. Повезло, что сценарий предполагал возможность разделения трекинга на две зоны по 4 игрока, поэтому я решил, что проблем не будет, можно принимать заказ и ни о чем не волноваться. Протестировать систему в домашних условиях было невозможно, т.к. требовалась большая площадь и много оборудования, которое будет куплено заказчиком, поэтому до монтажа я решил потратить время на автоматизацию калибровки трекинга.

Автокалибровка

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

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

Идея следующая:

  1. вешаю камеры и на глаз направляю их в игровую область
  2. запускаю режим записи на сервере, в котором все приходящие с камер 2D точки сохраняются в файл
  3. хожу по темной игровой локации с маркером в руках
  4. останавливаю запись и запускаю расчет калибровочных данных, при котором вычисляются расположения, ориентации и фокусные расстояния всех камер.
  5. в результате предыдущего пункта получается единое пространство, наполненное камерами. Т.к. это пространство не привязано к реальным координатам, оно имеет случайное смещение и поворот, которое я вычитаю вручную.

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





Вот так выглядит напечатанная на принтере специальная палка-калибровалка.

Тестирование большого проекта


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

Когда уровень кортизола в крови превысил теоретический максимум, я решил посмотреть на проблему с другой стороны. Как можно сократить количество разноцветных точек, не сокращая количество маркеров? Сделать трекинг активным. Пускай у каждого игрока, например, левый рог всегда корит красным. А второй иногда загорается зеленым по приходу команды с сервера так, что в один момент времени он горит только у одного игрока. Получается, что зеленая лампочка будет как-будто перепрыгивать с одного игрока на другого, обновляя привязку трекинга к красной лампочке и обнуляя ошибку ориентации магнитометра.

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



Алгоритмы трекинга пришлось заметно усложнить, но в итоге все заработало! Телепортации игроков друг в друга исчезли, нагрузка на процессор упала, засветки перестали мешать.


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



Чем все закончилось?


За 3 года мы открыли множество развлекательных точек по всему миру, но коронавирус внес свои коррективы, что дало нам возможность сменить направление работы в более общественно-полезную сторону. Теперь мы довольно успешно занимаемся разработкой медицинских симуляторов в VR. Команда у нас все еще маленькая и мы активно стремимся расширять штат. Если среди читателей Хабра есть опытные разработчики под UE4, ищущие работу, пожалуйста, напишите мне.



Традиционный забавный момент в конце статьи:


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



Система в прямом смысле работала через задницу.
Подробнее..

Как спрятать мусор в базе Spotify и превратить это в квест

14.09.2020 08:09:56 | Автор: admin
Опасный хакер прячет Spotify-код с секретной информациейОпасный хакер прячет Spotify-код с секретной информацией

Введение

Одной бессонной ночью мы с приятелем разговорились о Spotify-кодах.

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

Пример. Такая грусть у меня играет прямо сейчас.Пример. Такая грусть у меня играет прямо сейчас.

Мы решили разобраться, как же Spotify кодирует в них ссылки.

Как работают коды?

Выяснилось, что помимо меню Поделиться в приложении, есть официальный сайт Spotify Codes, который генерирует такие коды.

Если скопировать ссылку на картинку с этого сайта, получится что-то такое: https://scannables.scdn.co/uri/plain/jpeg/000000/white/640/spotify:track:5jxN9knH0vlfpN2Ft7a5xi

Прекрасно! Динамическая ссылка, которая принимает на вход ID трека и возвращает изображение с баркодом самое то для наших экспериментов.

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

Числа в поле height высоты столбиковЧисла в поле height высоты столбиков

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

Важные данные выделены краснымВажные данные выделены красным

Получив число 556205622371746371156, приложение превращает его в 58992959842 с помощью таблицы Грея. Именно это делает распознаванием таким быстрым и устойчивым к ошибкам. Как узнали? К этому моменту мы уже набрели на патент Spotify, описывающий принцип работы таких кодов.

Остался последний вопрос: как же приложение превращает лаконичное 58992959842 в spotify:track:5jxN9knH0vlfpN2Ft7a5xi?

Очевидно, такое число не может вместить в себя все комбинации длинного цифро-буквенного ID, а значит никакого алгоритма нет и соответствие между кодом и ID трека хранится где-то в базе.

Можно проверить, подсунув генератору какой-нибудь очень длинный мусор, который точно не влез бы в число: https://scannables.scdn.co/uri/plain/jpeg/000000/white/640/spotify:track:thisisaverylongidentifierwhichwoulddefinitelyoverflowthatnumericcode

Сработало. Печально, а ведь было интересно научиться кодировать/раскодировать такие картинки полностью самостоятельно.

Решила проверить обмен приложения с сервером в момент распознавания и догадка подтвердилась:

На сервер уходит 58992959842, а возвращается трек 5jxN9knH0vlfpN2Ft7a5xiНа сервер уходит 58992959842, а возвращается трек 5jxN9knH0vlfpN2Ft7a5xi

Скука: дальше всё происходит за ширмой бэкенда. Расходимся?

Оченьдлинныймусор

Стоп, что? Генератор сделал картинку для оченьдлинногомусора?

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

Картинка с мусором из примера вышеКартинка с мусором из примера выше

А что будет, если считать такой код приложением?

Будет ошибкаБудет ошибка

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

Эм, что?Эм, что?

Великолепно. Spotify складывает в базу всё, что мы укажем в запросе к генератору, хранит это там, а при сканировании отдаёт обратно в первозданном виде, никак не валидируя.

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

Всё лучше под музыку

Чтобы всё было аккуратно, нужно заставить приложение играть музыку, несмотря на чужеродные данные в ID трека.

Я уже собралась реверсить обфусцированный код Android-приложения, чтобы узнать, как работает парсер, но приятель предложил попробовать разделять музыкальный ID и нашу полезную нагрузку знаком вопроса. Идея сработала, но знак пришлось дважды пропустить через urlencode. Например, spotify:track:2ctvdKmETyOzPb2GiJJT53%253Fhi,habr!, выглядит вот так:

Код с двойным дномКод с двойным дном

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

Выводы

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

Навредит ли это Spotify? Теоретически эта особенность позволяет заполнить таблицу соответствий кодов и исчерпать всю ёмкость, сломав генерацию картинок для настоящих треков, но на практике это займёт очень много времени. Я посчитала.

Полезно ли это на практике? Не знаю, как это использовать. Можете прятать номера телефонов любовниц в кодах с Егором Летовым и обклеивать ими стены, тогда ваша законная женщина покинет вас, сочтя сумасшедшим, будете свободны. Только имейте в виду, что запрос к API для считывания кода, к сожалению, требует авторизационный токен Spotify-аккаунта, в отличие от запроса для генерации картинки.

Оригинальный квест был здесь, послание было в Base64. Кто-то прошёл его за 42 минуты. На большее я не рассчитывала: имеющие привычку лезть в трафик приложений догадались бы сразу.

Помогал думать, предполагал хранение кодов в базе и решил добавить в ID знак вопроса приятель Эль.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru