Я уже пару лет как изучаю протоколы радиосвязи. Началось это с момента, когда я из любопытства решил поэкспериментировать с USB-донглом RTL-SDR. Мне всегда хотелось понять, как передаются данные в пультах дистанционного управления (в частности, автомобильных брелках), попробовать перехватить их сигнал и выяснить, какие ещё в этом случае есть векторы атаки.
И хотя за эти годы мне удалось перехватить несколько сигналов с брелков, у меня не было возможности как следует их проанализировать, так как доступ к тем автомобилям был ограничен.
В этой статье я познакомлю непосвящённых со своей историей успешного реверс-инжиниринга и воспроизведения сигнала автомобильного брелка, начиная с самых базовых механизмов передачи радиосигналов и заканчивая всем ходом моих рассуждений и выводов за время реализации проекта.
Ещё одной целью, пожалуй, будет доказательство, что большинство машин не так уж просто угнать посредством перехвата сигнала (разве что Honda, хах), несмотря на то, что недавно в Канаде запретили якобы опасный Flipper Zero, который можно собрать из дешёвых модулей беспроводной связи.
Технические средства
▍ RTL-SDR
Впервые в мир радиосвязи я погрузился в 2016 году, когда узнал, что дешёвый (~$10) USB-донгл для ТВ/радио можно легко превратить в многофункциональный радиоприёмник для инспектирования и декодирования практически всей информации, передаваемой в диапазоне от 24 до 1750 МГц. Это устройство широко известно как RTL-SDR:
Секрет его столь мощных возможностей заключается в микросхеме, которая позволяет использовать радиосвязь с программным управлением (SDR, software defined radio). Как оказалось, при использовании этой микросхемы (RTL2832U) можно пропускать обработку сигнала, которая обычно происходит на аппаратном уровне, преобразуя необработанный сигнал в «содержательные» данные для потребления хостом (в данном случае речь идёт о ТВ/радио-трансляциях).
Имея доступ к необработанным синфазным и квадратурным данным сигнала (I/Q), можно получать, визуализировать и сохранять практически любой сигнал в сыром виде без необходимости знать радиочастотные параметры его передачи (модуляцию, частотный диапазон, скорость передачи и так далее), поскольку можно проанализировать эти данные самостоятельно. По сути, это даёт нам окно для сканирования практически любой активности в радиодиапазоне до 1,7 ГГц.
▍ Flipper Zero
Flipper Zero – это электронный девайс, эдакий «швейцарский нож» хакера, выход которого несколько лет назад вызвал резкий ажиотаж среди молодёжи и любителей электроники. Швейцарским ножом его прозвали за то, что в нём используется несколько модулей беспроводной связи, которые позволяют взаимодействовать с бытовой электроникой, домофонами, шлагбаумами и прочими устройствами.
Нас же интересует конкретно модуль Sub-Ghz, в роли которого выступает микросхема CC1101, поддерживающая частоты до 1 ГГц, обычно используемые в беспроводной бытовой электронике.
Но тут стоит отметить, что можно просто купить CC1101 отдельно (~$5) и наладить её работу через Arduino/Raspberry Pi, либо использовать переходник USB-TTL. Но Flipper то явно круче и практичней. ¯\_(ツ)_/¯
▍ CC1101 или RTL2832U
Микросхема CC1101 во Flipper Zero, в отличие от RTL2832U из RTL-SDR, является трансивером, так что для отправки сигналов мы будем использовать Flipper.
Тем не менее CC1101 не поддерживает SDR, а это значит, что обратно она будет присылать только те данные, которые полностью обработала. Иными словами, эта микросхема окажется для нас полезна, только если мы установим правильные параметры передаваемого сигнала.
Flipper Zero (CC1101) | RTL-SDR dongle (RTL2832U) | |
Получение сигналов | + | + |
Отправка сигналов | + | - |
Получение/анализ необработанных сигналов | - | + |
Примечание: естественно, трансиверы SDR существуют, но обычно стоят очень дорого.
Основные механизмы передачи радиосигналов (очень упрощённо)
Теперь, когда мы познакомились с оборудованием, пора разобрать некоторые принципы, необходимые для понимания темы.
▍ Вступление
Для передачи радиосигнала используются радиоволны, представляющие один из видов электромагнитного излучения.
Эти волны обычно имеют более высокую частоту в сравнении с исходным передаваемым сигналом. Это повышает устойчивость передачи данных, поскольку сигналы имеют варьирующиеся характеристики, что делает их отправку в виде радиоволн непрактичной, восприимчивой к помехам и позволяет добиться лишь небольшой дальности.
Эти волны называются несущими, так как изменяются для устойчивого переноса исходного сигнала по воздуху (подробнее об этом ниже).
Далее мы разберём некоторые основные принципы, необходимые для отправки/получения радиосигнала.
▍ Частота
Тут название говорит само за себя. Частота отражает количество колебаний несущих волн в секунду. Эта характеристика влияет на длину волны (чем выше частота, тем короче волны). На основе этого параметра также обычно определяют канал связи.
▍ Модуляция
Модуляция – это способ представления сигнала в радиоволнах. Двумя наиболее известными видами модуляции, которые наверняка знакомы большинству людей, являются AM (амплитудная модуляция) и FM (частотная модуляция).
Разница между ними в том, что при AM сигнал модулируется (кодируется) посредством амплитуды (или силы). Грубо говоря, это означает, что данные представляются путём изменения силы несущего сигнала.
В случае FM, очевидно, данные представляются путём модуляции частоты.
Эти принципы хорошо отражены в анимации из Википедии (линия «Signal» отражает передаваемые данные):
Модуляции также могут иметь разные подтипы и характеристики, о которых я расскажу позже.
▍ Частотный диапазон
Этот параметр отражает диапазон частот, доступных для модулируемого радиосигнала, или, иначе говоря, разницу между максимальной и минимальной частотой, которую может иметь сигнал. По сути, он определяет количество данных, которые сигнал может переносить.
Поскольку остальные характеристики на этом этапе для нас не так важны, можно переходить к самому интересному.
Визуальный анализ
▍ SDR#
SDR# – это бесплатное, интуитивное, компьютерное приложение для цифровой обработки сигналов (DSP, Digital Signal Processing), написанное на Си с акцентом на производительности. Оно позволяет визуализировать радиоспектр в реальном времени и поддерживает демодуляцию некоторых распространённых модуляций. Кроме того, оно даёт возможность использовать сторонние плагины для кастомных модуляций и интеграций.
С помощью этой программы мы будем обнаруживать сигнал и проводить его первичный анализ.
▍ Обнаружение сигнала
Настроившись на частоту 433,92 МГц с помощью донгла RTL-SDR (используя драйвер WinUSB вместо штатного DVB-T), можно наблюдать активность большинства пультов ДУ при достаточной их близости (в Евросоюзе и соседних странах, включая Марокко, где я живу, частота 433,92 МГц не относится к регулируемым).
При нажатии любой кнопки автомобильного брелка тут же выделяются 3 последовательных всплеска, которые видны на каскадной диаграмме под визуализацией спектра:
Визуализация сигнала автомобильного брелка с помощью SDR# (ось X = частота, ось Y = сила сигнала)
Также отчётливо видно, что у сигнала есть два основных пика по обе стороны частоты 433,92 МГц (красная линия в середине – это точная частота настройки).
Покопавшись в распространённых схемах модуляции, я нашёл интересный вариант 2-FSK.
▍ 2-FSK
FSK означает Frequency-Shift Keying (частотная манипуляция). Это схема частотной модуляции, в которой данные кодируются путём периодического сдвига частоты несущего сигнала между несколькими значениями.
Пока всё просто. Похоже, здесь мы имеем дело с FM.
Интерес же вызывает приставка «2», которая означает количество каналов кодирования. То есть мы по факту кодируем двоичные данные в двух отдельных частотах, одна для 0 и одна для 1, что объясняет два обнаруженных нами выше пика.
Примечание: для тех, кому интересно, что из себя представляют другие пики поменьше – это, по сути, нежелательные частоты, случайно генерируемые микросхемой передатчика. Их появление объясняется дешевизной микросхемы, а также близким расположением брелка и антенны. Так что это просто шум, на который можно не обращать внимания.
Практический анализ
Теперь, когда мы наглядно пронаблюдали сигнал, пора найти способ его проанализировать для считывания битов из радиоволн с целью обнаружить в них некую структуру или согласованность.
▍ Universal Radio Hacker
Как гласит README его репозитория, Universal Radio Hacker (URH) – это полностью опенсорсный инструмент для анализа беспроводных протоколов с нативной поддержкой многих распространённых SDR. URH позволяет легко демодулировать сигналы наряду с автоматическим обнаружением параметров модуляции, что существенно упрощает определение передаваемых по воздух битов и байтов.
Именно такое ПО нам нужно для декодирования радиоволн в биты.
При запуске URH предлагает открыть файл либо начать запись непосредственно с устройства.
Для запуска записи нужно выбрать источник и настроить некоторые параметры (лично я просто установил правильную частоту, остальное оставив по умолчанию).
После записи сигнала URH попытается обнаружить правильную конфигурацию для декодирования его радиоволн.
В первых записях у меня не получалось заставить URH найти правильные параметры, и он выдавал неверные результаты. Позже я выяснил, что запись нескольких повторяющихся сигналов за раз повышает шанс обнаружения приложением правильной конфигурации. В моём случае это оказалось: 50 отсчётов/символ, FSK.
При увеличении одного из сигналов мы видим 3 всплеска, которые наблюдали на диаграмме SDR# (второй из них состоит из 3 отдельных – то есть всего нам предстоит проанализировать 5 фрагментов).
Для каждого фрагмента автоматически извлекается последовательность битов, которые для лучшей визуализации можно преобразовать в шестнадцатеричный формат:
Здесь уже заметна явная согласованность и повторяющиеся паттерны байтов, значит мы на верном пути.
Тем не менее, кажется, мы что-то упускаем, поскольку есть здесь один интересный момент, а именно повтор одних и тех же 5 шестнадцатеричных цифр со множеством байтов
0х55
(01010101
).При переключении на соседнюю вкладку «Analysis» мы видим байты, которые только что извлекли из наблюдаемых всплесков. Каждый из них представлен в виде строки, и программа предлагает нам возможность декодирования с помощью одного из алгоритмов:
Перепробовав всё по очереди, я заметил, что Manchester II преобразует все байты
0х55
в нулевые без каких-либо ошибок декодирования:Вот это уже более приемлемый вид.
▍ Манчестерское кодирование
Манчестерское кодирование – это очень простая схема цифровой модуляции, которая обеспечивает, чтобы сигнал не оставался продолжительное время в состоянии логического нуля или единицы, а также делает его самосинхронизирующимся (для восстановления синхронизации).
Эти характеристики очень пригождаются при отправке цифровых данных по аналоговым каналам, подверженных шуму и помехам.
В манчестерской схеме двоичные данные кодируются в двух противоположных битах, в связи с чем
0
становится 01
, а 1
– 10
(или наоборот, в зависимости от стандарта):Вернёмся к нашему анализу.
Методом ручного тыка и сравнения разных снимков сигнала можно заметить, что каждое нажатие кнопки генерирует сигнал с такими характеристиками:
- Длинный всплеск (выделен жёлтым) без данных (декодируется в 100 нулевых байтов).
- Три очень похожих всплеска – частично изменяются лишь 2 байта (выделены красным).
- Заключительный всплеск (выделен зелёным), который уже короче, но всё равно очень похож на три предыдущих.
Я решил более детально рассмотреть эти три всплеска (назовём их пакетами) в середине, так как, похоже, это важная часть сигнала. В итоге я быстро заметил инкрементируемый ID (выделен синим), который с каждым очередным сигналом увеличивается на 1:
Для дальнейшего продолжения анализа нам нужно познакомиться с очень важным механизмом защиты удалённого доступа.
▍ Плавающий код
Плавающий код используется в системах доступа без ключа для предотвращения простых атак путём воспроизведения, при которых подслушивающее устройство записывает передачу сигнала и воспроизводит его позднее для «разблокировки». Подобные защиты часто используются в гаражных воротах и бесключевых системах доступа к автомобилю. Подробнее об этом коде можно почитать в Википедии.
Суть механизма в том, что брелок и машина «утверждают» между собой криптографически безопасный алгоритм генерации меняющегося ключа, который будет использоваться для аутентификации удалённого доступа.
Эти ключи генерируются и отслеживаются при помощи счётчика, который должен находиться в синхронизации между брелком и машиной. Такой механизм исключает возможное повторное использование машиной старого ключа, а также гарантирует постоянную генерацию брелком новых ключей.
Ниже показан пример реализации непрерывно меняющегося кода (спасибо RuhrSec 2017):
-
uid
: ID автомобиля/брелка; -
enck
: реализация алгоритма плавающего кода; -
ctr
: счётчик на автомобиле; -
ctr’
: счётчик на брелке.
Окно доступа позволяет брелку сохранять синхронизацию в случаях, когда автомобиль не получил сигнал (обычно максимум для 255 нажатий кнопок вне радиуса действия, после чего брелок нужно синхронизировать вручную).
С этим разобрались. Пора вернуться к анализу.
Поскольку теперь мы знаем, что плавающий код криптографически защищён, можно легко определить ту часть сигнала (выделена зелёным), которая отвечает за эту реализацию (ей будет часть с наибольшей энтропией):
Кроме того, мы можем предположить, что инкрементируемый ID представляет счётчик в системе плавающего кода, так как он удобно расположен рядом с ним.
Сравнивая сигналы «блокировки» и «разблокировки», я смог быстро найти байт (выделен розовым), отвечающий за эту команду (8 = разблокировка, 4 = блокировка):
Теперь из «меняющихся частей» сигнала нам осталось лишь разгадать два красных изменения, которые мы отметили ранее:
1) В отношении первого видно, что одни и те же значения повторяются во всех перехваченных сигналах.
Преобразовав эти три значения в двоичную форму, мы увидим следующее:
-
0x6
: 0110 -
0xA
: 1010 -
0xE
: 1110
А если проверить и последний, четвёртый, пакет?
-
0x13
: 10011
2) Теперь разгадаем последний байт.
Можно заметить, что он не только меняется для каждого пакета, но и что это происходит во всех сигналах.
Хмм, последний байт пакета, меняется случайным образом, а не контрольная ли это сумма?..
В качестве проверки можно попробовать выполнить XOR между этим байтом и только что проанализированным, чтобы понять, получится ли у нас статичное значение (поскольку, если рассматривать 3 пакета плавающего кода, то всё кроме этих двух байтов по факту остаётся статичным).
Проверим на двух примерах:
Пример 1:
-
0x06 ^ 0xB9
= 0xBF -
0x0A ^ 0xB5
= 0xBF -
0x0E ^ 0xB1
= 0xBF
-
0x06 ^ 0xCC
= 0xCA -
0x0A ^ 0xC0
= 0xCA -
0x0E ^ 0xC4
= 0xCA
Применив XOR ко всем байтам пакетов, мы видим, что значение всегда получается смещённым на 1:
Из этого можно заключить, что первые два байта пакета, скорее всего, исключаются из контрольной суммы (откуда и берётся 1):
И это вполне разумно, поскольку эти байты здесь будут действовать как syncword для синхронизации приёмника и обозначения начала данных.
Примечание: если вам интересно назначение первого длинного всплеска, выделенного на картинках жёлтым – он служит для пробуждения приёмника и его подготовки к получению данных (поскольку при бездействии он переходит в режим экономии энергии). И если вам также интересно, почему брелок отправляет три пакета почти с идентичными данными, то это делается просто для повышения надёжности на случай повреждения одного из пакетов при передаче (что наблюдалось в предыдущем скриншоте).
▍ Итоговый результат
После разметки остальных байтов в соответствии с моими догадками у меня получилось следующее:
Чётко! Мы только что провернули реверс-инжиниринг сигнала автомобильного брелка.
Возможно, я ещё напишу статью о том, как интегрировал поддержку этого формата сигналов в Flipper Zero, чтобы иметь возможность считывать, повторно сериализовать и воспроизводить их.
Спасибо за внимание!
Примечание: если вы заметили какие-либо неточности или возможные доработки по части содержания статьи, то можете отправить пул-реквест на GitHub.
Telegram-канал со скидками, розыгрышами призов и новостями IT ?
Комментарии (16)
sekuzmin
22.03.2024 13:15+2Возможно, я ещё напишу статью о том, как интегрировал поддержку этого формата сигналов в Flipper Zero, чтобы иметь возможность считывать, повторно сериализовать и воспроизводить их.
Уважаемый Sami ALAOUI KENDIL, с нетерпением ждём продолжение, поскольку пока не понятно зачем повторно сериализовать и воспроизводить rolling code. Из спортивного интереса?
IvanPetrof
22.03.2024 13:15+3хозяин брелка жмёт кнопку open/close
Злоумышленник записывает сигнал и одновременно заглушает его другим устройством, чтоб сигнал не дошёл до машины.
Хозяин жмёт ещё раз, т.к. "машина его не услышала"
Злоумышленник записывает второй сигнал, а сам воспроизводит первый записанный. Машина закрывается.
Довольный хозяин уходит.
Злоумышленник воспроизводит второй записанный сигнал. Машина открывается.
sekuzmin
22.03.2024 13:15+1Rolljam, спасибо в курсе. Достаточно просто записать raw сигнал на Flipper Zero и воспроизвести его, незачем "повторно сериализовать".
not-allowed-here
22.03.2024 13:15там счетчик в шифрованной части сигнала - и он должен совпадать или быть больше от передатчика между....
sekuzmin
22.03.2024 13:15Samy Kamkar объясняет - Drive It Like You Hacked It (DEF CON 23), смотреть с 41:40 по 43:00 и далее
JediPhilosopher
22.03.2024 13:15Это все дичь конечно. IT дала им всякие стойкие криптографические алгоритмы, диалоговые коды, цифровые подписи. Причем в случае брелок-авто это же очень просто все делается, тут нет проблемы с изначальным обменом ключами по незащищенному каналу и не надо всякие Диффи-Хеллманы городить. Нет никакой проблемы сделать систему не взламываемой программными способами. Но нет, по-прежнему делают вот такую ерунду тривиальную.
Kitsok
22.03.2024 13:15+1Технологии точно лет 30, если не больше, тогда просто не было сегодняшних контроллеров с тьмой памяти, криптоускорителями и стоимость в единицы долларов.
Wesha
22.03.2024 13:15+1Нет никакой проблемы сделать систему не взламываемой программными способами.
Есть проблема — специалисты, способные это сделать, не хотят, гады, работать за миску чевевицы.
freemanon
22.03.2024 13:15Как можно записать сигнал и одновременно его заглушить? Хозяин не рядом с машиной её запирает?
stranger777
22.03.2024 13:15Вообще удивительно, что на Хабре так мало статей про автомобили, учитывая, что бортовые компьютеры в них появились давным-давно, и что авто — по сути, один из самых массовых автоматических механизмов и т. д.
maikuss
22.03.2024 13:15+3Может быть, из-за того, что многие из тех, кто в этом разбирается, не афишируют своих умений. Кто-то потому, что работает в этой области, а кто-то может опасаться, что принудят работать.
NutsUnderline
По всем этим описаниям все просто, по факту разгадка этих последовательностей - довольно хлопотное дело.
кстати URH довольно требователен к процу, скажем на планшете с atom его точно не стоит запускать
Wesha
Ну некотрорые граждане часами кроссворды разгадывают — и не жалуются, говорят, что развлекаются так. А данный коллега развлекается по-своему.
NutsUnderline
я просто очень не люблю слова "да там все просто" :)
Wesha
так то ж для Ландау!
Лифшиц однажды читал лекцию по материалам Курса.
После лекции к нему подошел студент с раскрытым учебником:
– “Простите, профессор,вот тут у Вас написана формула, затем написано: “откуда очевидно следует”, и далее еще одна формула. Но мне, например, совсем не очевидно, как вторая формула получается из первой! Вы не могли бы прояснить?
Лифшиц взял учебник, внимательно просмотрел и, усмехнувшись, ответил:
– Эх, молодой человек! Очевидно, что это было очевидно для Ландау!