
Авто — идеальный полигон для экспериментов программно-аппаратного хакера. Здесь вам и реверс-инжиниринг прошивок IoT устройств, и подключение к портам дебага, и взлом беспроводных сетей, и радиохакинг. Но самое интересное начинается, когда все эти направления пересекаются в одном исследовании.
На связи Иван Глинкин, руководитель группы аппаратных исследований из команды Бастиона. Сегодня займемся реверс-инжинирингом штатного ключа автомобильной сигнализации (key fob) китайского JAC JS4, известного в России как Москвич 3. Этот китаец с русским именем за несколько лет уверенно прописался на наших дорогах, но в инфополе до сих пор нет информации о его тестировании на стойкость к взлому.
Итак, вызов принят! Мы проведем детальное исследование компонентной базы брелока, изучим его внутренности, просканируем эфир с помощью SDR, постараемся выявить плавающий код (hopping/rolling code) и наметим несколько векторов атаки.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, работающих в рамках легального тестирования. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и тайны переписки преследуются по закону.
Автор не является профессиональным специалистом по взлому автомобилей. Вся информация о методах взлома собрана из открытых источников, а описанные в статье эксперименты проводились исключительно на собственном автомобиле.
Принципы работы бесключевого доступа
Чтобы взломать сигнализацию и оценить ее стойкость к реальным угрозам, нужно сначала понять, как она работает. Это задача на стыке радиосвязи, криптографии и электроники ближнего поля — сложно и безумно увлекательно.
Для начала разберем по слоям архитектуру автомобильной сигнализации: от физики до лирики логики. В дверях, салоне и багажнике авто установлены низкочастотные антенны, работающие на частоте 125 кГц. Когда водитель касается дверной ручки, вокруг авто формируется LF-поле на 125 кГц радиусом ~1–1,5 м. Ключ улавливает это поле с помощью индуктивной катушки. Этот канал используется для активации ключа и передачи начального запроса. Однако ключ не отвечает по этому LF-каналу, а использует для ответа UHF-радиоканал на 433 МГц (или на ~315 / 868 / 902 МГц — зависит от региона).
Резюмируем схему работы бесключевого доступа: машина запрашивает ключ по LF-каналу (challenge), а ключ отвечает по UHF, передавая криптографически подписанный ответ (response).
Но как авто понимает, что ключ рядом? Дело в том, что LF (125 кГц) — это не обычная радиосвязь, а квазистатическое магнитное поле. Оно плохо проникает через металл, быстро затухает и, соответственно, позволяет определить зону нахождения ключа (дверь, салон, багажник). По принявшей ответ антенне система улавливает: ключ снаружи — можно открыть дверь, но запуск двигателя запрещен; ключ внутри — можно заводиться.
В современных авто обмен сообщениями между ключом и машиной защищается криптографией и другими методами. Обычно используется схема challenge-response, где ответ ключа зависит от скрытого секрета: «посчитай, сколько будет 2+2, потом умножь на наш секретный секрет (например, 1337), а затем возьми остаток от деления на другое секретное число и верни обратно». Также применяют симметричное шифрование (AES или свои проприетарные алгоритмы). Ну и, конечно же, плавающие коды (rolling codes), защищающие сигнал от простого копирования.
Распространенные методы взлома
Прежде чем браться за скальпель отвертки, микроскоп и SDR, разберемся, какие методы взлома автомобильных сигнализаций через радиоключ в принципе существуют. Это позволит сразу сфокусироваться на актуальных векторах, а не хвататься за всё подряд.
Если оставить за скобками НЛО-мобиль от Илона Маска, можно выделить три основных типа атак на сигнализации.
1. Replay-атака
Нестареющая классика. Злоумышленник перехватывает сигнал, когда владелец автомобиля нажимает на брелоке кнопку открытия/закрытия двери. После этого достаточно просто воспроизвести перехваченный сигнал без каких-либо изменений, имитируя легитимный ключ. Дело сделано: злоумышленник может открыть или закрыть авто.

Атака направлена на системы с фиксированным кодом, где нет защиты от повторного воспроизведения сигнала. В таких системах ключ сигнализации каждый раз отправляет автомобилю одно и то же значение.
«Противоядие» от такой угрозы — перевод кода передаваемого сигнала из постоянного в плавающий (те самые hopping/rolling codes). Тогда при каждом нажатии на кнопку ключа сигнализации формируется новый код по криптографически стойкому алгоритму. Приемник в автомобиле расшифровывает его по заранее согласованной формуле: совпало — машина открывается, не совпало — сигнал игнорируется.
2. Rolling jam-атака
Эта атака направлена на системы с плавающим кодом. Она сложнее, потому что требует слаженных действий двух атакующих. Первый перехватывает и записывает себе данные в момент передачи легитимного сигнала от ключа сигнализации. Второй находится рядом с машиной и глушит тот самый легитимный сигнал, не давая ему дойти до приемника сигнализации.

В итоге «сим-сим» не открывается, и хозяин авто машинально нажимает на кнопку сигнализации снова и снова. Так жертва подыгрывает злоумышленникам и дает им запас кодов. Перехваченные сигналы легитимны, но до сигнализации они не дошли — поэтому система не помечает их как ранее использованные. В результате у атакующих остается несколько валидных кодов. По сути, это отложенная replay-атака: используется не только что перехваченный сигнал, а заранее «сохраненный».
Для защиты от такой атаки нужно добавить в полезную нагрузку инкрементный счетчик. То есть если вечером при закрытии машины брелок отправил сигнал с номером 52, а ночью злоумышленник попытается использовать ранее записанные сигналы с номерами 49 и 50, то авто их проигнорирует.
3. Relay-атака
Поднимаемся еще на один уровень сложности. При атаке ретрансляции (relay-атака) злоумышленники размещают одно радиоустройство около автомобиля, а другое — неподалеку от ключа сигнализации. В результате сигнал фактически удлиняется, и машина ошибочно считает, что ключ где-то рядом. Теперь злоумышленник может открыть и завести автомобиль.

Производители пытаются противостоять таким атакам, подсчитывая временные интервалы между отправкой сигнала от автомобиля и получением сигнала от брелока. Поэтому в новые системы добавляют UWB (Ultra Wideband), которые измеряют время пролета сигнала в наносекундах и точно определяют расстояние между ключом и машиной. Если время получения ответа больше обычного, то автомобиль не реагирует.
Справедливости ради отметим, что возможна еще DoS-атака, когда злоумышленник просто блокирует сигнал ключа, не давая владельцу открыть машину. Но это скорее пранк, чем средство получения доступа, так что подробно останавливаться на этой схеме не будем.
Вскрытие ключа
С теорией разобрались — переходим к практике. Для начала разберем ключ и изучим его внутренности. Вероятно, такой «хирургический» осмотр даст нам ценные сведения, которые пригодятся на этапе перехвата и анализа радиоволн.
Внешний вид
Ключ выполнен из пластика и внешне ничем не отличается от своих «коллег по цеху».

На лицевой стороне размещены 3 кнопки: «открыть багажник», «открыть машину», «закрыть машину». Рядом расположен светодиод, который загорается при нажатии любой из кнопок и при получении ответного сигнала. Также он срабатывает при включении/выключении зажигания и при запирании дверей. На тыльной стороне имеется физическая кнопка извлечения ключа — на случай, если батарейка прикажет долго жить.
Извлекаем ключ из «ножен»: на корпусе указаны буквенно-цифровые комбинации.

У меня сразу возникла гипотеза, что они должны как-то коррелировать с кодом, который передается сигнализации. В нашем случае верхний ряд — 3704020U344E-Z001, нижний ряд — SW1.6.2 231205.
Поискав в сети информацию об аналогичных ключах, я наткнулся на разбор корпуса с практически идентичной маркировкой.

Как видно на представленном фото, набор цифр почти полностью совпадает, кроме последних шести. Получается, маркировки на сигнализациях двух разных машин отличаются всего шестью цифрами: 231205 против 240702. Как говорится, «меня терзают смутные сомнения».
Так или иначе, наша область исследования существенно сужается: будем искать, где применить данную комбинацию.
2. Изучаем схемотехнику
Теперь по инструкции разбираем корпус ключа на две части и исследуем заветную схему с «мозгами».

Перед нами россыпи конденсаторов, 3 кнопки и множественная перфорация — ничего необычного. Впрочем, глаз цепляется за integrated circuit или, по-русски, интегральную схему с маркировкой A3XA5 и поддерживающим ее работоспособность кварцевым генератором на 27,6 МГц.

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

Больше ничего интересного на плате нет. Значит, формировать полезную нагрузку и отправлять сигнал автомобилю должен чип A3XA5. В таком случае не помешает найти даташит на эту микросхему.
К сожалению, в этот раз обращение к «всемогущему» интернету ничего не дало. Мне удалось найти лишь объявление на Таобао о продаже аналогичных ключей за 5 юаней — как говорится, ни в чем себе не отказывайте.

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

Наконец, все дорожки «подсвечены», прозвонка завершена и схема отрисована на бумаге.

Теперь самое время перевести схему в электронный формат. Для этого я воспользовался Draw.io.

К сожалению, я не смог произвести замеры элементов, так как каждый из них пришлось бы выпаивать. Поскольку мне еще ездить на этой машине, я не решился на столь отчаянные меры и ограничился лишь схемой. Но и такие полумеры кое-что прояснили.
Мое предположение подтвердилось: ведущую роль в ключе-брелоке играет чип A3XA5 — в нем калькулируется код, формируется и направляется на антенну полезная нагрузка. Данный чип должен быть программируемым. Раз у нас на выходе 433,92 МГц, а в качестве опоры используется кварц на 27,6 МГц, то внутри чипа наверняка имеется PLL/синтезатор частоты. Интересно, что отношение здесь . Раз это не какое-нибудь «красивое» целое умножение, то архитектура явно сложнее, чем примитивное «гармоника + усилитель».
Через контакты 9–10, 13–14 подается сигнал с индуктивной катушки на 125 кГц для бесключевого доступа. Параллельные LC-контуры (катушка + 2 конденсатора) и микросхемы, подключенные к парам выводов, очень похожи на резонансные входы LF-канала. Судя по двум LF-веткам, брелок умеет не только «ловить 125 кГц», но и аккуратно работать с ориентацией/уровнем поля. Это нужно для устойчивой работы в реальных условиях (с учетом помех) и для корректного определения положения ключа относительно автомобиля.
Контакты 5, 6 и 22, скорее всего, предназначены для отлаживания и перепрошивки чипа. При этом один из них может использоваться для 4-й кнопки, которая в данном исполнении отсутствует. К слову, в ключе от Geely Monjaro KX11 можно найти 4 кнопки управления на том же чипе. Но вернемся к нашему предмету исследования.
Справа сверху — группа конденсаторов на землю: этот декаплинг снимает импульсные токи передатчика, чтобы не «плавала» частота и не падало питание при отправке сигнала. Верхняя «богатая» LC-обвязка у антенны нужна для согласования с короткой антенной в корпусе брелка, а также для фильтрации гармоник. Благодаря этому брелок укладывается в нормы по излучению и не мусорит на 2х/3х частоте.
Радиоэфир
Теперь, когда мы более-менее разобрались с железом, можно перейти к основному функционалу ключа — передаче радиоволн. Для этого вооружимся RTL-SDR, так как он принимает чистый сигнал с минимальными шумами. Когда же дело дойдет до воспроизведения сигнала, переключимся на HackRF.
Определение основных характеристик
Для работы с SDR я буду использовать приложение Universal Radio Hacker — подробно о нем наряду с другими SDR-инструментами я рассказывал в прошлой статье.
Подключаем RTL-SDR, присоединяем антенну от Alfa Wi-Fi (да-да, знаю, что не соответствует по длинам волн) и запускаем программу.

Начинаем с 433,92 МГц — это самая распространенная частота на территории РФ для IoT и другого радиоуправляемого оборудования. Запускаем URH на «запись» и одновременно нажимаем кнопку на брелоке.

Сигнал перехвачен — давайте его детально изучим.
Во-первых, мы получили достаточно чистый и красивый сигнал, значит, брелок действительно работает на частоте 433,92 МГц.
Во-вторых, частота сигнала остается постоянной, а информация передается за счет изменения амплитуды — это признак амплитудной модуляции (AM). При этом амплитуда переключается между фиксированными уровнями (нули и единицы). Значит, перед нами цифровая разновидность AM — Amplitude Shift Keying (ASK).
Теперь посмотрим, как программа интерпретирует полученные значения.

Как видим, сигнал разбивается на повторяющиеся пары бит 01, 10, 11 и 00. Такое поведение характерно для Манчестерского кодирования, которое бывает двух видов: Manchester I и Manchester II (фактически они зеркальны друг другу). Запомним эту информацию на будущее и пойдем дальше.

Следующим шагом демодулируем, а потом декодируем сигнал с помощью URH.

После демодуляции и перевода значений в HEX сигнал стал более понятным и читаемым. Более того, если сравнить всё побайтово, мы увидим, что полученные значения совпадают между собой. Это указывает на то, что мы правильно выбрали частоту и модуляцию, а также чисто приняли сигнал.
Если отбросить преамбулу в виде пятерок, получаем следующую последовательность:
0f5565555aa9a6a656696a9595556aaa955555555559a6a9669a99a95a659555a8
Теперь перейдем во вкладку «Анализ» и декодируем сигнал. Кликаем Decoding и выбираем по очереди Manchester I и II. Также выберем для отображения формат HEX, чтобы программа не спамила нулями и единицами.


Итого:
Manchester I (без преамбулы ff) — f81fe09174c3bfc03ffffe90d228e5bf8.
Manchester II (без преамбулы 00) — 7e01f6e8b3c403fc000016f2dd71a407.
На одном сигнале далеко не уедешь, поэтому следующим шагом запишем несколько нажатий на кнопки и проведем детальный анализ. Но сперва кратко подытожим, что у нас получилось:
Частота — 433,92 МГц.
Модуляция — ASK.
Кодировка — Manchester.
Анализ полезной нагрузки
Расширим выборку: запишем несколько последовательных сигналов для каждой из трех кнопок на брелоке, а затем сравним эти сигналы. Снова открываем URH, выставляем частоту с модуляцией и начинаем запись.
Первым делом я записал еще два повторных сигнала на открытие машины. Вот что получилось после декодирования и перевода значений в HEX:

7e01f6e8b3c403fc000016f2dd71a407 (записанный в прошлом шаге)
7e01f6e8b3c403fc000016f48daa7b7f
7e01f6e8b3c403fc000016f7ca6e75f9
Даже по этим трем «снятым» сигналам уже можно сделать несколько главных выводов. Во-первых, перед нами не статичный, а плавающий код, который меняется каждый раз при нажатии на кнопку. Поэтому вышеупомянутая replay-атака здесь не пройдет.
Во-вторых, меняются только последние 9 символов. При этом в Manchester I код идет на понижение (смотрите на десятый с конца символ: d → b → 8), а в Manchester II — на повышение: 2 → 4 → 7.
Для простоты и сокращения подсчетов остановимся на Manchester II — просто потому, что складывать мне нравится больше, чем вычитать :)
Теперь по аналогии трижды запишем кнопку закрытия двери и декодируем в Manchester II:


7e01f6e8b3c409f6000017072095579d
7e01f6e8b3c409f600001709d71874d1
7e01f6e8b3c409f60000170a9ce3bf27
При сравнении этих пэйлоадов с предыдущими, кроме повышающего «хвоста», заметны изменения двух байт в середине перед 0000: было 03fc, стало 09f6. Предположим, что эти байты отвечают за выбор действия (открыть/закрыть машину).
Теперь проанализируем последнюю кнопку — открытия багажника.


7e01f6e8b3c405fa0000170d876ba6ab
7e01f6e8b3c405fa0000170e63a6deb3
7e01f6e8b3c405fa0000171042998141
И снова попадание в яблочко: те же инкрементный хвост и смена в 2 байт в середине перед нулями (05fa — для открытия багажника).
Настало время собрать все кусочки пазла в единую картину.

7e01f6e8b3c4 | 03fc | 0000 | 16f2dd71a407 (OPEN)
7e01f6e8b3c4 | 03fc | 0000 | 16f48daa7b7f (OPEN)
7e01f6e8b3c4 | 03fc | 0000 | 16f7ca6e75f9 (OPEN)
7e01f6e8b3c4 | 09f6 | 0000 | 17072095579d (CLOSE)
7e01f6e8b3c4 | 09f6 | 0000 | 1709d71874d1 (CLOSE)
7e01f6e8b3c4 | 09f6 | 0000 | 170a9ce3bf27 (CLOSE)
7e01f6e8b3c4 | 05fa | 0000 | 170d876ba6ab (TRUNK)
7e01f6e8b3c4 | 05fa | 0000 | 170e63a6deb3 (TRUNK)
7e01f6e8b3c4 | 05fa | 0000 | 171042998141 (TRUNK)
Итого, что мы имеем:
[Preamble / Zeros] = 000000000000000000000000000000000000000000000000000000
[DeviceID] (64 бит) = 7e01f6e8b3c4
[ButtonField] (16 бит) = 03fc (OPEN) / 09f6 (CLOSE) / 05fa (TRUNK)
[Reserved/Padding] (16 бит) = 0000
[CryptoBlock] (48 бит) = rolling, повышающий
Порядок отправки сигнала следующий: 268 нулей, пэйлоад (86 символов: 54 нуля и 32 — полезная нагрузка), пэйлоад, пэйлоад, пауза, повтор пэйлоада, пауза (повторение, пока не отпустят кнопку). Пауза между повторами — 4,48 миллисекунды.
Анализ второго ключа
У любого авто в комплекте идут два экземпляра ключей, и мой Москвич 3 — не исключение. Так что для чистоты эксперимента пришлось просканировать и второй брелок. Маркировка на корпусе совпадает с первым ключом (231205), однако код в эфир отправляется другой:
7e00d4ecb3c4 | 03fc | 0000 | 01115f6ab947
7e00d4ecb3c4 | 03fc | 0000 | 0113440eae05
Теперь сравним DeviceID первого и второго ключа:
7e01f6e8b3c4 — первый ключ;
7e00d4ecb3c4 — второй ключ.
Начало и конец одинаковые, а вот середина меняется.
Если мы посмотрим на DeviceID второго ключа (7e00d4ecb3c4) в двоичной системе, то получим:
01111110 00000000 11010100 11101100 10110011 11000100
01111110 00000001 11110110 11101000 10110011 11000100
Отбрасываем заголовок (7e) и хвост (b3c4), получаем:
00000000 11010100 11101100
00000001 11110110 11101000
Попробуем сравнить с маркировкой на ключе (231205) в двоичном виде:
00000011 10000111 00100101
Ничего общего. К сожалению, здесь никакой закономерности выявить не получилось.
Невольно возникают мысли о брутфорсе: если предположить, что у следующего ключа с такой же маркировкой на корпусе изменяемая часть DeviceID начинается на 02, то пространство перебора — от 0000 до FFFF, то есть 65 536 возможных комбинаций.
Анализ анализа
Итак, мы расставили все по полочкам — осталось лишь найти алгоритм формирования криптоблока (инкрементного хвоста). Это та самая часть пакета, которая меняется после каждого нажатия на кнопку брелока, чтобы защитить систему от replay-атак:
7e01f6e8b3c4 | 03fc | 0000 | 16f2dd71a407
7e01f6e8b3c4 | 03fc | 0000 | 16f48daa7b7f
7e01f6e8b3c4 | 03fc | 0000 | 16f7ca6e75f9
Сначала я предположил, что в шифроблоке используется CRC (Cyclic Redundancy Check). Это циклический избыточный код, который применяется для проверки целостности цифровых данных путем вычисления и добавления к ним контрольной суммы фиксированного размера.
Алгоритм делит данные на числа и выполняет полиномиальное деление, получая остаток (контрольную сумму). Для вычисления CRC необходимо задать полином (бывает от 0000 до FFFF), инициализацию (бывает от 0000 до FFFF) и XOR (обычно 0000 или FFFF).
Для проверки данной версии я навайбкодил скрипт, который позволяет путем перебора найти подходящие значения для CRC. Осталось только ввести значения: берем первые 2 криптоблока от сигналов на открытие машины — 16f2dd71a407 и 16f48daa7b7f — и подставляем их в последовательность.
Скрипт вычисляет всё на ура: poly=0x177A9, initCrc=0x71A6.

Увы, «недолго музыка играла…». После подстановки шифроблока из третьего элемента CRC не совпал. Более того, не нашелся общий «знаменатель», так что данная теория потерпела фиаско.

Следующие две недели я пытался хотя бы на миллиметр приблизиться к пониманию алгоритма формирования подписи. Я делил эти значения, умножал, отнимал, возводил в степень, менял системы счисления — всё было тщетно. Удалось найти единственную закономерность: при вычитании одного числа из другого получается дельта от 20 до 60–70 тысяч, а в исключительных случаях и более 100 тысяч. Казалось бы, при современных мощностях это брутится на раз. Но отсутствие конкретного конечного числа усложняло задачу брутфорса.
Тогда я решил посчитать, а сколько, в принципе, имеется комбинаций после инкремента. Я взял последние 8 цифр, так как девятую мы получим путем добавления от 1 до 3. Получилось (более 12 миллиардов). Негусто или, точнее говоря, слишком густо… И опять неопределенность: дельта скачет от 4 до 12 миллиардов.
А что, если сменить систему счисления? Я взял исходники сигналов до декодирования в Manchester и проверил комбинации (представляю сразу с полуанализом):
Исходники сигналов (инкремент выделен болдом)
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a6a96 69a99a95a659555a 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a6a99 6569a6665aa69aaa 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a6a9a a9665a6a5a99aaa5 8
0f5565555aa9a6a656696a9595 565aa9a5 55555555 59a955a 96556599999aa5a9 8
0f5565555aa9a6a656696a9595 565aa9a5 55555555 59a9565 a99a95a55a996995 8
0f5565555aa9a6a656696a9595 565aa9a5 55555555 59a9566 65a96a56a6aa965a 8
0f5565555aa9a6a656696a9595 559aaa65 55555555 59a9569 a55a9a66a65a6666 8
0f5565555aa9a6a656696a9595 559aaa65 55555555 59a956a 5a56a65a69aa6696 8
0f5565555aa9a6a656696a9595 559aaa65 55555555 59a9595 595665a5a5559955 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a9966 6995a665699a5996 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a9969 6966565556a95a95 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a996a a9a99a9666a6596a 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a9995 a6665666569aaa99 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a9996 59a6a5659a6a699a 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a9999 96599695969a6a55 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a999a 655995a665a66666 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a9a6a 66695a5656a569a6 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a9a95 65a9595a5965a699 8
Как видно, из-за формата представления данных получилась четверичная система счисления, где в качестве основных цифр выступают 5, 6, 9, a. То есть числовой ряд выглядит следующим образом: 5, 6, 9, а, 55, 56, 59, 5а, 65, 66, 69, 6а, 95, 96, 99, 9а, а5, а6, а9, аа, 555, 556 и т. д.
Притом последняя цифра всегда 8, так что ее смело отбрасываем.
Кроме того, 18-й символ с конца всегда увеличивается на 1 порядок в нашей системе исчисления (5, 6, 9, а), следовательно, его тоже можно исключить из перебора.
В сухом остатке у нас 16 символов, которые могут быть разбросаны в хаотичном порядке. Общее количество комбинаций составляет .
Если бы речь шла про оффлайн-брутфорсинг, то данная цифра подобралась бы за пару секунд. Но мы имеем дело с онлайн-отправкой радиоволны длительностью 225 миллисекунд, поэтому скорость перебора составит ~4 пэйлоада в секунду. На проверку всех возможных комбинаций уйдет 34 года.
Всё-таки не хотелось бы оставлять начатое исследование в наследство будущим поколениям, так что я решил обратиться за помощью к искусственному интеллекту. Я попросил моего ИИ-шного помощника посчитать статистику вероятности расположения цифр. Чат, кроме банальных вещей, выдал следующее:
Сильные соседства (шаг 1, вправо):
5→a (сильно чаще нормы)
9→a (сильно чаще нормы)
6→5 (чаще нормы)
a→6 (чаще нормы)
9→9 (чуть чаще нормы)
Избегаемые соседства (шаг 1, вправо):
6→a (заметно реже нормы)
a→a (реже нормы)
5→6 (реже нормы)
9→5 (реже нормы)
Кольцо переходов (шаг 1):
6 → 5 → a → 6 (самый выраженный «маршрут»)
Через один (шаг 2, X _ Y):
Усилены: a→5, 5→9, 9→a
Ослаблены: 5→a (важно: рядом часто, через один — редко), 9→5, 6→9
Частые горизонтальные триграммы:
666
665
65a
a66
99a
5a6
В общем, есть над чем подумать…
125 кГц
Проведем последнее испытание в лабораторных условиях: попытаемся возбудить индуктивную катушку ключа на 125 кГц через Proxmark3, устройство для работы с картами доступа. Proxmark3 может работать в двух режимах: высокочастотном (13,56 МГц) и низкочастотном на 125 кГц, который мы и будем использовать.
Для начала немного контекста. По моим личным наблюдениям, бесключевой доступ работает в нескольких типичных сценариях — при открытии двери (когда тянем за ручку), при контроле закрытия (чтобы не оставить ключ в салоне) и при запуске двигателя. В каждом из этих случаев автомобиль отправляет низкочастотный (125 кГц) запрос по LF-каналу, пытаясь «нащупать» ключ вблизи, а ключ, получив этот сигнал, отвечает по UHF-каналу (433 МГц), моргая светодиодом.
Мой план был довольно прост:
положить ключ на катушку индуктивности Proxmark и запустить ее;
одновременно с этим запустить на другом компьютере URH и поймать сигнал, который ключ будет отправлять в ответ.

Проведя все предварительные процедуры, запускаем ПО Proxmark, пишем lf search и …ничего. Светодиод ключа не оживает, сигнал отсутствует. Ладно, проверяем URH на предмет получения сигнала… тоже ничего. Повторяю процедуру несколько раз, но все тщетно: ключ не реагирует. Наша теория могла не подтвердиться лишь по одной из двух причин: либо мы ошиблись c частотой, либо ключ ожидает от автомобиля на 125 кГц корректно сформированный LF-запрос, который в нашем случае не был сгенерирован.
А что если нажать на кнопку ключа (например, открытия машины) одновременно с запуском Proxmark? Сказано-сделано: кладем ключ на Proxmark, зажимаем кнопку (светодиод загорается и потухает) и запускаем lf search… Светодиод погас.
Проводим эксперимент еще раз — всё повторяется: стоит запустить Proxmark на 433 МГц, как передача прерывается. Значит, частота 125 кГц всё-таки определена верно, а вот формат подачи неправильный.

Хорошо, в таком случае определим, какой формат низкочастотной передачи прерывает 433. Начнем поочередно проверять: lf awid read, lf em 410xread, lf fdx read… К сожалению, почти все форматы дают одинаковый результат: брелок сразу выключается.
Однако один формат 125 кГц дает отличную от остальных реакцию ключа. При запросе lf cotag read светодиод брелока на мгновение гаснет, а потом снова загорается. При повторном исполнении команды брелок выключается. Повторив такой опыт несколько раз и убедившись, что это не случайность, а норма, я снова запустил URH и проверил, что происходит в эфире на 433 МГц.

Как видно на графике, при запуске Proxmark текущий сигнал резко прерывается, и практически сразу же генерируется другой. Анализ пэйлоадов показал, что это совершенно новый сигнал, как будто я отпустил кнопку и снова ее нажал.

Чтобы на 100% проверить данное направление и больше к нему не возвращаться, снова кладу ключ на Proxmark и запускаю lf read. Программа ожидаемо не возвращает ничего полезного:
#db# LF Sampling config: #db# [q] divisor: 95 #db# [b] bps: 8 #db# [d] decimation: 1 #db# [a] averaging: 1 #db# [t] trigger threshold: 0 #db# [s] samples to skip: 0 #db# Done, saved 40000 out of 40000 seen samples at 8 bits/sample #db# buffer samples: 7b 7b 7b 7b 7c 7b 7b 7a ... Reading 39999 bytes from device memory Data fetched Samples @ 8 bits/smpl, decimation 1:1
В общем, и такая проверка не принесла результатов.
От лаборатории к полевым испытаниям
Кажется, в лабораторных условиях мы выжали максимум — дальше гипотезы нужно проверять вживую, на самом автомобиле.
Нам необходимо протестировать несколько гипотез.
Вдруг никакой формулы в хвосте ключа нет, а наша находка — всего-навсего случайное число, которое существенно выше предыдущего по значению?
Вытащим батарейку из ключа и посмотрим, какой код будет отправлять брелок (возможно, инициализация каждый раз начинается заново).
Проведем replay-атаку с задержкой в 20-30-50 комбинаций. Примет ли машина значение с брелока, меньшее последнего значения на блоке?
При нахождении в машине подадим LF-питание на брелок (запуск двигателя) и послушаем, что отправляется в эфир: вдруг там одинаковый код?
1. Случайное число в конце
Для проверки этой гипотезы нужно попробовать отправить сигнал с произвольно подобранным хвостом — и посмотреть, откроется ли машина. RTL-SDR для передачи не годится, поэтому в дело идет HackRF.
У этого инструмента есть недостаток: минимальный sample rate в 2 MS/s против 1 MS/s у RTL-SDR. Из-за этого в сигнал попадает больше внеполосных помех и запись получается грязнее. Но для одноразового воспроизведения сойдет — после нескольких попыток мне удалось получить достаточно чистую копию. Теперь открываем URH, переходим во вкладку «Генератор», вносим изменения в хвост сигнала, увеличивая счетчик, и отправляем сигнал.
К сожалению (или к счастью), открыть машину так и не удалось. Очевидно, что взаимосвязь между брелоком и машиной хоть и осуществляется по открытому незашифрованному каналу, но с использованием rolling code по специальной формуле. Установить эту формулу мне не удалось.

2. Сброс счетчика на ключе
Теперь проверим самый простой вектор:
запишем последний сигнал;
вскроем ключ и отсоединим батарейку на пару минут;
установим батарейку обратно и соберем ключ;
повторно запишем сигнал.
Увы, снова мимо. Счетчик продолжает увеличиваться с последнего значения, а не с начального. Выходит, что установленный в брелоке чип A3XA5 имеет энергонезависимую память и не завязан на питание батарейки. Результат: печаль для пентестера.
3. Replay-атака с задержкой
Учитывая результаты проверки второго вектора, такая атака тоже не вселяет больших надежд. И всё же исследование не будет полным, если не исчерпать все возможные векторы атаки.
Берем наши старые записанные сигналы и пробуем их воспроизвести: машина молчит. Кликаем по брелоку 50 раз, сажая батарею, и снова пробуем первые записи — ничего. Авто устояло, а очередная гипотеза разбита вдребезги.
Впрочем, давайте посчитаем, какой выходит цикл, если взять полученную ранее последовательность:
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a9a6a 66695a5656a569a6 8
0f5565555aa9a6a656696a9595 556aaa95 55555555 59a9a95 65a9595a5965a699 8
Как видим, меняется 7 символов: 59a9a6a, потом 59a9a95. Следовательно, наша формула состоит из четырех возможных символов в седьмой степени, что дает 16 384 комбинаций.
Теоретически провести replay-атаку с задержкой возможно. Только вот эта «задержка» будет измеряться тысячами шагов счетчика (то есть тысячами нажатий брелока). На практике реализовать такой сценарий затруднительно.
4. Подача LF-питания на брелок
Переходим к последнему сценарию: записи сигнала от брелока при подаче LF-питания. Для этого садимся в машину, нажимаем педаль тормоза и перехватываем пэйлоад.

В результате получаем очень короткий сигнал, который некоторые могут принять за шум. Окей, но что же там внутри? Для ответа на этот вопрос демодулируем сигнал и переведем в HEX (в данном случае HackRF отработал чисто, насколько это возможно).

Затем повторим процедуру и сравним сигналы.

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

Сигналы чем-то похожи, но и отличия существенные — подобрать такой же или даже вычислить формулу нереально.
ffff81d1fcd9ba8cc785dbe173c5e9ddf5f74397fd051e0d58
ffff81d1fd4e9e833ae1dbe103c3e8cdf5f63d9bfd87620db2

В общем, финальный счет — 4:0 в пользу авто.
Заключение
В целом защита брелока сигнализации оказалась выше моих ожиданий. Признаюсь, я рассчитывал на легкую прогулку и быстрый взлом: как-никак, это китаец в российском обличии. На деле оказалось, что производитель позаботился о безопасности.
Конечно, можно было бы добавить еще симметричного шифрования, чтобы сигнал стал менее предсказуемым. Но и в реализованной схеме подобрать 4 миллиарда комбинаций не представляется возможным. Впрочем, в теории могут найтись энтузиасты с хорошей математической подготовкой, которым удастся восстановить алгоритм генерации сигнала и подписи.
Если резюмировать, результаты исследования порадовали меня как автовладельца, но расстроили как пентестера. Впрочем, это не значит, что Москвич 3 — неразгрызаемый орешек для угонщиков. Авто можно вскрыть не только при помощи криптовзлома ключа, но и механическими способами. Например, подключиться к OBD и прописать туда свой ключ — дело нескольких минут при наличии сноровки. Интересно также посмотреть, что можно сделать с помощью некоторых хакерских девайсов со специальной прошивкой и дополнительным функционалом, позволяющим декодировать сигнал от разных авто.
Так или иначе, описанное исследование показывает: угнать Москвич 3 через взлом брелока — задача не из простых. Но это не тот случай, когда можно спокойно выдохнуть и забыть про безопасность: если не получается через брелок, всегда найдется другой, более приземленный способ.
Также ненавязчиво приглашаю всех в свой Telegram-канал, где вы найдете массу интересного по теме аппаратного хакинга: http://t.me/glinkinivan

PURP — Telegram-канал, где кибербезопасность раскрывается с обеих сторон баррикад
t.me/purp_sec — инсайды и инсайты из мира этичного хакинга и бизнес-ориентированной защиты от специалистов Бастиона
Комментарии (39)

Alex_v99
22.04.2026 09:50А атаку с "удочкой" не проверяли?

GlinkinIvan Автор
22.04.2026 09:50К сожалению, нет.
Не подскажете, что это такое и как работает?
Alex_v99
22.04.2026 09:50Вы описали его в разделе Relay-атака. Извиняюсь, я полагал что жаргонное название такой атаки у всех на слуху...

vvzvlad
22.04.2026 09:50Это же бастион. У них каждая статья про железный инфобез из разряда "школьники открывают для себя айти". То они тампер замыкают припоем, то в прошлой статье рассказывали что килок — это "дорогие откатные ворота в госструктурах и сигнализации в автомобилях класса выше бюджетного", хотя он уже давно удел гаражных ворот.

strvv
22.04.2026 09:50Если надо сдать план по публикациям, ибо всё реклама, за исключением некролога. Но в качестве обучающего для исследователей как можно построить план исследований чего-либо сойдёт.

Shaman_RSHU
22.04.2026 09:50Не занимались исследованиями транспорндеров для платных магистраей (например, Западный скоростной диаметр в Санкт-Петербуре и ЛенОбласти)?

GlinkinIvan Автор
22.04.2026 09:50Да, были в планах такие идеи) Даже немного изучил, что там UHF RFID (если память не изменяет).
Но пока руки не дошли еще.

MaFrance351
22.04.2026 09:50Для защиты от такой атаки нужно добавить в полезную нагрузку инкрементный счетчик. То есть если вечером при закрытии машины брелок отправил сигнал с номером 52, а ночью злоумышленник попытается использовать ранее записанные сигналы с номерами 49 и 50, то авто их проигнорирует.
Иногда, правда, и это обходится.
Для этого ключ глушится, а злоумышленник сам отправляет первый из принятых кодов на открытие. Жертва думает, что ключ наконец-то сработал, а сигнализация чуть позже принимает и последующие перехваченные коды, потому что их порядок не нарушен.

BugM
22.04.2026 09:50Не совсем. Владелец потом закроет машину передав код с номером еще больше. И все перехваченное станет невалидным.
И даже перехват закрытия машины не поможет. Останутся только валидные сигналы на закрытие.
Для успеха два раза подряд перехватить циклы открыть-закрыть.

strvv
22.04.2026 09:50Да, это кейлог обходит, самосинхронизация. Иначе пропустил 2-3 кола и меняй/шей сигналку?

alcotel
22.04.2026 09:50А что машина на 125 кГц передаёт?
Наверное, код тоже не постоянный, и требует смены кода в ответе. Но всё-же проверить тоже было бы интересно.
Я, когда последний раз подбирал формулу для CRC, воспользовался её линейностью. Для подбора кода 64-битного сообщения нужно 64 линейно независимых кода. И ещё несколько - для проверки. Если линейности нет и близко - это точно не CRC, а уже ближе к хеш-сумме с криптографическими свойствами.

GlinkinIvan Автор
22.04.2026 09:50к сожалению в моей арсенале SDR-приемника для такой низкой частоты нет

MaFrance351
22.04.2026 09:50Заинтересовался. Оказывается, из популярных SDRов только Лайм может такое принять (у него диапазон от 100 кГц).
Правда, думаю, в случае с ключом проще не SDR использовать, а какой-то другой приёмник, более подходящий для этого.
dkom
Дата выпуска прошивки, ревизии платы и что-то типа того. Первая цифра год.
GlinkinIvan Автор
Да, как одна из теорий - почему бы и нет