Реверс инжиниринг протокола активации Яндекс.Станции
«Яндекс.Станция» — умная колонка с голосовым помощником Алиса. Чтобы её активировать, нужно поднести телефон и проиграть звук из приложения «Яндекс». Под катом я расскажу, как устроен этот сигнал, про пароль от WiFi в открытом виде и попробую развить идею передачи данных через звук.
Преамбула
Я закончил радиотехнический факультет МФТИ, изучал и разрабатывал системы связи от протоколов физического уровня до сетей федерального масштаба. Поэтому, когда друзья подарили Яндекс.Станцию, мне сразу стало интересно, как организована передача данных для активации через аудиотокен.
Процесс активации
Когда включаешь новую колонку, каким-то образом нужно передать на неё информацию для подключения к WiFi сети и авторизации в сервисах Яндекса. В Станции это сделано через звук и выглядит, как на видео ниже (7:34).
»… передача информации происходит, ну не по звуку, конечно …» — говорит Валентин. Знал бы он, что в этот момент его пароль от WiFi попал в видео практически в открытом виде! Но об этом позже.
А пока рассмотрим, что происходит. Телефон берет данные о WiFi сети (ssid из системы, пароль вводит пользователь) и данные для авторизации в Яндексе. Они каким-то образом кодируются, модулируются и излучаются динамиком телефона. Станция демодулирует сигнал с микрофонов, декодирует данные и использует их для подключения к сети и авторизации.
В этом процессе нас интересует, как кодируются и модулируются данные.
Визуальная демодуляция
Для получения образца сигнала не нужна сама Станция. Необходимо только, чтобы телефон был подключен к WiFi с интернетом. Я решил создавать точки доступа с разными ssid и паролями, чтобы посмотреть, как меняется сигнал. Для удобства стал записывать звук в файлы и работать с ними.
Для начала я создал точку доступа со случайным паролем »012345678» и подключил к ней телефон. Нажал «Проиграть звук» и записал получившийся сигнал. Давайте посмотрим на его спектр во времени (waterfall). Здесь по вертикальной оси отложена частота, по горизонтальной — время, а цвет определяется амплитудой.
Так, тут видно, что применяется частотная модуляция, а данные передаются символами по 40 мс. Также можно выделить возрастающую подпоследовательность:
Стоп! Кажется, у нас был возрастающий пароль.»012345678». Как эти цифры выглядят в кодировках ascii или utf-8?»30 31 32 33 34… 38». Ого! Даже менять пароль не пришлось! Вот он где лежит:
Я попробовал менять пароль и убедился, что правильно определил его положение в сигнале.
Получается, данные кодируются символами по 4 бита. По сути кодируется hex строка, где каждому значению 0 — F соответствует своя частота от 1 кГц до 4,6 кГц с шагом в 240 Гц. При этом в начале и в конце передачи есть излучение на частотах выше 5 кГц — метки начала и конца отделены от основной части на физическом уровне.
Декодирование
Чтобы каждый раз не переписывать на листочек символы, глядя на спектр, я набросал простой приёмник на питоне, который достаточно стабильно конвертирует аудиофайл в исходную hex-строку. Я стал менять ssid точки доступа и анализировать, на какие байты это влияет. В итоге выяснилось, что информация о ssid хранится в двух байтах перед паролем. При этом длинна этого блока не зависит от длины ssid. Как так?
Вероятно, на Станцию передаётся только хеш от ssid. При этом, скорее всего, Станция после включения вычисляет хеши названий всех доступных сетей. После чего выбирает сеть, сравнивая полученные значения с принятыми. Скорее всего, это сделано для уменьшения длины посылки. (Но как тогда происходит подключение к скрытым сетям?)
Также видно, что с каким-то периодом присутствуют вставки по 4 символа. На спектре их можно увидеть дважды внутри пароля. Вероятно, это какое-то помехоустойчивое кодирование, либо синхронизационные символы.
Данные для авторизации в Яндексе мне не удалось выделить. Однако, длина пакета достаточно маленькая, поэтому точно можно сказать, что в посылке нет какого-нибудь OAuth токена. Я предполагаю, что приложение «Яндекс» получает временную ссылку, часть которой передаёт на Станцию. А она, в свою очередь, получает по этой ссылке полноценные данные для аутентификации. Думаю, сделано это также для уменьшения длины посылки.
Написал в Яндекс?
Да, 8 мая 2019. Получил автоматический ответ:
Прошло 4 месяца — так и не связались. По правилам Яндекса, теперь можно разглашать информацию, чем я, собственно, и занимаюсь.
Это вообще проблема?
Возможно, сотрудники Яндекса не считают это проблемой. Действительно, это сложно назвать уязвимостью, ведь активация Станции редко происходит больше 1 раза. При этом, часто она находится в «доверенном» помещении. Дома или в офисе вы можете произносить пароль от WiFi вслух, что практически то же самое. Специалисты по информационной безопасности, как вы считаете?
Кроме того, алгоритм активации уже зашит в произведенные Станции, поэтому избавиться от этой уязвимости в текущей версии вряд ли удастся.
Однако, я считаю, это не повод игнорировать сообщения в bugbounty. По крайней мере, не вежливо обещать ответить и не делать этого. Ладно, будем считать, что моё обращение где-то затерялось. Если что, номер тикета: 19050804473488035.
Лично я считаю, что уязвимость какая-никакая есть. Поэтому, несмотря на то, что я обладаю стабильным приёмником этого сигнала, дать его вам не могу.
А также, хочу напомнить Wylsacom, Rozetked, и другим блогерам о необходимости регулярной смены пароля. По крайней мере я знаю, какой у вас был на момент обзора Яндекс.Станции)
Что в итоге?
Разработчики из Яндекса сделали крутую штуку. Они разукрасили процесс активации Станции, сделали его необычным. Единственная проблема, на мой взгляд — открытый пароль.
А ведь тот же процесс можно было сделать безопаснее с использованием Bluetooth. Это навело меня на мысли, что в данном случае не так важна безопасность или скорость. Важно шоу. Активация через звуки, напоминающие R2-D2 из «Звездных войн» впечатляет и выглядит необычно.
Такая позиция вдохновила меня развить идею разработчиков Яндекса и сделать протокол, ориентированный на впечатление. Что, если для модуляции hex символов использовать частоты нот? Почему бы не передать данные в До-мажоре? Получилось очень интересно, но об этом — уже в следующей статье.
Спасибо, что дочитали, успехов!