В июле 2022 года у исследователя безопасности Иана Табора угнали Toyota RAV4. Не через ретранслятор брелока, не через дыру в Bluetooth - через разъём левой фары. Два провода CAN High и CAN Low, устройство стоимостью в десятку долларов по компонентам, корпус от JBL-колонки для маскировки. Инцидент получил идентификатор CVE-2023-29389 и вскрыл то, о чём в автомобильной индустрии предпочитали молчать: протокол CAN, спроектированный в 1980-х, безоговорочно доверяет каждому фрейму на шине. Никакой аутентификации отправителя. Вообще.
Здесь разберём полный kill chain атак на CAN bus автомобиля - от лабораторного стенда и сниффинга трафика до инъекции фреймов, fuzzing ECU и принудительного отключения узлов через Bus-Off. Каждый этап - с конкретными командами, hex-значениями и объяснением на уровне протокола.
Почему CAN bus - идеальная мишень для атакующего
Controller Area Network создавался под инженерную задачу: заменить десятки килограммов медной лапши единой двухпроводной шиной. По данным VicOne, CAN bus экономит до 50 фунтов проводки в типичном автомобиле, где суммарная длина кабелей подбирается к миле. Приоритет - надёжность и экономия, а не защита от злоумышленника. Из-за этого automotive cybersecurity CAN остаётся больной темой для всей отрасли.Архитектурные свойства протокола, которые делают возможными атаки на CAN bus автомобиля:
Broadcast-среда без адресации отправителя. Каждый фрейм на шине виден всем ECU разом. Поле Arbitration ID задаёт приоритет сообщения и тип данных, но не идентифицирует источник. Любой узел - легитимный или воткнутый атакующим - может послать фрейм с произвольным ID, и все ECU проглотят его как штатный. На этом принципе и строится CAN-инъекция.
Арбитраж как вектор атаки. Когда два узла начинают передачу одновременно, побеждает фрейм с меньшим числовым значением ID - доминантные биты (логический 0) подавляют рецессивные (логическую 1). Исследование CANAttack (PMC, 2023) экспериментально показало: атакующий с высокоприоритетным ID стабильно выигрывает арбитраж и вытесняет легитимные сообщения. Латентность скомпрометированного узла - минимальна, а легитимные ECU стоят в очереди и страдают.
Механизм обработки ошибок. Стандарт CAN предусматривает счётчики ошибок (TEC и REC) для каждого узла. При накоплении ошибок узел последовательно переходит из Error Active в Error Passive и затем в Bus-Off - полное отключение от шины. Атакующий может спровоцировать этот переход искусственно, подменяя отдельные биты в чужих фреймах (подробности - в исследовании на OpenNet).
Множество физических точек доступа. OBD-II порт - самый известный, но далеко не единственный вход. Проводка CAN шины тянется к фарам, зеркалам, датчикам парковки, дверным модулям. В случае CVE-2023-29389 угонщики зашли через разъём левой фары Toyota RAV4 - хватило отогнуть бампер. Эксплуатация OBD-II атаки и подобных точек входа не требует хакерской квалификации - только физического доступа к машине.
Собираем стенд для пентеста автомобильных систем
Прежде чем лезть к реальному автомобилю, всё тестирование - на изолированном стенде. Это не перестраховка: без стенда невозможно понять семантику конкретных Arbitration ID и корректно декодировать сигналы для эксплуатации CAN протокола.Требования к окружению
Операционная система: Linux (Ubuntu 22.04 LTS или Kali Linux). Критична поддержка SocketCAN - нативной подсистемы ядра для работы с CAN-интерфейсами. На Windows придётся возиться с отдельным стеком вроде PCAN-View, что убивает автоматизацию.CAN-адаптер (на выбор):
| Адаптер | Цена (примерно) | SocketCAN | Применение |
|---|---|---|---|
| MCP2515 + MCP2551 (Arduino/RPi) | Менее 15 USD | Через драйвер spi-can | Бюджетный стенд, обучение |
| CANable (open-source, STM32) | 25–40 USD | Нативно (candleLight) | Компактный USB-адаптер |
| Kvaser Leaf Light v2 | 300+ USD | Нативно | Промышленный, высокая стабильность |
Я для домашнего стенда начинал с Arduino + MCP2551 E/P - дёшево и воспроизводимо (такой же вариант описан в исследовании на OpenNet). Для серьёзного automotive penetration testing лучше Kvaser или аналогичный промышленный адаптер - на высоких скоростях бюджетные решения иногда чудят.
Софт:
can-utils- утилитыcandump,cansend,cangen,canbusloadдля базовых операций через SocketCANpython-can- Python-библиотека для программной отправки и приёма фреймов- SavvyCAN - GUI-анализатор трафика CAN с поддержкой DBC-файлов
- Wireshark с модулем SocketCAN - для глубокого анализа на уровне пакетов
После подключения адаптера поднимаем интерфейс:
sudo ip link set can0 up type can bitrate 500000. Стандартная скорость для большинства автомобильных CAN шин - 500 кбит/с, хотя встречаются 125 кбит/с (low-speed CAN) и 250 кбит/с. Проверяем через candump can0 - если ECU на стенде активны, в терминале побегут фреймы с Arbitration ID и данными в hex.Инъекция фреймов CAN bus: от CVE-2023-29389 до собственного PoC
Инъекция фреймов CAN bus - базовая и самая распространённая атака. Суть предельно проста: атакующий втыкается в шину и шлёт фреймы, неотличимые от легитимных, потому что протокол не проверяет источник. Через инъекцию и реализуется ECU спуфинг - подмена сообщений от конкретного блока управления.CVE-2023-29389: анатомия реальной CAN-инъекции
Согласно NVD, уязвимость CVE-2023-29389 затрагивает Toyota RAV4 2021 года: автомобиль безоговорочно доверяет сообщениям от других ECU на CAN шине, что позволяет физически находящемуся рядом атакующему завести двигатель. Достаточно добраться до управляющей CAN шины через разъём фары (отогнув бампер) и закинуть поддельные сообщения «Key is validated» через CAN-инъекцию. Эксплуатация зафиксирована в дикой природе начиная с июля 2022 года.CVSS 3.1: 6.8 (MEDIUM). Вектор:
CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. Разберём компоненты:- AV
(Physical) - атакующий должен физически стоять у машины - AC:L (Low) - сложность эксплуатации минимальна, обходить нечего
- PR:N (None) - никаких привилегий, только доступ к проводке
- UI:N (None) - от владельца ничего не требуется
- C:H / I:H / A:H - полный компромисс конфиденциальности, целостности и доступности
Хронология атаки по данным расследования Кена Тинделла (Canis Automotive Labs) и анализа VicOne:
- Угонщик отгибает передний бампер и добирается до разъёма проводки левой фары, подключённой к управляющей CAN шине
- К проводам CAN High и CAN Low подключается устройство на базе чипа PIC18F с CAN-трансивером и схемой dominant-override. Корпус замаскирован под Bluetooth-колонку JBL - если полиция заметит, подозрений ноль
- Устройство шлёт wake-up фрейм и ждёт ответа от шины
- После ответа включается dominant-override - схема подавляет передачу от легитимных ECU, включая настоящий контроллер смарт-ключа, заставляя их проигрывать арбитраж
- Инжектор забрасывает поддельные фреймы «Key is validated, unlock immobilizer» с частотой ~20 раз в секунду
- Gateway ECU послушно копирует фреймы на другую CAN шину, ECU двигателя деактивирует иммобилайзер
- Следующая порция фреймов отпирает двери - эквивалент нажатия кнопки «Open» на брелоке
Пишем инжектор на python-can: пошаговая инструкция
На лабораторном стенде воспроизведём принцип инъекции. Допустим, через предварительный сниффинг (candump can0 -l) при различных действиях с автомобилем мы уже определили целевой Arbitration ID и формат данных.
Python:
import can
import time
bus = can.interface.Bus(channel='can0', interface='socketcan')
# Демонстрация концепции - реальные ID и данные
# восстанавливаются реверсом конкретной модели
msg = can.Message(
arbitration_id=0x620,
data=[0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
is_extended_id=False
)
for _ in range(100):
bus.send(msg)
time.sleep(0.05) # ~20 фреймов/с, как в реальном CAN-инжекторе
Пара важных моментов.
arbitration_id=0x620 - демонстрационное значение, не привязанное к конкретной модели. В реальном пентесте автомобильных систем ID определяется через реверс-инжиниринг: записываем трафик, сравниваем дампы в SavvyCAN, при наличии DBC-файла производителя декодируем сигналы через cantools. Без DBC - восстанавливаем семантику руками, коррелируя изменения в данных фреймов с физическим поведением машины (угол руля, обороты, состояние замков). Муторно, но работает.Частота 20 фреймов в секунду (
time.sleep(0.05)) совпадает с параметрами реального CAN-инжектора из CVE-2023-29389. Значение не случайное: достаточно высокое, чтобы Gateway ECU гарантированно принял хотя бы один фрейм за цикл опроса, но не настолько агрессивное, чтобы примитивная IDS поймала аномалию по частоте.Для проверки на втором терминале запускаем
candump can0 -td - в выводе должны быть видны инъецированные фреймы с характерным интервалом ~50 мс.Fuzzing CAN шины: поиск скрытых уязвимостей в ECU
Если инъекция фреймов - воспроизведение известной атаки с конкретными ID и данными, то fuzzing CAN шины - поиск неизвестных реакций ECU на неожиданный ввод. Цель - найти необработанные состояния: зависание ECU, перезагрузку, переход в недокументированный диагностический режим, утечку данных через ответные фреймы. Для vehicle network security fuzzing - основной метод обнаружения zero-day в прошивках ECU.
🔓 Эксклюзивный контент для зарегистрированных пользователей.
Виды fuzzing и выбор стратегии
Random fuzzing - генерация фреймов со случайными Arbitration ID и данными. Запускается одной командой:cangen can0 -g 1 -I r -L 8 -D r - рандомный ID, 8 байт случайных данных, интервал 1 мс. Проблема очевидна: пространство перебора чудовищное - 2048 стандартных ID, на каждый до 2^64 комбинаций данных. Большинство комбинаций не вызовут никакой видимой реакции, и поиск «интересного» ответа превращается в иголку в стоге сена.Targeted fuzzing - куда эффективнее. Сначала через
candump определяем активные ID на шине, затем для каждого ID систематически варьируем байты данных, отслеживая реакцию целевого ECU. В датасете CAN-MIRGU (NDSS VehicleSec 2024) исследователи классифицировали атаки на три типа: DoS (высокочастотная инъекция с фиксированным ID), Fuzzy (случайные данные при фиксированном ID), Spoofing (подмена конкретных сигналов с корректным форматом). Targeted fuzzing объединяет элементы Fuzzy и Spoofing.UDS-directed fuzzing - самый целенаправленный вариант для взлома внутренней сети автомобиля. Протокол UDS (ISO 14229) использует CAN как транспорт и определяет стандартные диагностические сервисы:
0x10 (DiagnosticSessionControl), 0x27 (SecurityAccess), 0x31 (RoutineControl), 0x23 (ReadMemoryByAddress). Fuzzing UDS-сервисов позволяет обнаружить незадокументированные диагностические сессии, обход SecurityAccess через слабые seed-key алгоритмы, доступ к записи в память ECU без аутентификации.
Python:
import can
import time
bus = can.interface.Bus(channel='can0', interface='socketcan')
# Перебор UDS-сервисов - ищем, кто отзовётся
for service_id in range(0x00, 0x100):
msg = can.Message(
arbitration_id=0x7DF, # broadcast диагностический запрос
data=[0x02, service_id, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00],
is_extended_id=False
)
bus.send(msg)
time.sleep(0.1)
0x7DF - стандартный для OBD-II диагностических запросов по ISO 15765-4. Ответы приходят в диапазоне 0x7E8–0x7EF (зависит от конкретного ECU). Мониторим через candump can0,7E8:7F8 и ищем положительные ответы: если ECU отвечает фреймом, начинающимся с 0x06, 0x50, ... - сервис DiagnosticSessionControl (0x10) доступен и можно переключиться в расширенную сессию. Бинго.Техника безопасности при fuzzing: отправка случайного фрейма на шину работающего автомобиля может отключить ABS, деактивировать подушки безопасности или заблокировать руль. Все эксперименты - только на изолированном стенде или на машине с выключенным двигателем, поднятой на подъёмнике, с отключённой тормозной системой от CAN. Это не паранойя - это здравый смысл.
Bus-Off атака: эксплуатация CAN протокола на уровне спецификации
Bus-Off - отдельный класс CAN bus уязвимостей, эксплуатирующий не отсутствие аутентификации, а штатный механизм обработки ошибок. Именно поэтому проблему невозможно закрыть обновлением прошивки - она заложена в саму спецификацию протокола CAN. Тут нужна переработка стандарта, а не патч.Каждый ECU поддерживает два счётчика: Transmit Error Counter (TEC) и Receive Error Counter (REC). При ошибке в передаваемом фрейме TEC увеличивается на 8, при успешной передаче уменьшается на 1. Асимметрия - ключ к атаке. Переход состояний:
| TEC | Состояние | Поведение узла |
|---|---|---|
| 0–127 | Error Active | Нормальная работа, отправляет Active Error Flags |
| 128–255 | Error Passive | Может передавать, но с ограничениями |
| Более 255 | Bus-Off | Полное отключение от шины |
Атакующий вызывает каскадный рост TEC у целевого ECU, подменяя отдельные биты в его фреймах прямо во время передачи. Не целые фреймы подставляются - точечная модификация: один бит превращает легитимный фрейм в ошибочный (подробности - в исследовании на OpenNet). Целевой ECU «считает», что его собственные сообщения содержат ошибки, инкрементирует TEC и через несколько десятков итераций уходит в Bus-Off. Всё, узел мёртв.
Практические сценарии, описанные исследователями: отключение ECU автоматического торможения перед препятствием, нарушение контроля дроссельной заслонки (двигатель продолжает ускоряться при отпущенной педали газа), деактивация модуля подушек безопасности, отключение ABS. В терминах MITRE ATT&CK - Endpoint Denial of Service (T1499, Impact).
Существенное ограничение: Bus-Off технически сложнее простой инъекции. Побитовая модификация требует точной синхронизации с передачей целевого ECU на физическом уровне, что невозможно через стандартный SocketCAN - нужен прямой доступ к CAN-трансиверу через FPGA или кастомную прошивку микроконтроллера с аппаратным CAN-контроллером.
Протокол CAN, кстати, живёт далеко за пределами автомобилей. Bus-Off уязвимость актуальна для лифтов, автоматических дверей, железнодорожного транспорта и промышленной автоматики - везде, где крутится Controller Area Network.
Маппинг атак на CAN bus в терминах MITRE ATT&CK
Automotive cybersecurity всё чаще рассматривается через призму MITRE ATT&CK. Фреймворк создавался для корпоративных сетей, но его тактики на удивление точно ложатся на kill chain атак на внутреннюю сеть автомобиля.| Этап атаки на CAN bus | Тактика | Техника | ID |
|---|---|---|---|
| Подключение устройства к шине | Initial Access | Hardware Additions | T1200 |
| Запись трафика для реверс-инжиниринга | Discovery, Credential Access | Network Sniffing | T1040 |
| Подавление легитимных ECU (dominant-override) | Credential Access, Collection | Adversary-in-the-Middle | T1557 |
| Инъекция поддельных фреймов | Impact | Transmitted Data Manipulation | T1565.002 |
| Bus-Off атака на конкретный ECU | Impact | Endpoint Denial of Service | T1499 |
| Перепрошивка ECU для закрепления | Defense Evasion, Persistence | Component Firmware | T1109 |
Маппинг полезен не только для отчётов по пентесту, но и для построения матрицы детектирования: каждой технике сопоставляется источник данных (трафик CAN, логи Gateway ECU, аппаратные датчики) и правило обнаружения.
Обнаружение и защита от атак на внутреннюю сеть автомобиля
Защита CAN bus - задача нетривиальная: протокол не предусматривает аутентификации на уровне стандарта. Но рабочие подходы существуют, и все они - комбинация нескольких уровней.Timing-based IDS. Каждый ECU шлёт фреймы с характерной периодичностью: модуль ABS - каждые 10 мс, климат-контроль - каждые 100 мс. Инъекция дополнительных фреймов с тем же ID ломает эту периодичность. IDS, анализирующая интервалы между фреймами одного ID, ловит ECU spoofing с высокой точностью. По данным CANAttack (PMC, 2023), при DoS-атаке через арбитраж латентность легитимных сообщений резко прыгает - надёжный индикатор компрометации.
Entropy-based detection. Нормальный трафик CAN предсказуем: фиксированный набор ID, ограниченный диапазон значений в полях данных. Fuzzing-атака резко поднимает энтропию - появляются нетипичные комбинации. Исследователи из журнала «Защита информации. Инсайд» предложили визуальную аналитику на основе радиальных гистограмм для мониторинга DoS, Fuzzy и Spoofing атак по дампам трафика - подход, полезный и при разборе инцидентов постфактум.
Перепрограммирование Gateway ECU. CVE-2023-29389 показала: Gateway ECU Toyota RAV4 тупо ретранслировал фреймы между шинами без проверки. Временное решение от Тинделла: перепрограммировать Gateway так, чтобы он пересылал сообщения о валидации ключа только при отсутствии ошибок на шине в течение заданного окна. Логика: CAN-инжектор с dominant-override неизбежно генерирует ошибки при подавлении других узлов. Нет ошибок за окно времени - можно пересылать. Есть - блокируем.
Zero Trust для CAN. Постоянное решение, описанное VicOne: ECU должны прекратить доверять сообщениям по умолчанию. Каждый фрейм проходит криптографическую валидацию - ECU получают секретные ключи и привязываются к конкретному автомобилю. На практике это CAN FD с дополнительными байтами для MAC (Message Authentication Code) или перевод критичных сегментов на Automotive Ethernet.
Сегментация шин. Вместо единой шины - топология с центральным коммутатором, фильтрующим трафик по правилам. Фрейм от модуля фар физически не попадает на шину управления двигателем. При такой архитектуре атака через разъём фары, как в CVE-2023-29389, невозможна: даже получив доступ к одному сегменту, атакующий не может инъецировать фреймы в критичный.
Вопрос к читателям
Bus-Off атака упирается в точную синхронизацию с битовым потоком целевого ECU. На стандартном SocketCAN-адаптере типа CANable с прошивкой candleLight задержка между user-space и физическим уровнем делает побитовую модификацию фреймов практически невозможной. У кого есть опыт реализации Bus-Off на стенде - какое оборудование использовали для побитового доступа: FPGA на Xilinx Zynq с IP-ядром CAN, кастомная прошивка на STM32 с прямым управлением аппаратным CAN-контроллером, или коммерческий анализатор вроде CANalyzer с CAPL-скриптом? Поделитесь конфигурацией стенда и достигнутой точностью синхронизации в наносекундах.
Последнее редактирование модератором: