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

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.
Опасный хакер прячет 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 знак вопроса приятель Эль.

Источник: https://habr.com/ru/post/518970/


Интересные статьи

Интересные статьи

Spotify — гигант музыкального стриминга, неохотно делящийся прибылью с исполнителями, — в патенте, выданном Европейским Союзом, описывает технологию, которая, к...
Пришло время продемонстрировать как криптографический АРМ на базе стандартов с открытым ключом cryptoarmpkcs работает на одной из мобильных платформ, а именно Android. Концепция, которая закла...
К Новому году, как обычно, Санта и его помощники готовили подарки. Сегодняшнее утро не предвещало ничего необычного — всё шло по плану: гудел конвейер с игрушками для детей и взрослых, гномы ...
Итак, в первой статье цикла говорилось, что для управления нашим оборудованием, реализованным средствами ПЛИС, для комплекса Redd лучше всего использовать процессорную систему, после чего на ...
Тема статьи навеяна результатами наблюдений за методикой создания шаблонов различными разработчиками, чьи проекты попадали мне на поддержку. Порой разобраться в, казалось бы, такой простой сущности ка...