CAN OBD-II Автомобили Взлом Книга Перевод

Craig Smith. Библия автомобильного хакера

Craig Smith. Библия автомобильного хакера

Мы начинаем публиковать перевод новой книги. На этот раз это будет ещё один “фолиант” от No Starch, прославившихся своими изданиями. На этот раз перевод будет публиковаться одной записью и для того чтобы получить обновление – достаточно будет просто обновить. Надеемся, что тебе понравится, а заодно и напоминаем, что любые тесты и аудиты лучше проводить с согласия хозяев ресурсов или собственности, соблюдай эти правила и проблем с законом не будет. Напоминаем, что мы не придумываем это сами, а лишь переводим и не несём ответственности за то как ты воспользуешься полученными знаниями.

Предисловие

Мир нуждается в хакерах, в том числе и в автомобильных. Автомобильные технологии, как и всё остальные, имеют тенденцию к усложнению и расширению взаимосвязанности. Все эти тенденции в совокупности требуют большего внимания к автомобильной безопасности и более талантливых специалистов, которые займутся этим.

Но кто такой хакер? Этот термин в последнее время был сильно искажен основными средствами массовой информации, но правильное использование термина «хакер» относится к человеку, который создает, исследует, интересуется – тому, кто учится искусству экспериментирования и разбирает системы до малейших деталей, чтобы понять их устройство. По моему опыту, лучшие профессионалы в области (а также просто любители) – это те, кому от природы интересно знать, как устроены вещи. Эти люди исследуют, копаются экспериментируют и разбирают, иногда просто ради удовольствия. Эти люди взламывают.

Автомобиль может быть довольно непростой целью для взлома. В большинстве автомобилей нет клавиатуры и формы для входа в систему – они поставляются с возможно незнакомыми наборами протоколов, процессоров, разъемов и операционных систем. Эта книга раскрывает общие компоненты автомобилей и познакомит вас с легкодоступными инструментами и информацией, которые помогут вам начать ваш путь в автомобильной безопасности. К концу книги вы поймете, что автомобиль – это совокупность подключенных к нему компьютеров, ну и колеса, разумеется. Вооружившись соответствующими инструментами и информацией, можете быть уверены, вы сможете взломать автомобиль.

Эта книга также содержит много тем об открытости. Мы чувствуем себя в большей безопасности, когда системы, от которых мы сильно зависим, можно инспектировать, исследовать и документировать, в том числе и автомобильные системы. Поэтому я рекомендую использовать эту книгу для исследования, аудита и документирования. С нетерпением жду возможности прочитать о некоторых ваших открытиях!

Введение

В 2014 году Open Garages – группа людей, заинтересованных в совместной работе по вопросам безопасности транспортных средств – выпустила первый мануал автохакера в качестве материала для курса по взлому автомобилей. Оригинальная книга была написана, чтобы, вмещавшись в бардачок автомобиля, она охватывала основы взлома автомобилей на однодневных или двухдневных курсах по автомобильной безопасности. Мы даже не предполагали, что книга вызовет такой интерес: за первую неделю ее загрузили более 300 тысяч раз. Фактически, популярность книги вырубила нашего интернет-провайдера (дважды!), чем они, разумеется, были недовольны. (Ничего страшного, они простили нас, и это хорошо, потому что я люблю своего небольшого провайдера. Привет SpeedSpan.net!)

В большинстве своем отзывы читателей были положительными. Бо́льшая часть критики была связана с тем, что руководство было слишком коротким и не содержало достаточное количество деталей. Эта книга направлена на удовлетворение этих жалоб. Библия автомобильного хакера дает гораздо больше подробностей о взломе автомобилей и даже охватывает некоторые вещи, которые напрямую не связаны с безопасностью, например, прокачку производительности и полезные инструменты для лучшего понимания, и работы с транспортными средствами.

Почему взлом автомобилей полезен для всех

Если вы читаете эту книгу, вероятно, вы уже знаете, почему хотите взламывать машины. Но на всякий случай вот удобный список с подробным описанием преимуществ взлома автомобилей:

Автомобильная промышленность выпускает удивительные автомобили со сложной электроникой и компьютерными системами, но предоставляет мало информации о том, что заставляет эти системы работать как целое. Поняв, как работает сеть автомобиля и как она взаимодействует в своей собственной системе и за ее пределами, вы сможете лучше диагностировать и устранять возникшие с автомобилем проблемы.

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

Понимание того, как устроены автомобили, может привести к модификациям, таким как снижение расхода топлива и использование сторонних запчастей. Как только вы разберетесь с системой взаимодействия, вы сможете легко интегрировать другие системы в свой автомобиль, например, дополнительный дисплей для отображения производительности или сторонние компоненты, которые интегрируются так же хорошо, как и заводские.

Иногда машины оснащаются не задокументированными или просто отключенными функциями. Обнаружение недокументированных и/или отключенных функций и их использование позволит вам эксплуатировать свой автомобиль в полной мере. Например, в автомобиле может быть недокументированный режим Valet, который позволит вам перевести автомобиль в ограниченный режим перед передачей ключей посторонним.

На момент написания этой книги, правила безопасности транспортных средств не касались вредоносных электронных угроз. Несмотря на то, что автомобили уязвимы для того же вредоносного ПО, что и ваш компьютер, автопроизводители не обязаны проверять безопасность электроники автомобиля. Эта ситуация просто неприемлема: мы возим на автомобилях свои семьи и друзей, и каждый из нас должен знать, что наши автомобили максимально безопасны. Если вы научитесь взламывать свою машину, вы будете знать ее уязвимости, сможете принять соответствующие меры предосторожности и стать лучшим сторонником высоких стандартов безопасности.

Автомобильная промышленность также сможет извлечь пользу из знаний, содержащихся в этой книге. В этой книге представлены рекомендации по выявлению угроз, а также современные методы обхода существующих средств защиты. Эта книга не только поможет вам разработать собственные методы обеспечения безопасности, но и предлагает исследователям сообщать о своих находках.

            Автомобили никогда не были так сильно напичканы электроникой как сегодня. В отчете IEEE Spectrum под названием «This Car Runs on Code», автор Роберт Н. Шаретт отмечает, что по состоянию на 2009 год автомобили обычно разрабатывались с более чем 100 микропроцессорами, 50 электронными блоками управления, 8 километрами проводки и 100 миллионами строк кода (http://spectrum.ieee.org/transportation/systems/this-car-runs-on-code). Инженеры Toyota шутят, что единственная причина, по которой они все еще ставят на свои машины колеса – это чтобы асфальт не царапал компьютеры. По мере того, как компьютерные системы становятся все более неотъемлемой частью транспортных средств, выполнение проверок безопасности становится пропорционально более важным и сложным процессом.

ВНИМАНИЕ

Взлом автомобилей следует воспринимать серьезно. Игры с сетью, беспроводными соединениями, бортовыми компьютерами или другой электроникой может повредить или вывести их из строя. Экспериментируя с любой из описанных в книге техник сделайте безопасность первостепенной задачей.  Как вы понимаете, ни автор, ни издатель этой книги не несут ответственности за любой ущерб, нанесенный вашему автомобилю.

1

Понимание моделей угроз

Если вы пришли из мира тестирования программ на проникновение, вы, вероятно, уже знакомы с поверхностями атак. Для всех остальных из нас, поверхность атаки относится ко всем возможным способам атаки цели, от уязвимостей в отдельных компонентах до уязвимостей, затрагивающих автомобиль в целом.

Обсуждая поверхность атаки, мы не рассматриваем, как эксплуатировать цель, нас интересует только точки входа в нее. Вы можете представлять площадь атаки как площадь поверхности по сравнению с объемом объекта. Так, два объекта могут иметь одинаковый объем, но совершенно разные площади поверхности. Чем больше площадь поверхности, тем больше риск. Если считать, что объем объекта является его ценой, наша цель по усилению безопасности – снизить соотношение риска к цене.

Поиск направлений атаки

Оценивая направление атаки на транспортное средство, представьте себя злоумшленником, пытающимся причинить автомобилю вред. Чтобы найти слабые места в системе безопасности прежде всего осмотрите машину вдоль и поперёк, обратите внимание на окружающую среду. Обязательно подумайте обо всех способах, через которые данные могут попасть в автомобиль, а также обо всех возможностях связи транспортного средства с внешним миром.

Изучая авто, задайтесь следующюми вопросами:

При осмотре салона учитывайте следующее:

Как видите, способов попадания данных в автомобиль довольно много. Что произойдет, если какие-либо из этих данных будут искажены или намеренно вредоносны? Вот тут и вступает в игру моделирование угроз.

Моделирование угроз

О моделировании угроз написаны целые книги, но я хочу дать вам краткий обзор, чтобы вы могли построить свои собственные модели угроз. (Если у вас есть дополнительные вопросы или вам просто интересна эта тема, обязательно прочтите какую-то тематическую книгу!)

При моделировании угроз автомобиля вы собираете информацию об архитектуре вашей цели и создаете диаграмму, чтобы проиллюстрировать, как части авто взаимодействуют между собой. Затем вы используете эти карты для выявления уязвимых входов и ведения контрольного списка вещей для аудита. Это поможет вам расставить приоритеты в точках входа, которые будут наиболее выгодными.

Обычно модели угроз создаются в процессе разработки и проектирования продукта. Если компания, производящая конкретный продукт, имеет хороший жизненный цикл разработки, она создает модель угроз на этапе разработки продукта, и постоянно обновляет ее по мере прохождения продукта через жизненный цикл разработки. Модели угроз – это живые документы, которые динамично изменяются по мере изменения цели, а также по тому, как вы постепенно узнаете о ней новые детали, поэтому вам следует часто обновлять модель угроз.

Ваша модель угроз может состоять из разных уровней. Если процесс в вашей модели сложен, вам следует подумать о его дальнейшем разбиении, добавив больше уровней в свои диаграммы. Однако вначале «Уровень 2» – это то, что вам нужно. Мы обсудим различные уровни в следующих разделах, начиная с угрозы уровня 0.

Уровень 0: Вид с высоты птичьего полета

На этом уровне мы используем контрольный список, который мы создали при рассмотрении поверхностей атаки. Подумайте, как данные могут попасть в автомобиль. Нарисуйте авто в центре, затем выделите внешнее и внутреннее пространство. Рисунок 1-1 иллюстрирует возможную диаграмму уровня 0.

Прямоугольники – это входы, а круг в центре – автомобиль. На пути к автомобилю входы пересекают две пунктирные линии, которые обозначают внешние (external) и внутренние (internal) угрозы.

Круг с транспортным средством представляет собой не входные данные, а, скорее, сложный процесс, то есть серию задач, которые можно разбить дальше. Процессы пронумерованы, и, вы видите, этот имеет номер 1.0. Если бы в вашей модели угроз было несколько сложных элементов, вы бы пронумеровали их последовательно. Например, назвали бы второй процесс 2.0, третий – 3.0 и так далее. По мере того, как вы будете изучать особенности своего автомобиля, вы будете обновлять диаграмму. Ничего страшного, если вам непонятны какие-то сокращения или обозначенные на диаграмме, вскоре мы исправим это.

Рисунок 1-1 Входы уровня 0

Уровень 1: Ресиверы

            Чтобы перейти к диаграмме уровня 1, выберите процесс для изучения. Поскольку в нашей диаграмме есть только один процесс, давайте углубимся в устройство автомобиля и сосредоточимся по отдельности на каждом входе.

Карта уровня 1, изображенная на рисунке 1-2, почти идентична карте уровня 0. Единственное отличие состоит в том, что здесь мы указываем соединения транспортных средств, которые получают входы уровня 0. Пока что мы не будем подробно рассматривать ресиверы. Мы смотрим только на основное устройство или область, с которой взаимодействует вход.

Рисунок 1-2 Карта уровня 1 входов и подключений транспортного средства

Обратите внимание на то, что на рисунке 1-2 мы пронумеровали каждый ресивер. Первая цифра обозначает метку процесса из диаграммы уровня 0 на рисунке 1-1, а вторая цифра – номер ресивера. Поскольку информационно-развлекательный блок (Infotainment) это одновременно и сложный процесс, и вход, мы обвели его в круг. Также у нас имеется еще три процесса: иммобилайзер (immobilizer), ЭБУ (ECU) и TPMS ресивер.

Пунктирные линии на карте уровня 1 обозначают разделение границ доверия. Входные данные в верхней части диаграммы являются наименее надежными, входные же данные в нижней части – наиболее надежными. Чем больше границ доверия пересекает канал связи, тем более рискованным становится этот канал.

Уровень 2: Анализ ресивера

На уровне 2 мы исследуем коммуникации, происходящие внутри автомобиля. В нашем примере диаграммы (рис. 1-3) основное внимание уделяется информационно-развлекательной консоли на базе Linux, ресивер 1.1. Это один из наиболее сложных ресиверов, который часто напрямую подключается к внутренней сети автомобиля.

На рисунке 1-3 мы сгруппировали каналы связи в прямоугольники с пунктирными линиями, чтобы еще раз представить границы доверия. Теперь внутри информационно-развлекательной консоли появилась новая граница доверия, называемая пространством ядра (Kernel Space). Системы, которые взаимодействуют напрямую с ядром, представляют больший риск, чем системы, которые взаимодействуют с системными приложениями, поскольку они могут обойти любые механизмы контроля доступа к информационно-развлекательному блоку. Следовательно, сотовый канал (Cellular) представляет собой более высокий риск, чем канал Wi-Fi, поскольку он пересекает границу доверия в пространстве ядра. Канал Wi-Fi, с другой стороны, взаимодействует с процессом WPA Supplicant в пространстве пользователя.

Рисунок 1-3 Карта уровня 2 информационно-развлекательной консоли

Эта система представляет собой автомобильную информационно-развлекательную систему (IVI) на базе Linux, в ней используются части, общие для среды Linux. В пространстве ядра вы видите ссылки на модули udev, HSI и Kvaser, которые получают данные от нашей модели угроз. Модуль udev загружает USB-устройства, HSI – это серийный драйвер, обеспечивающий сотовую связь, а Kvaser – сетевой драйвер авто.

Шаблон нумерации для уровня 2 теперь Х.Х.Х, но система идентификации осталась такая же, как и раньше. На уровне 0 мы взяли процесс автомобиля 1.0 и углубились в него. Затем мы пометили все процессы на уровне 1 как 1.1, 1.2 и так далее. Затем мы выбрали информационно-развлекательный процесс с пометкой 1.1 и разбили его на диаграмму уровня 2. На уровне 2 мы пометили все сложные процессы как 1.1.1, 1.1.2 и так далее. (Вы можете продолжить эту схему нумерации, когда будете еще глубже погружаться в процессы. Схема нумерации предназначена для целей документации, она позволяет вам ссылаться на точный процесс на соответствующем уровне.)

Примечание

В идеале на этом этапе вы должны определить, какие процессы обрабатывают какие входы, но пока нам остается только гадать. В реальной жизни вам потребуется прибегнуть к реверс-инженирингу информационно-развлекательной системы, чтобы найти эту информацию.

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

Идентификация угроз

 Теперь, когда мы углубились в карты моделирования угроз, мы можем приступить к выявлению потенциальных угроз. Выявление угроз часто бывает более увлекательным с группой людей и доской, но вы можете сделать это и самостоятельно в качестве мысленного упражнения.

Давайте вместе попробуем сделать это упражнение. Начните с уровня 0 – с высоты птичьего полета – и рассмотрите потенциальные высокоуровневые проблемы с входами, ресиверами и границами угроз. Теперь давайте перечислим все потенциальные угрозы с нашими моделями угроз.

Уровень 0: Вид с высоты птичьего полета

При определении угроз на уровне 0 старайтесь оставаться на высоком уровне. Некоторые из этих угроз могут показаться вам нереалистичными, поскольку вы осведомлены о дополнительных препятствиях или средствах защиты, но важно включить в этот список все возможные угрозы, даже если некоторые из них уже были устранены. Фишка заключается в том, чтобы провести мозговой шторм и назвать все возможные риски каждого процесса и входа.

На уровне 0 высокоуровневые угрозы заключаются в том, что злоумышленник может:

Сначала может показаться сложным придумать несколько сценариев атаки. Часто хорошо, когда на этом этапе участвуют и люди, не являющиеся инженерами, потому что как разработчик или инженер, вы, как правило, можете естественно дискредитировать некоторые идеи, даже не понимая, что делаете это.

Будьте креативными. Представьте себя Джеймсом Бондом и постарайтесь придумать как можно большее количество атак. Может быть, подумайте о других сценариях атак и о том, применимы ли они к сфере автомобилей? Например, рассмотрим программу-вымогатель – вредоносное программное обеспечение, которое может зашифровать или заблокировать ваш компьютер или телефон, пока вы не заплатите мошенникам деньги. Можно ли использовать это на транспортных средствах? Ответ – да. Запишите программу-вымогатель.

Уровень 1: Ресиверы

Идентификация угроз на уровне 1 больше фокусируется на соединениях каждой части, а не на соединениях, которые могут быть установлены непосредственно на входах. Уязвимости, о которых мы говорим на этом уровне, относятся к уязвимостям, которые влияют на то, что подключается к устройствам в автомобиле.

Мы разделим их на группы угроз, которые относятся к сотовой связи, Wi-Fi, брелокам (KES), датчикам давления шин (TPMS), информационно-развлекательной консоли, USB, Bluetooth и подключений к шине сети контролеров (CAN). Как вы можете видеть из списка, существует множество потенциальных путей попасть в автомобиль.

Сотовая связь (Cellular)

Злоумышленник может использовать сотовую связь в автомобиле, чтобы:

Wi-Fi

Злоумышленник может использовать Wi-Fi соединение для:

Брелок

Злоумышленник может использовать соединение с брелоком для:

Датчики контроля давления шин (TPMS)

Злоумышленник может использовать соединение TPMS для:

Модуль мультимедиа (Infotainment)

Злоумышленник может использовать подключения к экрану мультимедиа для:

USB

Злоумышленник может использовать подключение к USB-порту для:

Bluetooth

Злоумышленник может использовать соединение Bluetooth для:

Сеть контроллеров (CAN)

Злоумышленник может использовать подключение к шине CAN для:

Уровень 2: Анализ ресивера

На уровне 2 мы можем больше поговорить об идентификации конкретных угроз. Когда мы узнаем, какое соединение обрабатывает отдельно взятое приложение, мы можем начать проверку на основе возможных угроз.

Мы разделим угрозы на пять групп: Bluez (Bluetooth угрозы), wpa_supplicant (Wi-Fi угрозы), HSI (модуль сотового ядра с высокоскоростным синхронным интерфейсом), udev (диспетчер устройств ядра) и драйвер Kvaser (драйвер трансивера CAN). В следующих списках я указал угрозы для каждой из групп.

Bluez

Старые или не пропатченные версии уязвимостей Bluetooth:

Wpa_supplicant

HSI

Udev

Драйвер Kvaser

Эти списки потенциальных уязвимостей ни в коем случае не являются исчерпывающими, но, по крайней мере, они должны дать вам представление о том, как работает этот брейншторм. Если вы перейдете к карте потенциальных угроз вашего автомобиля уровня 3, вы бы выбрали один из процессов, например, HSI, и начали бы смотреть его исходный код ядра, чтобы определить чувствительные методы и зависимости, которые могут быть уязвимы для атак.

Системы оценки угроз

Задокументировав множество угроз, теперь мы можем оценить их по уровню риска. Общие рейтинговые системы включают в себя системы DREAD, ASIL и MIL-STD-882E. DREAD обычно используется в веб-тестировании, в то время как автомобильная промышленность и правительство используют ISO 26262 и MIL-STD-882E для оценки угроз. К сожалению, стандарты ASIL ISO 26262 и MIL-STD-882E ориентированы на нарушения безопасности и не подходят для обработки вредоносных угроз. Более подробную информацию об этих стандартах вы можете найти по адресу http://opengarages.org/index.php/Policies_and_Guidelines.

Рейтинговая система DREAD

Аббревиатура DREAD расшифровывается как:

Damage Potential (Возможный ущерб) Насколько велик ущерб?

Reproducibility (Воспроизводимость) Насколько легко воспроизвести?

Exploitability (Возможность эксплуатации) Насколько легко атаковать?

Affected users (Затронутые пользователи) Сколько пользователей пострадало?

Discoverability (Обнаруживаемость) Насколько легко найти уязвимость?

 Категория рейтингаВысокая(3)Средняя(2)Низкая(1)
DDamage Potential
(Возможный ущерб)
Может подорвать систему безопасности
и завоевать полное ее
доверие, в конечном итоге завладеть
системой автомобиля
Возможна утечка конфиденциальной
информации
Возможна утечка банальной
информации
RReproducibility
(Воспроизводимость)
Всегда воспроизводитсяМожет быть воспроизведен только в определенных условиях
или в определенное время
Очень сложно воспроизвести, даже учитывая наличие
информации о конкретной уязвимости
EExploitability
(Возможность эксплуатации)
Позволяет выполнить взлом даже начинающему хакеруПозволяет опытному хакеру создать атаку, которую можно
 использовать повторно
Позволяет выполнить атаку только опытному злоумышленнику
с глубокими знаниями
AAffected users
(Затронутые пользователи)
Влияет на всех пользователей, включая пользователя по умолчанию и основных клиентовВлияет на некоторых пользователей и
определенные настройки
Затрагивает очень небольшой процент пользователей; обычно
влияет на неясную функцию
DDiscoverability
(Обнаруживаемость)
Можно легко найти в опубликованном объяснении атакиВлияет на редко используемую деталь, следовательно,
злоумышленнику необходимо проявить изобретательность,
чтобы обнаружить эксплоит
Маловероятно, что злоумышленники найдут
способ эксплуатирования
Таблица 1-1: Рейтинговая система DREAD

Теперь мы можем применить каждую категорию DREAD из таблицы 1-1 к идентифицированным угрозам, которые мы обсуждали ранее в этой главе, и оценить их по шкале от низкого уровня риска к высокому (1-3). Например, если мы возьмем угрозу HSI уровня 2, описанную в разделе «Уровень 2: Анализ ресивера», мы можем получить рейтинг угрозы, подобный тем, которые изображен в таблице 1-2.

Угрозы HSIDREADИтог
Старая, не пропатченная версия HSI, которая может быть эксплуатирована3323314
HSI которая может быть восприимчива к инъекционной последовательной связи2223312
Таблица 1-2: Угрозы HSI уровня 2 с оценкой DREAD

Вы можете определить общую оценку, используя значения в столбце «Итого» таблицы 1-3.

ИтогоУровень риска
5-7Низкий
8-11Средний
12-15Высокий
Таблица1-3: Таблица оценки рисков DREAD

При оценке рекомендуется оставлять результаты подсчета видимыми, чтобы человек, просматривающий результаты, мог лучше понять риски. В случае HSI, каждой из угроз мы можем присвоить высокий уровень риска, как показано на таблице 1-4.

Угрозы HSIDREADУровень риска
Старая, не пропатченная версия HSI, которая может быть эксплуатирована33233Высокий
HSI которая может быть восприимчива к инъекционной последовательной связи22233Высокий
Таблица 1-4: Угрозы HSI уровня 2 с примененными уровнями риска DREAD

Хотя оба риска отмечены как высокие, мы можем видеть, что более старая версия модели HSI представляет несколько более высокий риск, чем последовательные атаки с использованием инъекции, а потому, устранение этого риска мы можем сделать приоритетным. Мы также можем видеть, что причина, по которой риск инъекционной последовательной связи ниже, заключается в том, что ее ущерб менее серьезен, а эксплойт воспроизвести труднее, чем у старой версии HSI.

CVSS: альтернатива DREAD

Если вы нашли, что DREAD недостаточно подробен для вас, предлагаю рассмотреть более детальную методологию оценивания рисков, известную как общая система оценки уязвимостей – CVSS (Common Vulnerability Scoring System). CVSS предлагает гораздо больше категорий и деталей оценки, нежели DREAD, их можно сгруппировать: базовые, временные и средовые. Каждая из групп подразделяется на подгруппы – шесть в базовых, три во временных и пять в средовых – всего 14 оценочных зон!

Примечание

Хотя при оценке угроз мы могли бы использовать ISO 26262 ASIL или MIL-STD-882E, нам нужны более подробные сведения, чем просто Риск = Вероятность × Серьезность. Если вам пришлось выбирать между этими двумя системами проверки безопасности, используйте MIL-STD-882E от Министерства обороны. Система уровня целостности автомобильной безопасности (ASIL) слишком часто будет иметь риск попадания в рейтинг QM, о которой часто отзываются «meh» (буквально, отсутствие интереса). Система Министерства обороны имеет тенденцию приводить результаты к более высокому рангу, что приравнивается к более высокой стоимости жизненного цикла. Кроме того, MIL-STD-882E предназначен для его применения на протяжении всего жизненного цикла системы, включая удаление, что хорошо сочетается с безопасным жизненным циклом разработки.

Работа с результатами моделей угроз

На данный момент у нас имеется схема множества потенциальных угроз для нашего автомобиля, в которой мы ранжировали их по степени риска. Что теперь? Ну, ответ зависит от того, в какой команде ты работаешь. Используя военный жаргон, атакующая сторона – это «красная команда», а сторона защитников – «синяя команда». Если вы находитесь в красной команде, ваш следующий шаг – начать атаковать области наибольшего риска, которые, вероятно, имеют наибольшие шансы на успех. Если вы в синей команде, вернитесь к своей диаграмме рисков и модифицируйте каждую угрозу с помощью контрмер.

Например, если бы мы взяли на себя два риска из «Рейтинговой системы DREAD», к каждому из них мы могли бы добавить раздел о мерах противодействия. Таблица 1-5 включает меры противодействия риску выполнения кода HSI, а таблица 1-6 включает меры противодействия риску перехвата кода HSI.

УгрозаВыполнение кода в пространстве ядра
РискВысокий
Техника атакиЭксплуатация уязвимости в старых версиях HSI
КонтрмерыЯдро и его модули должны быть обновлены до последних выпусков
Таблица 1-5: Риск выполнения кода HSI
УгрозаПерехват и введение команд из сотовой сети
РискВысокий
Техника атакиПерехват последовательной связи через HSI
КонтрмерыВсе команды, отправляемые по сотовой сети должны иметь криптографическую подпись
Таблица 1-6: Перехват команд HSI

Теперь у вас есть задокументированный список уязвимостей высокого риска с их решениями. Вы можете расставить приоритеты для любых решений, которые в настоящее время не реализованы.

Резюме

 В этой главе вы узнали о важности использования моделей угроз для определения и документирования состояния вашей безопасности, а также о важности привлечения как технических специалистов, так и совсем несведущих людей, для продумывания возможных сценариев. Затем мы углубились в эти сценарии, чтобы выявить все потенциальные риски. Используя систему оценивания, мы ранжировали и классифицировали каждую потенциальную угрозу. После оценки угроз мы получили документ, определяющий нашу текущую позицию безопасности продукта, все существующие виды контрмер и список задач с первоочередными задачами, которые все еще необходимо решить.

2

Протоколы шин

В этой главе мы обсудим различные протоколы шин, используемых в транспортных средствах. В вашем автомобиле может найтись парочка таковых, но если он был выпущен ранее 2000 года, то их может и вовсе не оказаться.

Протоколы шин управляют передачей пакетов через сеть вашего автомобиля. Несколько сетей и сотни датчиков обмениваются данными по этим системам шин, отправляя сообщения, которые контролируют поведение автомобиля и получение его сетью информации в любой момент времени.

Каждый производитель решает лично, какая шина и какие протоколы будут наиболее подходящими для его автомобиля. Один протокол, шина CAN, существует в стандартном месте на всех автомобилях: на разъеме OBD-II. При этом сами пакеты, передаваемые по CAN-шине транспортного средства, не стандартизованы.  

Информация, критически важная для автомобиля, такая как контроль оборотов двигателя и торможения, происходит на линиях высокоскоростных шин, в то время как некритическая информация, такая как управление дверным замком и кондиционером, происходит на линиях средней и низкой скорости.

Мы подробно поговорим о различных шинах и протоколах, с которыми вы можете столкнуться в своем автомобиле. Чтобы определить линии шин для вашего конкретного автомобиля, посмотрите его распиновку OBD-II в интернете.

Шина CAN

CAN – это простой протокол, используемый на производстве и в автомобильной промышленности. Современные автомобили буквально нашпигованы небольшими встроенными системами и электронными блоками управления (ЭБУ), которые могут обмениваться данными с помощью протокола CAN. CAN был стандартом для легковых автомобилей и легких грузовиков в США с 1996 года, но не был обязательным до 2008 года (2001 для европейских автомобилей). Если ваш автомобиль старше 1996 года, он все еще может иметь CAN, вам просто нужно проверить это.

CAN работает по двум проводам: CAN high (CANH) и CAN low (CANL). CAN использует дифференциальную линию связи (за исключением низкоскоростной CAN, обсуждаемой далее, в разделе «Шина GMLAN»), что означает, что при поступлении сигнала CAN повышает напряжение на одной линии и соответственно снижает напряжение на другой (смотрите рисунок 2-1). Дифференциальная линия связи используется в средах, которые должны быть отказоустойчивыми, невосприимчивыми к шуму, например, в автомобильных системах и на производстве.

Рисунок 2-1 Дифференциальная линия связи CAN

На рисунке показан сигнал, полученный с помощью PicoScope, которые прослушивает как CANH (более темные линии в верхней части графика), так и CANL (более светлые линии в нижней части графика). Обратите внимание, что, когда по шине CAN передается бит, сигнал одновременно передает на 1 В выше и ниже. Датчики и ЭБУ имеют трансивер, который проверяет срабатывание обеих сигналов; если это не так, трансивер отклоняет пакет как шум.

Две витые пары образуют шину и требуют оконечной нагрузки на каждом из ее концов. На обоих проводах на концах есть резистор на 120 Ом. Если модуль не находится на конце шины, ему не нужно беспокоиться о завершении. Как человеку, который может подключаться к линиям, вам нужно беспокоиться о завершении только тогда, когда вы снимаете оконечное устройство, чтобы прослушать провода.

Разъем OBD-II

Многие автомобили оснащены разъемом OBD-II, также известным как диагностический разъем (DLC, Diagnostic Link Connector), который взаимодействует с внутренней сетью транспортного средства. Обычно этот разъем располагается под рулевой колонкой или спрятан в другом месте приборной панели в относительно доступном месте. Возможно, вам придется поискать его, типичное расположение разъема OBD-II показано на рисунке 2-2.

Рисунок 2-2 Возможное местоположение разъема OBD-II

В некоторых автомобилях эти разъемы могут быть спрятаны за небольшими панелями. Обычно они либо черные, либо белые. К некоторым получить доступ не составит никакого труда, а некоторые спрятаны под пластиком. Кто ищет – тот найдет!

Поиск соединений CAN

CAN легко найти при поиске кабелей, потому как его напряжение покоя составляет 2,5 В. Когда приходит сигнал, это значение повышается или понижается на 1 В (3,5 В или 1,5 В). Провода CAN проходят через автомобиль и соединяются между ЭБУ и другими датчиками, также они всегда находятся в двухпроводных парах. Если вы возьмете мультиметр и проверите напряжение проводов, то обнаружите, что в состоянии покоя их напряжение будет равно 2,5 В, а при поступлении сигнала колебаться на 1 В. Если вы обнаружите провод, передающий напряжение 2,5 В, это почти наверняка окажется CAN.

Вы должны найти соединения CANH и CANL на контактах 6 и 14 разъема OBD-II, как показано на рисунке 2-3.

Рисунок 2-3 Вид пинов CAN на разъеме OBD-II

Вы обнаружите, что не все шины доступны посредством разъема OBD-II. Чтобы найти дополнительные «внутренние» линии шин вы можете использовать электрические схемы.

Схема пакета CAN-шины

Есть два типа CAN-пакетов: стандартные и расширенные. Расширенные пакеты схожи на стандартные, но с бо́льшим пространством для хранения идентификаторов.

Стандартные пакеты

Каждый пакет CAN-шины содержит четыре ключевых элемента:

Идентификатор арбитража Идентификатор арбитража – это широковещательное сообщение, которое идентифицирует ИД устройства, пытающегося установить связь, хотя любое устройство может отправлять несколько ИД арбитража. Если по шине одновременно отправляются два CAN-пакета, выигрывает тот, у которого ИД арбитража более низкий.

 Расширение идентификатора (IDE) Этот бит всегда равен 0 для стандартной CAN.

Код длины данных (DLC) Это размер данных, который находится в диапазоне от 0 до 8 байт.

Данные Это сами данные. Максимальный размер данных, переносимых стандартным пакетом шины CAN, может составлять до 8 байтов.

На рисунке 2-4 показан формат стандартных пакетов CAN.

Рисунок 2-4 Формат стандартных пакетов CAN

Поскольку пакеты CAN-шины транслируются(broadcast), все контроллеры в одной сети видят каждый пакет, что-то вроде UDP в сетях Ethernet. Пакеты не содержат информации о том, что отправил отдельно взятый контроллер (или злоумышленник). Поскольку любое устройство может видеть и передавать пакеты, оно также может легко имитировать поведение любого другого устройства.

Расширенные пакеты

Расширенные пакеты похожи на стандартные, за исключением того, что их можно объединить в цепочку для создания более длинных идентификаторов. Расширенные пакеты разработаны с учетом стандартного форматирования CAN для обеспечения обратной совместимости. Таким образом, если датчик не поддерживает расширенные пакеты, он не даст сбой, если другой пакет передает расширенные пакеты CAN в этой же сети.

Стандартные пакеты также отличаются от расширенных использованием флагов. При просмотре расширенных пакетов в дампе сети вы удивите, что в отличие от стандартных пакетов, расширенные пакеты используют замещающий удаленный запрос (SRR) вместо запроса удаленной передачи (RTR) с SSR, установленным на 1. Они также будут иметь IDE, установленный на 1, а их пакеты будут иметь 18-битный идентификатор, который является второй частью стандартного 11-битного идентификатора. Существуют дополнительные протоколы на подобии CAN, специфичные для некоторых производителей, они также обратно совместимы со стандартом CAN почти так же, как и расширенный CAN.

Протокол ISO-TP

ISO 15765-2, также известный как ISO-TP, является стандартом для отправки пакетов по шине CAN, который расширяет 8-байтовый предел CAN для поддержки до 4095 байт путем объединения пакетов CAN в цепочку. Чаще всего ISO-TP используется для диагностики и сообщений KWP (альтернативный протокол CAN), но его также можно использовать всякий раз, когда через CAN необходимо передать большие объемы данных. Программа can-utils включает isotptun, проверенный инструмент туннелирования для SocketCAN, который позволяет двум устройствам туннелировать IP через CAN. (Подробное объяснение того, как установить и использовать can-utils смотрите в разделе «Настройка can-utils для подключения к устройствам CAN»).

Чтобы инкапсулировать ISO-TP в CAN используется первый байт для расширенной адресации, оставляя только 7 байт для данных в пакете. Отправка большого количества информации через ISO-TP может легко зафлудить шину, поэтому будьте осторожны при использовании этого стандарта для передачи больших объемов данных на активной шине.

Протокол CANopen

Другой пример расширения протокола CAN – протокол CANopen. CANopen разбивает 11-битный идентификатор на 4-битный код функции и 7-битный идентификатор узла – комбинацию, известную как идентификатор объекта связи (COB-ID). Широковещательное сообщение в этой системе имеет 0х как для кода функции, так и для идентификатора узла. CANopen больше используется в промышленных условиях, нежели в автомобильном строении.

Если вы видите идентификаторы арбитража 0х0, вы нашли отличное доказательство того, что для связи система использует CANopen. CANopen очень похож на обычный CAN, но имеет определенную структуру вокруг идентификаторов арбитража. Например, контрольные сообщения имеют формат 0х700 + идентификатор узла. Реверсировать и документировать сети CANopen даже немного легче, чем стандартную шину CAN.

Шина GMLAN

GMLAN – это реализация CAN-шины от General Motors. Он, как и UDS, основан на ISO 15765-2 ISO-TP. Шина GMLAN состоит из однопроводной низкоскоростной шины и двухпроводной высокоскоростной шины. Низкоскоростная шина, однопроводная шина CAN, которая работает со скоростью 33,33 Кбит/с с максимум 32 узлами, была принята как попытка снизить стоимость проводки. Она используется для передачи такой некритической информации как информационно-развлекательный центр, элементы управления HVAC, дверные замки и т. д. Напротив, высокоскоростная шина работает со скоростью 500 Кбит/с с максимум 16 узлами. Узлы в сети GMLAN связаны с датчиками на этой шине.

Протокол SAE J1850

Протокол SAE J1850 был первоначально принят в 1994 году, и до сих пор встречается в некоторых современных автомобилях, например, некоторых моделях General Motors или Chrysler. Эти шины старше и медленнее, чем CAN, но дешевле в реализации.

Существует два типа протоколов J1850: широтно-импульсная модуляция (PWM) и переменная ширина импульса (VPW). На рисунке 2-5 изображено, где найти контакты PWM на разъеме OBD- II. VPW использует только контакт 2.

Рисунок 2-5 Пины PWM

Скорость подразделяется на три класса: А, В и С. Скорость PWM и VPW – 10,4 Кбит/с – относится к классу А, что означает, что эти устройства продаются исключительно для использования в деловой, промышленной и коммерческой средах. (Шина J1850 VPW со скоростью 10,4 Кбит/с отвечает требованиям автомобильной промышленности по низкому уровню излучения). Устройства класса В продаются для использования во всех без исключениях сферах, и имеют вторую стандартную реализацию SAE, которая может передавать данные со скоростью до 100 Кбит/с, но она, разумеется, и стоит дороже. Окончательная реализация может работать на скорости до 1 Мбит/с и используется в устройствах класса С. Как вы могли догадаться, эта третья реализация является самой дорогой и используется в основном в критически важных системах, работающих в реальном времени и медиа-сетях.

Протокол PWM

PWN использует дифференциальную передачу сигналов на контактах 2 и 10 и в основном используется в автомобилях марки Ford. Он работает с высоким напряжением – 5 В – ,скоростью 41,6 Кбит/с, и использует двухпроводную дифференциальную передачу сигналов, ровно такую же, как и CAN.

PWM имеет сигнал с фиксированным битом, поэтому 1 всегда является высоким сигналом, а 0 – всегда низким. В остальном этот протокол связи идентичен протоколу VPW. Различия заключаются в скорости, напряжении и количестве проводов, используемых для создания шины.

Протокол VPW

VPW, однопроводная шина, использует только контакт 2 и обычно применяется в автомобилях General Motors и Chrysler. VPW имеет высокое напряжение – 7 В, и скорость 10, 4 Кбит/с.

Если сравнивать ее с CAN, имеется несколько ключевых отличий в способе интерпретации данных VPW. Во-первых, поскольку VPW использует зависящее от времени сигнализирование, получение 1 бита определяется не только высоким потенциалом на шине. Чтобы считаться единичным битом – 1 или 0 – он должен оставаться высоким или низким в течение установленного времени. Вытягивание шины в высокое положение приведет к напряжению в 7 В, а отправка низкого сигнала приведет к земному или около земному уровню напряжения. Эта шина, также, в состоянии покоя или отсутствия передачи, остается на около земном уровне (ниже 3 В).

Пакеты VPW используют формат, показанный на рисунке 2-6.

Рисунок 2-6 Формат VPW

Раздел данных имеет установленный размер – всегда 11 бит, за которыми следует 1-битная проверка достоверности CRC. Таблица 2-1 показывает значение заголовочных битов.

Заголовочные битыЗначениеПримечание
PPPПриоритет сообщения000 = Самый высокий, 111 – Самый низкий
HРазмер заголовка0 = 3 байта, 1 = одиночный байт
KОтвет в кадре0 = Необходим, 1 = Не допускается
YРежим адресации0 = Функциональный, 1 = Физический
ZZТип сообщенияБудет варьироваться от того, как установлены K и Y
Таблица 2-1: Значение заголовочных битов

Данные отклика в кадре (IFR) могут следовать сразу после этого сообщения. Обычно сигнал конца данных (EOD), состоящий из низко потенциального сигнала длительностью 200 мкс, возникает сразу после CRC, а если включены данные IFR, он начинается сразу после EOD. Если IFR не используется, длительность EOD будет увеличена до 280 мкс, вызывая сигнал конца кадра (EOF).

Протокол Ключевого слова и ISO 9141-2

Протокол Ключевого слова (Keyword protocol) 2000 (ISO 14230), также известный как KWP2000, использует контакт 7 и широко используется в автомобилях США, выпущенных после 2003 года. Сообщения, отправленные с использованием KWP2000, могут содержать вплоть до 255 байт.

Протокол KWP2000 имеет две вариации, которые отличаются, главным образом, инициализацией скорости передачи данных. Варианты:

ISO 9141-2, или K-Line, является разновидностью KWP2000, наиболее часто встречающейся в европейских автомобилях. K-Line использует контакт 7, и опционально, контакт 15, как показано на рисунке 2-7. K-Line – это протокол универсального асинхронного приемопередатчика (UART), аналогичный последовательному. UART используют стандартные биты и могут включать бит четности и стоп биты. (Если вы когда-либо устанавливали модем, то должны знать эту терминологию).

Рисунок 2-7 Пины  KWP K-Line

На рисунке 2-8 изображена структура пакета протокола. В отличие от пакетов CAN, пакеты K-Line имеют адрес источника (передатчик) и адрес назначения (ресивер). K-Line может использовать аналогичную или похожую структуру запроса идентификатора параметра (PID), что и CAN.

Рисунок 2-8 Компоновка пакета KWP K-Line

Протокол локальной межсетевой связи

Локальная составная сеть (LIN) – самый дешевый из транспортных протоколов. Был разработан как дополнение к CAN. У него нет кода арбитража или приоритета; вместо этого всю передачу выполняет один главный узел.

LIN может поддерживать до 16 подчиненных узлов, которые в основном просто слушают главный узел. Иногда им необходимо отвечать, но это не их главная функция. Главный узел LIN часто подключается к шине CAN.

Максимальная скорость LIN составляет 20 Кбит/с. Также, LIN – это однопроводная шина, работающая от 12 В. Вы не увидите LIN на разъем OBD, но он часто используется вместо прямых пакетов CAN для управления элементами простых устройств, поэтому не забывайте о его существовании.

Кадр сообщения LIN включает заголовок, который всегда отправляется главным узлом, и секцию ответа, которая может управляться им же или ведомым устройством (Смотрите рисунок 2-9).

Рисунок 2-9 Формат LIN

Поле SYNC используется для синхронизации часов. ID представляет содержимое сообщения, то есть тип передаваемых данных. ID может содержать до 64 вариантов. ID 60 и 61 используются для передачи диагностической информации.

При чтении диагностической информации ведущее устройство отправляет идентификатор 60, а ведомое устройство отвечает идентификатором 61. В диагностике используются все 8 байт. Первый байт называется адресом узла для диагностики (NAD). Первая половина диапазона байтов (то есть 1-127) определена для диагностики, совместимой с ISO, а 128-255 могут быть специфичными для конкретного устройства.

  Протокол MOST

Протокол MOST (Media Oriented Systems Transport) разработан для мультимедийных устройств. Обычно MOST имеет кольцевую топологию, или виртуальную звезду, которая поддерживает до 64 устройств MOST. Одно устройство MOST действует как ведущее устройство синхронизации, которое непрерывно передает кадры в кольцо.

MOST работает со скоростью примерно 23 Мбод и поддерживает до 15 несжатых аудиоканалов CD-качества или аудио/видео каналов MPEG1. Отдельный канал управления работает со скоростью 769 Кбод и отправляет сообщения конфигурации на устройства MOST.

MOST имеет три скорости: MOST25, MOST50 и MOST150. Стандарт MOST или MOST25 работает на пластиковом оптоволокне (POF). Передача осуществляется с помощью светодиода с длиной волны красного света 650 нм. Аналогичный протокол, MOST50, удваивает полосу пропускания и увеличивает длину кадра до 1025 бит. Трафик MOST50, вместо оптоволокна, обычно передается по неэкранированной витой паре (UTP). Наконец, MOST150 реализует технологию Ethernet и увеличивает частоту кадров до 3072 бит или 150 Мбит/с, что примерно в шесть раз превышает пропускную способность MOST25.

Каждый кадр MOST имеет три канала:

В дополнение к мастеру синхронизации, мастер сети MOST автоматически назначает устройствам адреса, что позволяет создать своего рода структуру plug-and-play. Еще одна уникальная особенность MOST состоит в том, что, в отличие от других шин, он направляет пакеты через отдельные входящие и исходящие порты.

Сетевые уровни MOST

Если ваша цель – взломать видео- или аудиопоток, протокол MOST может быть вам не так интересен. MOST может предоставить доступ к автомобильному микрофону или сотовой системе, а также к информации о трафике, которая может быть интересна авторам вредоносного ПО.

На рисунке 2-10 показано, как MOST разделен на семь уровней модели Взаимодействия Открытых Систем (OSI), которая стандартизирует обмен данными по сетям. Если вы знакомы с другими сетевыми протоколами на основе мультимедиа, то MOST также может показаться вам знакомым.

Рисунок 2-10 MOST разделен на семь уровней модели OSI. Уровни OSI находятся в левом столбце

Блоки управления MOST

В MOST25 блок состоит из 16 кадров. Фрейм имеет размер 512 бит и выглядит как показано на рисунке 2-11.

Рисунок 2-11 Фрейм MOST25

Синхронные данные содержат от 6 до 15 квадлетов (каждый квадлет составляет 4 байта), а асинхронные данные содержат от 0 до 9 квадлетов. Контрольный кадр составляет 2 байта, но после объединения полного блока или 16 кадров вы получаете 32 байта контрольных данных.

Собранный блок управления расположен, как показано на рисунке 2-12.

Рисунок 2-12 Схема блока управления в блоке

Область данных содержит FblockID, InstID, FktID, Op Type, Tel ID, Tel Len и 12 байт данных. Например, FblockID 0х52 может быть навигационной системой. InstID – это пример функционального блока. Здесь может быть несколько основных функций, например, две смены CD дисков. InstID различает, с каким ядром он взаимодействует. FktID используется для запроса функциональных блоков более высокого уровня. Например, FktID 0х0 запрашивает список идентификаторов функций, поддерживаемых функциональным блоком. OP Type – это тип операции, которую нужно выполнить: получить, установить, увеличить, уменьшить и т. д. Tel ID и Len – это тип и длина телеграммы соответственно. Типы телеграмм подразумевают одиночную или многопакетную передачу и длину самой телеграммы.

MOST50 имеет структуру, аналогичную MOST25, но с бо́льшим разделом данных. MOST150 предоставляет два дополнительных канала: Ethernet и изохронный. Ethernet работает как обычные конфигурации TCP/IP или Appletalk. Изохронный имеет три механизма: пакетный режим, постоянная скорость и потоковая передача пакетов.

Взлом MOST

MOST можно взломать с устройства, которое уже поддерживает его, например, через информационно-развлекательный блок автомобиля или через встроенный контроллер MOST. Основанный на Linux проект most4linux предоставляет драйвер ядра для MOST PCI-устройств и на момент написания этой книги поддерживает Siemens CT SE 2 и OASIS Silicon Systems или карты SMSC PCI. Драйвер most4linux обеспечивает взаимодействие в пространстве пользователя через сеть MOST и подключается к структуре Advanced Linux Sound Architecture (ALSA) для чтения и записи аудиоданных. На данный момент most4linux следует рассматривать как приложение, находящееся на стадии альфа-тестирования, но оно уже включает в себя несколько утилит, которые вы можете использовать, а именно:

Текущий драйвер most4linux был написан для ядер Linux 2.6, так что, возможно, вам не придется работать, если вы захотите создать общий сниффер. MOST довольно дорог в реализации, поэтому общий сниффер не будет дешевым.

Шина FlexRay

FlexRay – это высокоскоростная шина, которая может передавать данные со скоростью до 10 Мбит/с. Она предназначена для чувствительной ко времени связи, такой как руление, торможение и т. д. FlexRay дороже чем CAN, поэтому в большинстве случаев FlexRay используется для высокопроизводительных систем, CAN – для среднего уровня и LIN – для недорогих решений.

Аппаратные средства

FlexRay использует витую пару, но также может поддерживать двухканальную структуру, что может повысить отказоустойчивость и пропускную способность. Однако, в большинстве реализаций FlexRay используется только одна пара проводов, аналогично реализациям шины CAN.

Топология сети

FlexRay поддерживает стандартную топологию шины, такую как шина CAN, где многие ЭБУ работают с шиной по витой паре. Он также поддерживает топологию звезды, такую как Ethernet, которая может работать с более длинными сегментами. При реализации в звездообразной топологии концентратор FlexRay представляет собой активное устройство FlexRay, которое взаимодействует с другими узлами. В схеме шины FlexRay требует правильного согласования резистора, как и в стандартной шине CAN. При желании звездообразную топологию и топологию шины можно комбинировать для создания гибридной схемы. 

Реализация

При создании сети FlexRay производитель должен произвести стандартную настройку сети. Напомним, что в сети CAN каждому устройству просто нужно знать скорость передачи и идентификаторы, которые ему нужны (если таковые имеются). В схеме шины одновременно может взаимодействовать только одно устройство. В случае шины CAN порядок, кто первый сообщает о конфликте, определяется идентификатором арбитража.

Напротив, когда FlexRay настроен для передачи данных по шине, он использует так называемую схему множественного доступа с временным разделением (TDMA), чтобы гарантировать детерминизм: скорость всегда одна и та же (детерминированная), и для заполнения данных по мере того, как пакеты проходят по проводу, подобно тому, как работают сотовые сети, такие как GSM, система полагается на передатчики. Устройства FlexRay не обнаруживают сеть или адреса автоматически, поэтому эта функция должна быть запрограммирована в них во время производства.

Хотя этот подход со статической адресацией снижает затраты во время производства, для тестируемого устройства использование шины может быть затруднительным, поскольку оно не знает конфигурации сети, и устройство, добавленное в вашу сеть FlexRay, соответственно, не будет знать для каких слотов предназначены определенные данные. Для решения этой проблемы во время разработки FlexRay были разработаны специальные форматы обмена данными, такие как формат обмена для полевой шины (FIBEX).

FIBEX – это формат XML, используемый для описания FlexRay, а также сетевых настроек CAN, LIN и MOST. Карты топологии FIBEX записывают ЭБУ и то, как они подключены через каналы, и могут реализовывать шлюзы для определения маршрутизации между шинами. Эти карты также могут включать все сигналы и то, как они могут интерпретироваться.

Данные FIBEX используются во время компиляции прошивки и позволяют разработчикам ссылаться на известные сетевые сигналы в своем коде; компилятор обрабатывает размещение и конфигурацию. Чтобы посмотреть FIBEX, загрузите FIBEX Explorer с http://sourceforge.net/projects/fibexplorer/.

Циклы FlexRay

Цикл FlexRay можно рассматривать как пакет.  Продолжительность каждого цикла определяется во время проектирования и должна состоять из четырех частей, как показано на рисунке 2-13.

Рисунок 2-13 Четыре части цикла FlexRay

Статический сегмент (Static) содержит зарезервированные слоты для данных, которые всегда имеют одно и то же значение. Слоты динамического сегмента (Dynamic) содержат данные, которые могут иметь разные представления. Окно символа (Symbol Window) используется сетью для сигнализации, а сегмент ожидания (Idle), он же тихий режим, используется для синхронизации.

Наименьшая единица времени в FlexRay называется микротиком, который обычно равен одной миллисекунде. Все узлы синхронизированы по времени, и запускают свои микротики данных одновременно.

Динамическая секция разделяется на мини-интервалы, обычно, длиной в один микротик. Динамический сегмент обычно используется для менее важных, прерывистых данных, таких как внутренняя температура воздуха. По мере прохождения минислотов, ЭБУ может выбирать их заполнение данными. Если все минислоты заполнены, ЭБУ должен дожидаться следующего цикла.

На рисунке 2-14 циклы FlexRay представлены в виде вагонов поезда. Передатчики, отвечающие за заполнение информации для статических слотов, делают это по прошествии цикла, динамические слоты, в свое время, заполняются в порядке очереди. Все вагоны поезда имеют одинаковый размер и отражают детерминированные во времени свойства FlexRay.

Рисунок 2-14 Поезд, представляющий циклы FlexRay

Окно символов обычно не используется напрямую большинством устройств FlexRay, а это означает, что, если вы думаете как хакер, вам определенно стоит повозиться с этой секцией. Кластеры FlexRay работают в состояниях, которые контролируются менеджером состояний FlexRay. Согласно стандарту AUTOSAR 4.2.1 это следующие состояния: готовность, пробуждение, запуск, запрос остановки, онлайн, онлайн-пассивный, слот только для ключей и Low-number-of-coldstarters.

Хотя большинство состояний очевидны, некоторые все же нуждаются в дополнительных пояснениях. В частности, онлайн – это нормальное состояние связи, в то время как онлайн-пассивное состояние должно вызываться только в случае ошибок синхронизации. В пассивном онлайн режиме данные как не отправляются, так и не принимаются. Только для ключей означает, что данные могут передаваться только в ключевых слотах. Low-number-of-coldstarters означает, что шина работает в полном режиме связи, но полагается только на кадры синхронизации. Также существуют дополнительные рабочие состояния, такие как конфигурация, спящий режим, только получение и режим ожидания.

Макет пакета

Фактический пакет, который использует FlexRay, содержит несколько полей и вписывается в цикл в статическом или динамическом слоте (Смотрите рисунок 2-15).

Рисунок 2-15 Макет пакета FlexRay

Биты состояния:

Индикатор кадра (Frame ID) – это слот, в котором должен быть передан пакет при использовании в статических слотах. Когда пакет предназначен для динамического слота (1-2047), идентификатор кадра представляет приоритет этого пакета. Если два пакета имеют одинаковый сигнал, то выигрывает пакет с высшим приоритетом. Длина полезной нагрузки (Payload Length) – это число в словах (2 байта), длина которого может достигать до 127 слов, что означает, что пакет FlexRay может нести 254 байта данных – более чем в 30 раз больше, нежели пакет CAN. Заголовок CRC (Header CRC) должен быть очевидным, а счетчик циклов (Cycle Count) используется как счетчик связи, который увеличивается каждый раз при запуске цикла связи.

Одна действительно полезная вещь в статических слотах заключается в том, что ЭБУ может считывать более ранние статические слоты и выводить значение на основе этих входов в том же цикле. Например, предположим, что у вас есть компонент, которому необходимо знать положение каждого колеса, прежде чем он сможет выводить какие-либо конкретные регулировки. Если первые четыре слота в статическом слоте содержат положение каждого колеса, то ЭБУ калибровки может считать их и все еще успевает заполнить следующий слот любой регулировкой.

Сниффинг сети FlexRay

На момент написания этой книги Linux не имеет официальной поддержки FlexRay, но есть некоторые патчи от различных производителей, которые добавляют его поддержку для определенных ядер и архитектур (В Linux есть поддержка FlexCAN, FlexCAN – это сеть CAN-шины, вдохновленная FlexRay).

В настоящее время стандартных инструментов с открытым исходным кодом для сниффинга FlexRay нет. Если вам нужен универсальный инструмент для прослушивания трафика FlexRay, в настоящее время вам придется использовать какой-либо проприетарный продукт, который, к слову, будет стоить немалых денег. Если вы захотите мониторить сеть FlexRay без файла FIBEX, вам, по крайней мере, нужно будет знать скорость передачи данных шины. В идеале вы также должны знать длину цикла (в миллисекундах) и, если возможно, размер разделения кластера (соотношение статического до динамического). Технически кластер FlexRay может иметь до 1048 конфигураций с 74 параметрами. Подход к определению этих параметров подробно описан в статье Эрика Арменгауда, Андреаса Штайнингера и Мартина Хорауэра «Automatic Parameter Identification in FlexRay based Automotive Communication Networks» (IEEE, 2006).

При спуфинге пакетов в сети FlexRay с двумя каналами необходимо одновременно спуфить оба канала. Кроме того, вы встретите реализации FlexRay, называемые Bus Guardian, которые предназначены для предотвращения флудинга или монополизации шины любым одним устройством. Bus Guardian работает на аппаратном уровне через контакт на микросхеме FlexRay, обычно называемый Bus Guardian Enable (BGE). Этот пин часто отмечается как необязательный, но Bus Guardian может установить его слишком высоко, чтобы отключить нежелательное устройство.

Автомобильный Ethernet

Поскольку MOST и FlexRay дорогие и теряют свою поддержку (консорциум FlexRay, похоже, распался), большинство новых транспортных средств переходит на Ethernet. Реализации Ethernet варьируются, но в основном, не сильно отличаются от стандартной компьютерной сети. Часто пакеты CAN инкапсулируются как UDP, а звук передается как голос по IP (VoIP). Ethernet может передавать данные со скоростью до 10 Гбит/с, используя непатентованные протоколы и любую выбранную топологию.

Хотя общего стандарта для трафика CAN нет, производители все чаще начинают использовать стандарт IEEE 802.1 AS Audio Video Bridging (AVB). Этот стандарт поддерживает качество обслуживания (QoS) и формирование трафика, а также использует синхронизированные по времени пакеты UDP. Для достижения этой синхронизации узлы следуют алгоритму ведущих часов (best master clock), чтобы определить, какой узел должен быть ведущим устройством синхронизации. Главный узел обычно синхронизируется с внешним источником синхронизации, таким как GPS или (в худшем случае) встроенным генератором. Главный узел синхронизируется с другими узлами, отправляя синхронизированные пакеты (10 миллисекунд), подчиненное устройство отвечает запросом задержки, и смещение времени вычисляется на основе этого обмена.

С точки зрения исследователя, единственная проблема с автомобильным Ethernet заключается в том, чтобы выяснить, как с ним можно взаимодействовать. Возможно, вам придется изготовить или купить специальный кабель для взаимодействия с автомобильными кабелями Ethernet, потому что они не выглядят как стандартные кабели с витой парой, которые вы можете увидеть в сетевом шкафу. Как правило, разъем представляет собой просто провод, подобный тем, которые вы видите при подключении ЭБУ. Не ожидайте, что у коннекторов будет собственный разъем, а если он и будет, то он не будет похож на RJ-45. Некоторые открытые коннекторы могут быть круглыми, как показано на рисунке 2-16.

Рисунок 2-16 Круглые коннекторы Ethernet

Схема расположения выводов разъема OBD-II

Остальные контакты в распиновке OBD-II зависят от производителя. Их расположение различается, поэтому это всего лишь рекомендации. Распиновка может отличаться в зависимости от марки и модели автомобиля. К примеру, на рисунке 2-17 показана распиновка General Motors.

Рисунок 2-17 Изображение полной распиновки OBD для автомобиля General Motors

Обратите внимание, что разъем OBD может иметь более одной линии CAN, например, еще могут быть низкоскоростные (LS-CAN) или среднескоростные (MS-CAN) линии. Низкоскоростные работают со скоростью около 33 Кбит/с, среднескоростные – около 128 Кбит/с, а высокоскоростные (HS-CAN) – около 500 Кбит/с.

При подключении вашего сниффера к автомобилю вы часто будете использовать разъем DB9-to-OBDII. На рисунке 2-18 показан вид штекера.

Рисунок 2-18 Типичный вид штекера разъема DB9. Звездочка (*) означает, что пин необязателен. Адаптер DB9 может иметь всего три контакта

Эта распиновка является распространенной в Соединенном Королевстве, и, если вы делаете кабель самостоятельно, она будет самой простой в изготовлении. Однако некоторые снифферы, такие как многие щиты Arduino, ожидают разъем DB9 американского типа (Смотрите рисунок 2-19).

Рисунок 2-19 Американский коннектор DB9

Версия для США имеет больше функций и дает вам больше доступа к другим разъемам OBD, помимо CAN. К счастью, на обоих разъемах есть 9-ый контакт, так что не вы не сожжете ваш сниффер, если случайно схватите не тот кабель. У некоторых снифферов, таких как CANtact, есть перемычки, которые можно установить в зависимости от того, какой кабель вы используете – британский или американский.

 Стандарт OBD-III

OBD-III – довольно противоречивая эволюция стандарта OBD-II. Изначально OBD-II был разработан с учетом требований к испытаниям на выбросы (по крайней мере, с точки зрения регулирующих органов), но теперь, когда модуль управления трансмиссией (PCM) определяет, соответствует ли автомобиль установленным нормам, мы по-прежнему сталкиваемся с неудобствами, когда владелец транспортного средства должен проходить инспекцию авто каждые два года. Стандарт OBD-III позволяет PCM сообщать свой статус удаленно, без вмешательства владельца. Эта связь обычно осуществляется посредством придорожного транспондера, но также может работать через сотовую и спутниковую связи.

Совет по воздушным ресурсам Калифорнии (CARB) начал тестирование придорожных считывающих устройств для OBD-III в 1994 году на способность считывать данные о транспортных средствах с восьми полос движения, движущихся со скоростью 160 км/ч. Если в авто обнаруживается неисправность, она передает диагностические коды неисправностей (DTC) и идентификационные номера автомобилей (VIN) на ближайший транспондер. Идея состояла в создании системы, сообщающей количество загрязняющих веществ, попадающих в атмосферу, без необходимости ждать до двух лет для проверки уровня выбросов.

Большинство реализаций OBD-III напрямую зависят от производителя. Автомобиль сообщит производителю о неисправностях, а затем свяжется с владельцем, чтобы сообщить ему о необходимости ремонта. Как вы можете догадаться, у этой системы есть некоторые очевидные юридические вопросы, на которые еще предстоит ответить, включая риск массового наблюдения за частной собственностью. Безусловно, со стороны правоохранительных органов есть много возможностей для злоупотреблений, в том числе скоростных ловушек, отслеживания, иммобилизации и т. д.

Некоторые представленные запросы предложений по интеграции OBD-III в транспортные средства утверждают, что используют транспондеры для хранения следующей информации:

Важно отметить, что даже если OBD-III отправляет только DTC и VIN, добавить дополнительные метаданные, такие как местоположение, время и историю транспортного средства, проезжающего транспондер, несложно. По большей части OBD-III – это монстр под кроватью. На момент написания этой книги применение транспондера развернуто еще не было, хотя системы домашнего телефона, такие как OnStar, развертываются для уведомления автосалона о различных проблемах безопасности.

Резюме

При работе с целевым автомобилем вы можете столкнуться с множеством различных шин и протоколов. Когда вы выясните какие именно используются в вашем авто, изучите контакты, используя ваш OBD-II, чтобы определить, какие инструменты вам понадобятся и чего ожидать при реверсировании сети вашего автомобиля.

В этой главе я сосредоточился на легкодоступных шинах через разъем OBD-II, но вам также стоит взглянуть на электрические схемы вашего автомобиля, чтобы найти другие линии шин. Не все линии шин доступны через разъем OBD-II, и при поиске определенного пакета может быть проще найти модуль и линии шины, выходящие из конкретного модуля, нежели реверсить определенный пакет.

3

Взаимодействие автомобиля и socketcan

Когда для коммуникаций автомобиля вы начнете использовать CAN, скорее всего, вы быстро обнаружите, что это смесь различных драйверов и программных утилит. Идеальным было бы объединить инструменты CAN и их различные интерфейсы в один общий интерфейс, чтобы мы могли легко обмениваться информацией между инструментами.

К счастью, такой набор тулзов с общим интерфейсом уже есть, и он бесплатен! Если у вас есть Linux, как основная операционная система, или же на виртуальной машине, у вас уже есть этот набор. Он называется SocketCAN и был создан на сайте разработки с открытым исходным кодом BerliOS в 2006 году. Сегодня термин SocketCAN используется для обозначения реализации драйверов CAN в качестве сетевых устройств, таких как карты Ethernet, а также для описания доступа приложений к шине CAN через интерфейс программирования сетевых сокетов. В этой главе мы научимся настраивать SocketCAN для упрощения взаимодействия с автомобилем.

Исследовательская группа Volkswagen предоставила оригинальную реализацию SocketCAN, которая поддерживает встроенные микросхемы CAN и драйверы карт, внешние USB, а также последовательные и виртуальные устройства CAN. Пакет утилит CAN предоставляет несколько приложений и инструментов для взаимодействия с сетевыми устройствами CAN, протоколами, специфичными для CAN, и возможностью настройки виртуальной среды CAN. Чтобы протестировать примеры из этой книги, рекомендую установить последнюю версию Linux на виртуальную машину. В стандартных репозиториях последних версий Ubuntu утилиты CAN предустановлены.

SocketCAN связан с сетевым стеком Linux, что позволяет очень легко создавать инструменты для поддержки CAN. Приложения SocketCAN могут использовать стандартные вызовы сокетов C с настраиваемым семейством сетевых протоколов PF_CAN.

На рисунке 3-1 сравнивается реализация традиционного программного обеспечения CAN с реализацией унифицированного SocketCAN.

Рисунок 3-1 Схема SocketCAN (слева) и традиционная реализация ПО SocketCAN (справа)

В традиционной реализации программного обеспечения SocketCAN, приложение имеет собственный протокол, который обычно обращается к символьному устройству, например, к последовательному драйверу, а затем к фактическому драйверу оборудования. Слева на рисунке SocketCAN реализован на ядре Linux. Создав собственное семейство протоколов CAN, SocketCAN может интегрироваться с существующими драйверами сетевых устройств, что позволяет приложениям обрабатывать интерфейс шины CAN как общий сетевой интерфейс.  

Настройка can-utils для подключения к устройствам CAN

Для установки can-utils вы должны использовать дистрибутив Linux от 2008 года или новее, или дистрибутив Linux с ядром версии 2.5.25 или выше. Сначала мы установим can-utils, а затем расскажем, как настроить его для вашей конкретной цели.

Установка can-utils

Для установки can-utils вы должны иметь возможность использовать свой менеджер пакетов. Вот пример Debian/Ubuntu:

sudo apt-get install can-utils

Если в вашем менеджере пакетов нет can-utils, установите его из источника с помощью команды git:

git clone https://github.com/linux-can/can-utils

На момент написания книги в can-utils есть файлы configure, make и make install, но в более старых версиях вам необходимо ввести просто make для установки из источника.

Настройка встроенных чипсетов

Следующий шаг будет зависеть от вашего оборудования. Если вы ищете сниффер CAN, вам следует проверить список поддерживаемых драйверов Linux, чтобы убедиться, что ваше устройство совместимо. На момент написания этой книги, встроенные в Linux драйверы поддерживают следующие чипсеты:

Контроллеры CAN, такие как SJA1000, обычно встроены в карты ISA, PCI и PCMCIA или другое встроенное оборудование. Например, драйвер карты EMS PCMCIA реализует доступ к своему чипу SJA1000. Когда вы вставляете карту EMS PCMCIA в ноутбук, ms_pcmcia загружается в ядро, которое затем требует загрузки модуля sja1000 и модуля can_dev. Модуль can_dev предоставляет стандартные интерфейсы конфигурации – например, для установки скорости передачи данных для контроллеров CAN.

Модульная концепция ядра Linux также применима к драйверам оборудования CAN, которые подключают контроллеры CAN через аппаратную шину, например, kvaser_pci, peak_pci и т. д. Когда вы подключаете поддерживаемое устройство, эти модули должны автоматически загружаться, вы можете увидеть их, введя команду lsmod. Драйверы USB, такие как usb8dev, обычно реализуют собственный протокол связи USB, и, следовательно, не загружают драйвер контроллера CAN.

Например, когда вы подключаете адаптер PEAK-System PCAN-USB, модуль can_dev загружается, а модуль peak_usb завершает его инициализацию. Используя команду отображения сообщений dmesg, вы должны увидеть следующий результат:

dmesg
–snip —
[ 8603.743057] CAN device driver interface
[ 8603.748745] peak_usb 3-2:1.0: PEAK-System PCAN-USB adapter hwrev 28 serial
    FFFFFFFF (1 channel)
[ 8603.749554] peak_usb 3-2:1.0 can0: attached to PCAN-USB channel 0 (device
    255)
[ 8603.749664] usbcore: registered new interface driver peak_usb

Вы можете проверить, правильно ли загружен интерфейс и с помощью ifconfig убедиться, что интерфейс can0 теперь присутствует:

ifconfig can0
can0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          UP RUNNING NOARP  MTU:16  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Теперь установите скорость CAN-шины. (Более подробную информацию о скорости шины вы найдете в главе 5). Ключевой компонент, который вам нужно установить – это битрейт. Это и есть скорость шины. Типичное значение скорости для высокоскоростной CAN (HS-CAN) составляет 500 Кбит/с. Значения 250 Кбит/с или 125 Кбит/с типичны для низкоскоростных CAN-шин.

sudo ip link set can0 type can bitrate 500000
sudo ip link set up can0

После запуска устройства can0, вы сможете использовать инструменты can-utils из его интерфейса. Для связи между ядром и инструментами пользовательского пространства Linux использует netlink. Вы можете получить доступ к netlink с помощью команды ip link. Чтобы просмотреть все параметры netlink, введите следующее:

ip link set can0 type can help

Если вы начнете замечать странное поведение, такое как отсутствие захвата пакетов, или их ошибки, возможно, интерфейс был остановлен. Если вы работаете с внешним устройством, просто переподключите его или выполните сброс. Если устройство внутреннее, для его сброса выполните следующие команды:

sudo ip link set canX type can restart-ms 100
sudo ip link set canX type can restart

Настройка последовательных устройств CAN

Внешние устройства CAN обычно обмениваются данными через последовательный порт. Фактически, даже USB-устройства в автомобиле часто обмениваются данными через последовательный интерфейс – обычно им выступает микросхема FTDI от Future Technology Devices International, Ltd.

Известно, что с SocketCAN работают следующие устройства:

Примечание

Если вы используете Arduino или создаете собственный сниффер, чтобы ваше устройство заработало, в своей прошивке вы должны реализовать протокол LAWICEL, также известный как протокол SLCAN. Подробнее смотрите http://www.can232.com/docs/canusb_manual.pdf и https://github.com/linux-can/can-misc/blob/master/docs/SLCAN-API.pdf.

Чтобы использовать один из адаптеров USB-to-serial, сначала вы должны инициализировать как последовательное оборудование, так и скорость передачи данных на шине CAN:

slcand -o -s6 -t hw -S 3000000 /dev/ttyUSB0
ip link set up slcan0

Slcand предоставляет интерфейс, необходимый для преобразования последовательной связи для сетевого драйвера, slcan0. В slcand можно передать следующие параметры:

В таблице 3-1 перечислены числа, переданные в –s, и соответствующие скорости передачи данных.

ЧислоСкорость
010 Кбит/с
120 Кбит/с
250 Кбит/с
3100 Кбит/с
4125 Кбит/с
5250 Кбит/с
6500 Кбит/с
7800 Кбит/с
81000 Кбит/с
Таблица 3-1: Числа и соответствующий битрейт

Как видите, ввод -s6 подготавливает устройство к взаимодействию с сетью CAN-шины 500 Кбит/с.

После установки этих параметров у вас должно появится устройство slcan0. Для подтверждения введите следующее:

ifconfig slcan0
slcan0    Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          NOARP  MTU:16  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Большая часть информации, возвращаемой ifconfig, имеет общие значения по умолчанию, они могут быть нулями. Это нормально. Мы просто убеждаемся, что можем видеть устройство с помощью ifconfig. Если мы видим устройство slcan0, то можем быть уверены в том, что сможем использовать наши инструменты для последовательной связи с контроллером CAN.

Примечание

На этом этапе будет полезно проверить, есть ли на вашем физическом сниффере дополнительные лампочки-индикаторы. Зачастую у сниффера CAN есть зеленый и красный индикаторы, которые обозначают, что он правильно взаимодействует с шиной CAN

Настройка виртуальной сети CAN

Если у вас нет оборудования CAN, с которым можно было бы поиграться, не бойтесь. Для тестирования вы можете настроить виртуальную сеть CAN. Для этого просто загрузите модуль vcan.

modprobe vcan

Проверив dmesg, вы не должны видеть ничего, кроме такого сообщения:

dmesg
[604882.283392] vcan: Virtual CAN interface driver

Теперь вам нужно просто настроить интерфейс, как описано в разделе «Настройка встроенных чипсетов», но без указания скорости передачи для виртуального интерфейса.

ip link add dev vcan0 type vcan
ip link set up vcan0

Чтобы убедиться в корректности проделанных действий, введите следующее:

ifconfig vcan0
vcan0     Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          UP RUNNING NOARP  MTU:16  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Если на выходе вы видите vcan0, вы готовы к работе.

Пакет утилит CAN

После того, как наше CAN-устройство запущено и работает, давайте подробно рассмотрим can-utils. Здесь они перечислены и кратко описаны; мы будем использовать их на протяжении всей книги, и по мере ее прочтения, вы будете все глубже вдаваться в детали их использования.

asc2log Этот инструмент анализирует дампы ASCII CAN в следующей форме в стандартный формат логфайла SocketCAN:

0.002367 1 390x Rx d 8 17 00 14 00 C0 00 08 00

bcmserver Сервер управления проверки концепции (PoC) Яна-Никласа Мейера принимает следующие команды:

vcan1 A 1 0 123 8 11 22 33 44 55 66 77 88

            По умолчанию, он прослушивает порт 28600. Его можно использовать для выполнения рутинной работы, когда вы имеете дело с повторяющимися сообщениями CAN.

сanbusload Этот инструмент определяет, какой идентификатор является ответственным за передачу наибольшего трафика на шину и принимает следующие параметры:

interface@bitrate

Вы можете указать столько интерфейсов, сколько захотите, и настроить canbusload на отображение гистограммы с показателями наихудших пропускных скоростей.

can-calc-bit-timing Эта команда вычисляет скорость передачи данных и соответствующие значения регистров для каждого набора микросхем CAN, поддерживаемого ядром.

candump Эта утилита выгружает CAN-пакеты. Он также может принимать фильтры и пакеты логов.

canfdtest Этот инструмент выполняет тестовые отправки и получения по двум шинам CAN.

cangen Эта команда генерирует пакеты CAN и может передавать их в заданных интервалах. Она также может генерировать случайные пакеты.

cangw   Этот инструмент управляет шлюзами между различными шинами CAN, а также может фильтровать и изменять пакеты перед их отправлением на следующую шину.

canlogserver Эта утилита прослушивает порт 28700 (по умолчанию) на предмет CAN-пакетов и записывает их в стандартном формате в stdout.

canplayer Эта команда воспроизводит пакеты, сохраненные в стандартном «компактном» формате SocketCAN.

cansend Этот инструмент отправляет в сеть один CAN-кадр.

cansniffer Этот интерактивный сниффер группирует пакеты по идентификатору и выделяет измененные байты.

isotpdump Этот инструмент выгружает пакеты CAN ISO-TP, которые описаны в разделе «Отправка данных с помощью ISO-TP и CAN».

isotprecv Эта утилита принимает пакеты CAN ISO-TP и выводит их в stdout.

isotpsend Эта команда отправляет CAN-пакеты ISO-TP, поступающие из stdin.

isotpserver Этот инструмент реализует мост TCP / IP для ISO-TP и принимает пакеты данных в формате 1122334455667788

isotpsniffer Этот интерактивный сниффер схож с cansniffer, но предназначен для пакетов ISO-TP.

isotptun Эта утилита создает сетевой туннель по сети CAN.

log2asc Этот инструмент преобразовывает стандартный компактный формат в следующий формат ASCII:

0.002367 1 390x Rx d 8 17 00 14 00 C0 00 08 00

log2long Эта команда преобразует стандартный компактный формат в формат, читабельный для пользователя.

slcan_attach Это инструмент командной строки для устройств CAN с последовательной линией.

slcand Эта команда обрабатывает устройства CAN с последовательной линией.

slcanpty Этот инструмент создает псевдотерминальный интерфейс Linux (PTY) для связи с последовательным интерфейсом CAN.

Установка дополнительных модулей ядра

Некоторые из более продвинутых и экспериментальных команд, например, на основе ISO-TP, перед тем, как их можно будет использовать, требуют, чтобы вы установили дополнительные модули ядра, такие как can-isotp. На момент написания книги эти дополнительные модули не были включены в стандартные ядра Linux, и вам, вероятно, придется компилировать их отдельно. Загрузить дополнительные ядра CAN вы можете следующим образом:

git clone https://gitorious.org/linux-can/can-modules.git
cd can-modules/net/can
sudo ./make_isotp.sh

После завершения make должен быть создан файл can-isotp.ko.

Если вы запустите make в корневой папке репозитория, он попытается скомпилировать некоторые несинхронизированные модули, поэтому лучше скомпилировать необходимый модуль в текущем каталоге. Чтобы загрузить недавно скомпилированный модуль can-isotp.ko, запустите insmod:

sudo insmod ./can-isotp.ko

dmesg должен показать, что он загружен правильно:

dmesg
[830053.381705] can: isotp protocol (rev 20141116 alpha)

Примечание

Как только драйвер ISO-TP окажется стабильным, его следует переместить в стабильную ветвь ядра Linux. В зависимости от того, когда вы читаете это, он, возможно, уже мог быть перемещен, поэтому перед компиляцией собственного драйвера обязательно проверьте, не установлен ли он. 

Модуль can-isotp.ko

Модуль can-isotp.ko – это реализация протокола CAN на сетевом уровне Linux, который требует от системы загрузки основного модуля can.ko Модуль can.ko предоставляет инфраструктуру сетевого уровня для всех реализаций протокола CAN в ядре, таких как can_raw.ko, can_bcm.ko, и can-gw.ko. Если все работает правильно, в ответ на следующую команду вы должны увидеть такой вывод:

sudo insmod ./can-isotp.ko
[830053.374734] can: controller area network core (rev 20120528 abi 9)
[830053.374746] NET: Registered protocol family 29
[830053.376897] can: netlink gateway (rev 20130117) max_hops=1

Если can.ko не будет загружен, вы получите следующее:

sudo insmod ./can-isotp.ko
insmod: ERROR: could not insert module ./can-isotp.ko: Unknown symbol in
module

Если вы забыли подключить устройство CAN или загрузить модуль ядра CAN, вы увидите это странное сообщение об ошибке. Если для получения дополнительной информации вы введете dmesg, вы увидите серию пропущенных символов, на которые есть ссылки в сообщении об ошибках.

dmesg
[830760.460054] can_isotp: Unknown symbol can_rx_unregister (err 0)
[830760.460134] can_isotp: Unknown symbol can_proto_register (err 0)
[830760.460186] can_isotp: Unknown symbol can_send (err 0)
[830760.460220] can_isotp: Unknown symbol can_ioctl (err 0)
[830760.460311] can_isotp: Unknown symbol can_proto_unregister (err 0)
[830760.460345] can_isotp: Unknown symbol can_rx_register (err 0)

Вывод dmesg показывает множество сообщений Unknown symbol (о неизвестных символах), особенно в методах can_x. (Игнорируйте сообщения (err 0)). Эти сообщения говорят нам, что модуль _isotop не может найти методы, связанные со стандартными функциями CAN. Эти сообщения указывают на то, что вам необходимо загрузить модуль can.ko. После его загрузки все должно заработать.

Программирование приложений SocketCAN

Несмотря на то, что can-utils очень надежен, скорее всего, вскоре вы захотите написать собственные инструменты для выполнения определенных действий. (Если вы не разработчик, можете пропустить этот раздел).

Подключение к сокету CAN

Для написания собственных утилит, сначала вам потребуется присоединиться к сокету CAN. Подключение к сокету CAN в Linux аналогично подключению к любому сетевому сокету, с которым вы могли встретиться в сетевом программировании TCP/IP. Ниже продемонстрирован код С, специфичный для CAN, а также минимально необходимый код для подключения к сокету CAN. Этот фрагмент кода будет привязан к can0 как к необработанному CAN-сокету.

int s;
struct sockaddr_can addr;
struct ifreq ifr;

s = socket(PF_CAN, SOCK_RAW, CAN_RAW);

strcpy(ifr.ifr_name, “can0”);
ioctl(s, SIOCGIFINDEX, &ifr);

addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;

bind(s, (struct sockaddr *)&addr, sizeof(addr));

Давайте разберем разделы, относящиеся к CAN:

s = socket(PF_CAN, SOCK_RAW, CAN_RAW);

Эта строка указывает семейство протоколов, PF_CAN, и определяет сокет как CAN_RAW. Вы также можете использовать CAN_BCM, если планируете создать службу электронного блока управления (BCM). Служба BCM – это более сложная структура, которая может отслеживать изменения байтов и очередь циклических передач пакетов CAN.

Эти две строки указывают интерфейс:

strcpy(ifr.ifr_name, “can0”);
ioctl(s, SIOCGIFINDEX, &ifr);

Эти строки настраивают семейство CAN для sockaddr, а затем привязываются к сокету, что позволяет вам читать пакеты из сети:

addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;

Настройка структуры CAN

Далее мы настроим структуру CAN и прочитаем байты сети CAN для нашей новой определенной структуры:

struct can_frame frame;
nbytes = read(s, &frame, sizeof(struct can_frame));

can_frame определяется в linux/can.h как:

struct can_frame {
        canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
        __u8    can_dlc; /* frame payload length in byte (0 .. 8) */
        __u8    data[8] __attribute__((aligned(8)));
};

Запись в сеть CAN аналогична команде чтения, но в обратном порядке. Все просто, не так ли?

Интерфейс Procfs

Модули сетевого уровня SocketCAN также реализуют интерфейс procfs. Доступ к информации в proc может упростить создание сценариев bash, а также предоставить быстрый способ увидеть, как работает ядро. Предоставленную информацию о сетевом уровне вы найдете в /proc/net/can/ and /proc/net/can-bcm/. Вы можете увидеть список перехватчиков в CAN-ресивере, выполнив поиск в файле rcvlist_all с помощью cat:

cat /proc/net/can/rcvlist_all
            receive list ‘rx_all’:
                       (vcan3: no entry)
                        (vcan2: no entry)
                          (vcan1: no entry)
                          device   can_id   can_mask  function  userdata   matches  ident
                          vcan0     000     00000000  f88e6370  f6c6f400         0 raw
                           (any: no entry)

Некоторые другие полезные файлы procfs включают следующее:

stats Статистика сетевого уровня CAN

reset_stats Сбрасывает статистику (например, для измерений)

version Версия SocketCAN

Вы можете ограничивать максимальную длину передаваемых пакетов в proc:

echo 1000 > /sys/class/net/can0/tx_queue_len

Для этого значения установите то значение максимальной длины пакета, которого по вашим ощущениям хватит для приложения. Обычно вам не нужно менять это значение, но если вы обнаружите, что у вас есть проблемы с тротлингом, то можете поэкспериментировать с максимальной длинной.

Socketcand

Socketcand (https://github.com/dschanoeh/socketcand) предоставляет сетевой интерфейс для сети CAN. Хотя он не включает в себя can-utils, он все же может быть очень полезным, особенно при разработке приложения на языках программирования, таких как Go, которые не могут устанавливать параметры низкоуровневого сокета CAN, описанные в этой главе.

Socketcand включает полный протокол для управления его взаимодействием с шиной CAN. Например, вы можете отправить в socketcand следующую строку, которая откроет интерфейс loopback:

< can0 C listen_only loopback three_samples >

Протокол для socketcand по существу такой же, как и у BCM-сервера Яна-Никласа Мейера, упомянутого ранее; на самом деле это форк сервера BCM. (Socketcand, однако, немного более надежен, чем сервер BCM).

Kayak

Kayak – это графический пользовательский интерфейс на основе Java для диагностики и мониторинга CAN. (Смотрите рисунок 3-2). Он является одним из лучших инструментов для использования с socketcand. Для маппинга Kayak связывается с OpenStreetMaps и может обрабатывать определения CAN. Как приложение на основе Java, Kayak не зависит от платформы, поэтому для обработки связи с трансиверами CAN он полагается на socketcand.

Kayak вы можете скачать, либо же скомпилировать сами. Чтобы скомпилировать Kayak, установите последнюю версию Apache Maven и клонируйте git репозиторий Kayak. После завершения клонирования выполните следующую команду:

mvn clean package

Вы должны найти свой двоичный файл в папке Kayak/application/target/kayak/bin.

Рисунок 3-2 Графический интерфейс Kayak

Перед запуском Kayak запустите socketcand:

socketcand -i can0

Примечание

К socketcand вы можете подключить столько CAN-устройств, сколько хотите, перечисляйте их через запятую.

Дальше запустите Kayak и выполните следующие действия:

  1. С помощью Ctrl+N создайте новый проект и дайте ему название.
  2. Щелкните правой кнопкой мыши по проекту и выберите Newbus; затем дайте своей шине имя (смотрите рисунок 3-3).
Рисунок 3-3 Создание имени для CAN-шины
Рисунок 3-4 Поиск Auto Discoveryна вкладке Connections
Рисунок 3-5 Установка соединения с шиной
Рисунок 3-6 Чтобы просмотреть пакеты с CAN шины, откройте RAW просмотр и нажмите кнопку воспроизведения

Kayak может легко записывать и воспроизводить сеансы захвата пакетов и поддерживает определения CAN (хранящиеся в открытом формате KDC). На момент написания этой книги графический интерфейс пользователя не поддерживает создание определений, но далее в книгу я покажу, как это делать самостоятельно.

Kayak – отличный кроссплатформенный инструмент с открытым исходным кодом. Кроме того, он имеет удобный графический интерфейс с широким спектром функций, который позволяет определять пакеты CAN, которые вы видите, и просматривать их в графическом виде.

Резюме

В этой главе вы узнали, как использовать SocketCAN в качестве унифицированного интерфейса для устройств CAN, а также как настроить устройство и применить соответствующий битрейт для шины CAN. Я рассмотрел все стандартные утилиты пакета can-utils, которые поставляются с SocketCAN, и показал вам, как написать низкоуровневый код C для прямого взаимодействия с сокетами CAN. Наконец, вы узнали, как использовать socketcand для удаленного взаимодействия с вашими CAN устройствами, и настроили Kayak для работы с socketcand. Теперь, когда вы настроили связь со своим автомобилем, вы почти готовы к тому, чтобы опробовать парочку первых атак.

4

Диагностика и ведение логов

В преобладающем большинстве разъем OBD-II используется механиками для быстрого анализа и устранения проблем с автомобилем. (Чтобы узнать, как найти разъем OBD-II, смотрите главу «Разъем OBD-II»). Когда в автомобиле возникает неисправность, он сохраняет информацию о ней, и включает лампочку «проверьте двигатель», также известную как индикатор неисправности (MIL). Эти стандартные диагностические проверки выполняются основным ЭБУ транспортного средства или модулем управления коробки передач (PCM), который может состоять из нескольких модулей ЭБУ (для простоты обсуждения мы будем упоминать его просто как PCM).

Когда во время своего очередного эксперимента с шиной автомобиля вы обнаружите неисправности, для их устранения, вам понадобится возможность чтения и записи в PCM. В этой главе мы узнаем, как получать и очищать диагностические коды, а также запрашивать диагностические службы ЭБУ. Мы также узнаем, как получить доступ к данным о ДТП автомобиля и как подобрать (brute-force) скрытые диагностические коды.

Диагностические коды неисправностей

PCM хранит коды ошибок как диагностические коды неисправностей. DTC хранятся в разных местах. Например, коды DTC, хранящиеся в памяти, находятся в ОЗУ PCM, что означает, что при потере питания от батареи коды стираются (как и все коды DTC, хранящиеся в ОЗУ). Более серьезные коды неисправностей хранятся в местах, которые переживут сбой питания.

Ошибки обычно классифицируются как серьезные и легкие. Легкие неисправности соответствуют периодическим проблемам, в то время как серьезные неисправности не исчезнут без какого-либо вмешательства. Чтобы определить, является ли неисправность серьезной или нет, механики часто удаляют коды неисправности и немного проезжаются на автомобиле, чтобы проверить, появляется ли ошибка снова.  Если ошибка появляется снова, неисправность является серьезной. Легкая неисправность может быть вызвана, например, неплотно закрытой крышкой бензобака.

Однако не все неисправности сразу вызывают срабатывание индикатора MIL. В частности, неисправности класса A, которые сигнализируют отказ системы выбросов автомобиля, сразу же вызывают срабатывание индикатора MIL, а неисправности класса B, которые не влияют на систему выбросов авто, при первом их появлении сохраняются как отложенные ошибки. Перед срабатыванием индикатора MIL, PCM ожидает записи нескольких одинаковых неисправностей. При сбоях класса С индикатор MIL загорается редко, вместо этого появляется сообщения типа «скоро потребуется осмотр». Неисправности класса D вообще не включают лампочку MIL.

При сохранении кодов неисправности PCM делает снимки всех соответствующих компонентов двигателя в так называемых стоп-кадр данных, которые обычно содержат следующую информацию:

Некоторые системы хранят только один стоп-кадр, обычно для первого сработавшего кода неисправности или кода неисправности с наивысшим приоритетом, в то время как другие системы записывают несколько.

В идеальном мире эти стоп-кадры должны были бы делаться сразу после появления кода неисправности, но в наших автомобилях обычно они регистрируются примерно пять секунд после срабатывания кода неисправности.

         Формат DTC

DTC – это пятизначный буквенно-цифровой код. Например, вы можете увидеть такие коды: P0477 (низкий уровень клапана регулирования давления выхлопных газов); U0151 (потеря связи с модулем управления удерживающей системой). Первая позиция кода представляет основную функцию компонента, установившего код, как показано в таблице 4-1.

Позиция байтаОписание
1P (0x0) = коробка передач, B (0x1) = кузов
C (0x2) = шасси, U (0x3) = сеть
20,2,3 (стандарт SAE) 1,3 (зависит от производителя)
3Подгруппа позиции 1
4Конкретная область ошибки
5Конкретная область ошибки
Таблица 4-1: Диагностические коды

Примечание

Если установлено значение 3, байт 2 является как стандартом, определенным SAE, так и кодом конкретного производителя. Первоначально значение 3 использовалось исключительно для производителей, но сейчас значение 3 все больше хотят стандартизировать, чтобы обозначить им стандартный код. В современных автомобилях, если вы видите цифру 3 во второй позиции, вероятно, это стандартный код SAE.

Пять символов в DTC предоставлены в сети всего двумя необработанными байтами. В таблице 4-2 показано, как разбить два байта DTC на полный пятизначный код.

Таблица 4-2: Двоичные диагностические коды поломок

За исключением первых двух, значения имеют отношения один-к-одному. Чтобы увидеть обозначение первых двух битов, обратитесь к таблице 4-1.

У вас должна быть возможность выхода в интернет, чтобы иметь возможность найти значение любого кода. Вот несколько примеров диапазонов для распространенных кодов неисправности трансмиссии:

Чтобы узнать значение того или иного кода, приобретите книгу по ремонту из серии Chilton в местном автомагазине. Там вы найдете список всех диагностических кодов OBD-II для вашего автомобиля.

Считывание кодов неисправности с помощью средств сканирования

Механики проверяют коды неисправности с помощью диагностических приборов. Инструменты сканирования – это хорошо, но их наличие для взлома автомобиля не обязательно. Вы можете приобрести такое оборудование в любом автомагазине или в интернете по цене от 100 до 3000 долларов.

В качестве самого дешевого решения вы можете купить устройство под названием ELM327 на eBay примерно за 10 баксов. Обычно это электронные ключи, которым требуется дополнительное программное обеспечение, например, мобильное приложение, чтобы они могли функционировать как полноценные инструменты сканирования. Само программное обеспечение обычно бесплатное или стоит менее 5 долларов. Базовый диагностический прибор должен уметь исследовать систему неисправностей автомобиля и сообщать об общих кодах DTC, кроме специфических кодов отдельных производителей. Более профессиональные приборы должны иметь базы данных со специфическими кодами отдельных производителей для более подробного тестирования.

Очистка DTC

Коды неисправности обычно стираются сами, как только неисправность больше не появляется, в условиях, подобным тем, когда неисправность была обнаружена впервые. Для этого определяются следующие условия:

В нормальных условиях, когда PCM больше не замечает неисправностей после трех проверок, индикатор MIL гаснет, а коды DTC стираются. Есть и другие способы сбросить эти коды: вы можете удалить легкие коды неисправностей с помощью диагностического прибора (описанного в предыдущем разделе) или отсоединив аккумулятор автомобиля. Однако постоянные или серьезные коды неисправности сохраняются в NVRAM и удаляются только тогда, когда PCM больше не видит состояния неисправности. Причина этому достаточно проста: не дать механикам вручную выключить лампочку индикации неисправности о очистить коды DTC, если проблемы все еще имеются. Постоянные коды DTC дают механикам историю неисправностей автомобиля, чтобы те могли подробнее вникнуть в суть проблемы.

Единые диагностические службы

Единые диагностические службы (UDS) разработаны, чтобы обеспечить унифицированный способ показать автомеханикам, что происходит с транспортным средством, без необходимости платить огромные лицензионные сборы за проприетарные схемы пакетов CAN-шины от производителя.

К сожалению, хотя UDS были разработаны, чтобы сделать информацию о транспортном средстве доступной даже для «семейных» механиков, в действительности все обстоит немного иначе: пакеты CAN отправляются одинаково, но их содержимое различается для каждой марки, модели и даже года.

Автопроизводители продают дилерам лицензии на детали содержимого пакета. На практике, UDS просто работает как шлюз, чтобы сделать доступной некоторую, но не всю, информацию о транспортном средстве. Система UDS не влияет на работу транспортного средства; по сути, это просто доступное только для чтения представление о том, что происходит с авто. Однако UDS можно использовать для выполнения более сложных операций, таких как диагностические тесты или модификации прошивки (службы, которые являются функцией только высокопроизводительных инструментов сканирования). Подобные диагностические тесты отправляют системе запрос на выполнение действия, и этот запрос генерирует сигналы, такие как другие пакеты CAN, которые используются для выполнения работы. Например, диагностический инструмент может сделать запрос на разблокировку дверей автомобиля, в результате чего компонент отправляет отдельный сигнал CAN, который фактически выполняет собственно разблокировку дверей.

Отправка данных по ISO-TP и CAN

Поскольку кадры CAN ограничены 8 байтами данных, для отправки больших выходных данных по шине CAN, UDS использует протокол ISO-TP. Вы по-прежнему можете использовать обычный CAN для чтения или отправки данных, но ответ не будет полным, поскольку ISO-TP объединяет несколько пакетов CAN в цепочку.

Чтобы проверить ISO-TP, подключитесь к сети CAN, в которой есть модули с диагностической функцией, например, ECU. Затем отправьте пакет, созданный для ISO-TP, через обычный CAN с помощью приложения SocketCAND cansend:

cansend can0 7df#02010d
Replies similar to 7e8 03 41 0d 00

В этом листинге 7df – это диагностический код OBD, 02 – размер пакета, 01 – режим (показывает текущие данные; список общих режимов и PID смотрите в вложении B), а 0d – сервис (скорость автомобиля 0, потому что он был неподвижен). В ответе к идентификатору добавляется 0x8 (7e8); следующий байт – это размер ответа. Затем ответ добавляют к типу запроса 0x40, в данном случае это 0x41. Затем сервис повторяется и следует за данными. ISO-TP диктует, как отвечать на CAN-пакеты.

Обычные CAN-пакеты используют структуру «запустил и забыл», то есть они просто отправляют данные без ожидания ответного пакета. ISO-TP определяет метод получения данных ответа. Поскольку эти данные не могут быть отправлены обратно с использованием того же идентификатора арбитража, получатель возвращает ответ, добавляя к идентификатору 0x8 и отмечает, что ответ является положительным, добавляя к запросу 0x40. (Если ответ не прошел, вы должны увидеть 0x7F вместо положительного ответа + 0x40).

В таблице 4-3 перечислены наиболее частые реакции на ошибки.

Hex (4-ый байт)АббревиатураОписание
10GRОбщий отказ
11SNSСервис не поддерживается
12SFNSПодфункция не поддерживается
13IMLOIFНеверная длина сообщения или недопустимый формат
14RTLСлишком длинный ответ
21BRRОтсутствует повторный запрос
22CNCНеправильное состояние
24RSEОшибка последовательности запроса
25NRFSCНет ответа от компонента подсети
26FPEORAВыполнению запрошенного действия  препятствует ошибка
31ROORЗапрос вне диапазона
33SADОтказ в доступе
35IKНеверный ключ
36ENOAПревышено количество попыток
37RTDNEНе истекла требуемая выдержка времени
38-4FRBEDLSDЗарезервировано документом безопасности расширенного канала передачи данных
70UDNAЗагрузка/скачивание не принято
71TDSПередача данных приостановлена
72GPFОбщий сбой программирования
73WBSCСбой счетчика последовательности блоков
78RCRRPЗапрос получен правильно, но ответ еще не получен
7ESFNSIASПодфункция не поддерживается в активно сеансе
7FSNSIASСервис не поддерживается в активном сеансе
Таблица 4-3: Типичные ошибки UDS

Например, если вы используете службу 0x11 для сброса ЭБУ, а ЭБУ не поддерживает удаленный сброс, вы можете увидеть следующее:

cansend can0 7df#021101
Replies similar to 7e8 03 7F 11 11

В этом ответе мы видим, что после 0x7e8 следующим байтом является 0x03, который отображает размер ответа. Следующий байт, 0x7F, представляет ошибку для службы 0x11, третьего байта. Последний байт, 0x11, отображает возвращенную ошибку – в данном случае сервис не поддерживается (SNS).

Чтобы отправить или получить что-либо, содержащее более 8 байтов данных в стандартном пакете CAN, используйте инструмент SocketCAN ISO-TP. Чтобы увидеть ответ на ваши команды istotpsend в одном терминале запустите istotpsend, а во втором isotpsniffer (или isotprecv). (Не забудьте изменить (insmod) ваш модуль can-isotp.ko, как описано в главе 3).

Например, в одном терминале настройте сниффер следующим образом:

isotpsniffer -s 7df -d 7e8 can0

Затем во втором терминале отправьте пакет запроса через командую строку:

echo “09 02” | isotpsend -s 7DF -d 7E8 can0

При использовании ISO-TP необходимо указать адрес источника и получателя (ID). В этом случае UDS источником является 0x7df, а местом назначения (ответом) является 0x7x8. (При использовании инструментов ISO-TP префикс 0x в адресах не указывается).

В этом примере чтобы запросить VIN автомобиля мы отправляем пакет, содержащий PID 0x02 с режимом 0x09. Ответ в сниффере должен отображать VIN автомобиля, как показано в последней строке вывода:

isotpsniffer -s 7df -d 7e8 can0
 can0  7DF  [2]  09 02  – ‘..’
 can0  7E8  [20]  49➊ 02➋ 01➌ 31 47 31 5A 54 35 33 38 32 36 46 31 30 39 31 34 39
     – ‘I..1G1ZT53826F109149’

Первые три байта составляют ответ UDS. 0x49➊ – это услуга 0x09 + 0x40, что означает положительный ответ для PID 0x02➋ следующего байта. Третий байт, 0x01➌, указывает, количество возвращаемых элементов данных (в данном случае один VIN). Возвращенный VIN – G1ZT53826F109149. Вбейте этот VIN в Google, и вы должны увидеть подробную информацию об этом авто, которая была взята из ЭБУ, снятого с разбитой машины, найденной на свалке. Таблица 4-4 показывает информацию, которую вы должны увидеть:

МодельГодМаркаКузовДвигатель
Malibu2006ChevroletСедан 4 двери3.5 L V6 OHV 12V
Таблица 4-4: Информация по VIN

Если бы вы смотрели этот запрос UDS через обычный сниффер CAN, вы бы увидели несколько пакетов ответа на 0x7x8. Вы можете пересобрать пакет ISO-TP вручную или с помощью скрипта, но инструменты ISO-TP значительно упрощают задачу.

Примечание

Если у вас возникли проблемы с запуском инструментов ISO-TP, убедитесь, что ваш модуль ядра скомпилирован и установлен правильно. (Смотрите «Установка дополнительных модулей ядра»).

Понятия режимов и PID

Первый байт раздела данных в диагностическом коде – это режим. В автомобильных руководствах режимы начинаются с «$», как, например, $1. Символ «$» используется для обозначения шестнадцатеричного числа. Режим $1 соответствует 0x01, $0A соответствует 0x0A и так далее. Здесь я привел несколько примеров, другие примеры смотрите во вложении B.

0x01: показывает текущие данные

Показывает потоки данных заданного PID. Отправка PID 0x00 возвращает 4 байта, доступных в битовой кодировке (от 0x01 до 0x20).

0x02: показывает данные стоп-кадра

Имеет те же значения PID, что и 0x01, за исключением того, что возвращенные данные относятся к состоянию стоп-кадра.

0x03: показывает сохраненные «подтвержденные» диагностические коды неисправностей

Соответствует кодам неисправностей, указанным в разделе «Формат DTC».

0x04: стирает коды неисправности и очищает журнал диагностики

Стирает коды неисправности и данные стоп-кадра.

0x07: показывает «ожидающие» диагностические коды

Отображает коды, которые всплывали один раз, и не были подтверждены; статус: ожидание.

0x08: операции управления бортового компонента/системы

Позволяет техническому специалисту вручную включать и выключать исполнительные механизмы автомобиля. Системные исполнительные механизмы позволяют воздействовать на различные устройства “по проводам” (drive-by-wire) и физически управлять ими. Эти коды нестандартны, поэтому с обычным диагностическим прибором многие операции будут недоступны. Инструменты диагностирования дилерских центров имеют гораздо больший доступ к внутреннему устройству транспортных средств и являются интересной целью для хакеров и реверс-инженеров.

0x09: запрашивает информацию об автомобиле

С помощью режима 0x09 можно извлечь несколько фрагментов данных.

0x0a: постоянные диагностические коды

Этот режим извлекает коды неисправности, которые были стерты в режиме 0x04. Эти коды неисправностей удаляются после того, как PCM подтвердит, что состояния неисправности больше нет. (Смотрите «Удаление кодов неисправности»)

Брутфорс диагностических режимов

У каждого производителя есть свои собственные режимы и PID, которые обычно можно получить, немного покопавшись в «приобретенном» программном обеспечении дилера, используя инструменты или грубую силу. Самый просто способ брутфорса – использование инструмента с открытым исходным кодом под названием CaringCaribou (CC), доступный для скачивания по адресу: https://github.com/CaringCaribou/caringcaribou.

CaringCaribou состоит из набора модулей Python, предназначенных для работы с SocketCAN. Одним из таких модулей является модуль DCM, специально предназначенный для обнаружения диагностических служб.

Чтобы начать работу с CaringCaribou, создайте RC-файл в своем корневом каталоге ~/.canrc.

[default]
interface = socketcan_ctypes
channel = can0

Установите свой канал на канал вашего устройства SocketCAN. Теперь, чтобы узнать, какую диагностику поддерживает ваш автомобиль, запустите следующее:

./cc.py dcm discovery

Это отправит код присутствия тестировщика на каждый идентификатор арбитража. Как только инструмент обнаружит корректный ответ (0x40 + сервис) или ошибку (0x7f), он выведет идентификатор арбитража и идентификатор ответа. Вот пример сеанса обнаружения с использованием CaringCaribou:

——————-
CARING CARIBOU v0.1
——————-

Loaded module ‘dcm’

Starting diagnostics service discovery
Sending diagnostics Tester Present to 0x0244
Found diagnostics at arbitration ID 0x0244, reply at 0x0644

Мы видим, что на 0x0244 отвечает диагностическая служба. Отлично! Затем мы проверяем различные службы по 0x0244:

./cc.py dcm services 0x0244 0x0644

——————-
CARING CARIBOU v0.1
——————-

Loaded module ‘dcm’

Starting DCM service discovery
Probing service 0xff (16 found)
Done!

Supported service 0x00: Unknown service
Supported service 0x10: DIAGNOSTIC_SESSION_CONTROL
Supported service 0x1a: Unknown service
Supported service 0x00: Unknown service
Supported service 0x23: READ_MEMORY_BY_ADDRESS
Supported service 0x27: SECURITY_ACCESS
Supported service 0x00: Unknown service
Supported service 0x34: REQUEST_DOWNLOAD
Supported service 0x3b: Unknown service
Supported service 0x00: Unknown service
Supported service 0x00: Unknown service
Supported service 0x00: Unknown service
Supported service 0xa5: Unknown service
Supported service 0xa9: Unknown service
Supported service 0xaa: Unknown service
Supported service 0xae: Unknown service

Обратите внимание, что в выходных данных перечислено несколько повторяющихся служб для службы 0x01. Часто это происходит из-за того, что сообщение об ошибке не относится к службе UDS. Например, запросы ниже 0x0A являются устаревшими режимами, которые не отвечают официальному протоколу UDS.

Примечание

На момент написания этой книги CaringCaribou находится на ранней стадии разработки, поэтому ваши результаты могут отличаться. Текущая доступная версия не учитывает старые режимы и неправильно анализирует ответ, именно поэтому на выходе вы видите несколько одинаковых служб с идентификатором 0x00. Пока что просто игнорируйте эти службы; это ложные срабатывания. Опция обнаружения в CaringCaribou останавливается на первом идентификаторе арбитража, который отвечает на запрос диагностического управления сеансом (DSC). Перезапустите сканирование с того места, где оно было остановлено, используя параметр –min, следующим образом:

./cc.py dcm discovery -min 0x245

В нашем примере сканирование также прекратится немного позже по этому более распространенному диагностическому ID:

Found diagnostics at arbitration ID 0x07df, reply at 0x07e8  

Поддержание автомобиля в диагностическом состоянии

При выполнении определенных типов диагностических операций важно поддерживать автомобиль в диагностическом состоянии, поскольку вероятность прерывания его работы снизится. Чтобы поддерживать транспортное средство в этом состоянии, вам необходимо постоянно отправлять пакет, чтобы сообщать автомобилю о присутствии специалиста по диагностике.

Эти простые скрипты будут поддерживать автомобиль в диагностическом состоянии, что будет полезным для прошивки ПЗУ и брутборса. Пакет присутствия специалиста по диагностике будет поддерживать диагностическое состояние автомобиля. Это работает как сердцебиение, поэтому вам необходимо передавать этот пакет каждые одну-две секунды, как показано ниже:

#!/bin/sh
while :
do
    cansend can0 7df#013e
    sleep 1
done

Вы можете сделать тоже самое с помощью cangen:

cangen -g 1000 -I 7DF -D 013E -L 2 can0

Примечание

На момент написания этой книги cangen не всегда работает с устройствами CAN с последовательной линией. Один из возможных обходных путей – указать slcand использовать имена в стиле canX вместо slcanX.

Для чтения данных по идентификатору и запроса информации на устройствах используйте команду ReadDataByID. 0x01 – это стандартный запрос. Расширенная версия, 0x22, может возвращать информацию, недоступную с помощью стандартных инструментов OBD.

Для доступа к защищенной информации используйте команду SecurityAccess (0x27). Это может быть «скользкий» ключ, в том плане, что пароль или ключ будут каждый раз меняться, но важно то, что ответ контроллера будет успешным. Например, если вы отправляете ключ 0x01, и это правильный код доступа, то в ответ вы должны получить 0x02. Некоторые запросы, такие как перепрошивка ПЗУ, потребуют от вас запроса SecurityAccess. Если у вас нет алгоритма для генерации необходимого ответа на запрос, вам придется подобрать ключ.

Ведение журнала регистратора логов

Вероятно, вы знаете, что в самолетах есть черные ящики, в которые записывается информация о полетах, а также все разговоры в кабине и по радио. Все автомобили 2015 года и новее также должны иметь тип черного ящика, известный как регистратор данных о событиях (EDR), но EDR записывают только часть информации, которую может записать черный ящик на самолете. Информация, хранящаяся в EDR, включает следующее (более полный список вы найдете в SAE J1698-2:

Хотя эти данные очень похожи на данные стоп-кадра, их цель – сбор и хранение информации во время аварии. EDR хранит информацию постоянно. Изначально эта информация хранилась в модуле управления подушками безопасности (ACM), но современные автомобили распределяют эти данные между электронными блоками управления. Эти ящики собирают данные от других ЭБУ и датчиков и хранят их для восстановления после аварии. На рисунке 4-1 показан типичный EDR.

Рисунок 4-1 Типичный EDR

Чтение данных с EDR

Официальный способ чтения данных с EDR – это набор инструментов для извлечения данных о авариях (CDR). Базовый инструмент CDR подключается к разъему OBD и извлекает данные (или изображение автомобиля) из главного ЭБУ. Инструменты CDR также могут получать доступ к данным в других модулях, таких как ACM или модуль датчика опрокидывания (ROS), но для этого его стоит подключить напрямую к этим устройствам, а не пытаться сделать это через порт OBD.

В комплекты CDR входят как собственное оборудование, так и программное обеспечение. Оборудование обычно стоит около 2 тысяч долларов, а стоимость ПО будет зависеть от количества поддерживаемых типов транспортных типов. Формат данных о сбоях автомобиля часто считается проприетарным, и многие производители лицензируют протокол связи поставщикам инструментов, которые создают CDR. Очевидно, что это не в интересах потребителя. Национальная администрация безопасности дорожного движения (NHTSA) предложила использовать стандартный метод связи OBD для доступа к этим данным.

Стандарт SAE J1698

Стандарт SAE J1698 перечисляет рекомендуемые методы сбора данных о событиях и определяет записи событий по частоте дискретизации: высокая, низкая и статическая. Высокая частота дискретизации – это данные, записанные во время сбоя, низкая – это данные перед сбоем, а статическая – это данные, которые не меняются. SAE J1698 оказывает влияние на многих автопроизводителей, но он не обязательно соответствует правилам для всех данных, полученных с автомобиля.

Некоторые записываемые элементы:

Хотя SAE J1698 записывает координаты, многие производители заявляют, что не записывают эту информацию из соображений конфиденциальности. Ваши соображения могут отличаться от их.

Другие методы поиска данных

Не все производители соответствуют стандарту SAE J1698. Например, с 1990-х годов General Motors собирала небольшой объем данных EDR в модуле датчиков и диагностики (SDM) своих автомобилей. SDM хранит Delta-v транспортного средства, которое представляет собой изменение скорости автомобиля в продольном направлении. SDM не записывает никакой информации после аварии.

Другой пример – EDR компании Ford, известный как модуль контроля безопасности (RCM). Ford вместо Delta-v хранит данные о продольном и поперечном ускорении автомобиля. Если в автомобиле есть электронное управление дроссельной заслонкой, PCM сохраняет дополнительные данные EDR, в том числе, был ли пассажир совершеннолетним, процент нажатия педалей газа/тормоза и был ли диагностический код активен в момент аварии.

Автоматизированные системы уведомления о авариях

Системы автоматического уведомления о сбоях (ACN) – это системы домашнего телефона, которые связываются с производителем автомобиля или третьей стороной с информацией о событии. Они объединяются с другими системами восстановления после аварии и расширяют функциональность, обращаясь к производителю или третьей стороне. Одно из основных его отличий заключается в том, что нет никаких правил или стандартов относительно того, какие данные будут собираться и отправляться в сеть ACN. ACN индивидуальны для каждого производителя, и каждая система будет отправлять разную информацию. Например, автоматизированная система уведомления о столкновениях Veridian (выпущенная в 2001 году) сообщает следующую информацию:

Вредоносное воздействие

Злоумышленники могут нацеливаться на коды неисправности и замораживать данные с целью сокрытия вредоносной активности. Например, если эксплоиту необходимо воспользоваться кратковременным условием, данные о замораживании автомобиля, скорее всего, пропустят событие из-за задержек в записи. Захваченные снимки стоп-кадра редко содержат информацию, которая поможет определить, был ли DTC вызван вредоносной атакой. (Поскольку системы EDR обычно срабатывают только во время аварии, маловероятно, что злоумышленник будет нацеливаться на них, поскольку вряд ли они могут содержать ценные данные).

Злоумышленник, проводящий фаззинг системы транспортного средства, может проверить наличие сработавших кодов неисправности и использовать информацию, содержащую в коде неисправности, для определения того, какой компонент неисправен. Этот тип атаки, скорее всего, будет происходить на этапе исследования (когда злоумышленник пытается определить, на какие компоненты воздействовали случайно сгенерированные пакеты), а не во время активации эксплоита.

Доступ к PID, зависящим от производителя, и их фаззинг – посредством перепрошивки или использования режима 0x08 – может привести к интересным результатам. Поскольку интерфейс каждого производителя держится в секрете, трудно оценить реальный риск для сети. К сожалению, чтобы выполнить работу по определению наличия уязвимостей, специалистам по безопасности потребуется реверсировать или фаззировать эти проприетарные интерфейсы. Злоумышленники должны будут сделать то же самое, хотя у них не будет мотивации делиться своими находками. Чем дольше они будут держать в секрете недокументированные точки входа и уязвимости, тем дольше их эксплоит будет оставаться незамеченным. Наличие секретных точек входа в автомобиль не повышает его безопасность; уязвимости существуют независимо от того, обсуждают ли их люди. Поскольку продажа таких уязвимостей приносит деньги (иногда сумы превышают 50 тысяч долларов США), у отрасли мало стимулов для поддержки сообщества.

Резюме

В этой главе мы вышли за рамки традиционных пакетов CAN, чтобы понять устройство более сложных протоколов, таких как ISO-TP. Вы узнали, как CAN-пакеты могут быть связаны друг с другом для отправления более крупных сообщений или создания двухсторонней связи по CAN. Также вы узнали, как считывать и удалять любые коды неисправности. Вы узнали, как найти недокументированные диагностические службы, и увидели, какие данные записываются о вас и ваших привычках вождения. Вы также изучили некоторые способы использования диагностических служб злоумышленниками.

5

Реверс-инжениринг CAN-шины

Чтобы отреверсить CAN-шину, сначала мы должны иметь возможность читать CAN-пакеты и определять, что контролирует отдельно взятый пакет. Тем не менее, нам не нужно иметь доступ к официальным диагностическим CAN-пакетам, потому что в большинстве своем они доступны только для чтения. Вместо этого наш интерес будет фокусироваться на всех других пакетах, которые передаются по CAN-шине. Остальные недиагностические пакеты – это те пакеты, которые машина фактически использует для выполнения определенных действий. На добычу информации, содержащейся в этих пакетах может потребоваться достаточно много времени, но эти знания могут иметь критическое значение для понимания поведения автомобиля.

Расположение CAN-шины

Разумеется, перед тем как реверсить CAN-шину, нам нужно ее найти. Если у вас есть доступ к разъему OBD-II, схема расположения контактов разъема вашего автомобиля должна показать вам, где именно расположена шина CAN. (Для ознакомления с типичным расположением разъемов OBD и их распиновкой смотрите главу 2). Если у вас нет доступа к разъему OBD-II или вы ищите скрытые сигналы CAN, попробуйте один из следующих методов:

Примечание

Когда автомобиль заглушен, шина CAN обычно «молчит», но что-то настолько простое, как вставление ключа или нажатие на ручку двери скорее всего «разбудит» автомобиль и подаст сигнал.

После того, как вы определили сеть CAN, следующим шагом будет начало мониторинга трафика.

Реверсирование связи шины CAN с помощью can-utils и Wireshark

Во-первых, вам нужно определить тип связи, работающий на шине. Вам часто придется определять какой-то сигнал, или то, как реагирует определенный компонент, например, как разблокируется автомобиль или работает трансмиссия. Для этого, найдите шину, которую используют эти целевые компоненты, а затем отреверсите пакеты, перемещающиеся по этой шине. Так вы сможете определить их назначение.

Чтобы отслеживать активность CAN, вам нужно устройство, которое может отслеживать и генерировать CAN-пакеты. На рынке существует масса таких устройств. Дешевые устройства OBD-II, которые продаются по цене менее 20 долларов, с технической точки зрения работают, но их анализаторы работают медленно и пропускают много пакетов. Всегда лучше иметь максимально хорошее устройство, потому что оно будет работать с большим количеством программных инструментов – аппаратное и программное обеспечение с открытым исходным кодом всегда будет лучшим вариантом.  Тем не менее, проприетарное устройство, специально разработанное для сниффинга CAN, также будет выполнять все необходимые базовые функции. Мы рассмотрим использование candump из пакета can-utils и Wireshark для захвата и фильтрации пакетов.

Общий анализ пакетов не работает для CAN, так как пакеты CAN уникальны для каждой марки и модели автомобиля. Кроме того, из-за сильного шума на CAN, сортировать каждый отдельно взятый пакет будет слишком сложно.

Использование Wireshark

Wireshark (https://www.wireshark.org/) – распространенный инструмент мониторинга сети. Если у вас есть опыт работы с сетями, вашим первым инстинктивным действием для просмотра пакетов CAN может быть использование Wireshark. Технически он выполняет свою работу, но скоро мы увидим, почему Wireshark не лучший инструмент, который можно использовать для мониторинга.

Если вы хотите использовать Wireshark для захвата CAN-пакетов, вы можете сделать это вместе с SocketCAN. Wireshark может прослушивать как canX, так и vcanX, но не slcanX, потому что устройства с последовательным соединением в действительности не являются устройствами netlink и для их работы требуется утилиты трансляции. Если вам нужно использовать устройство slcanX с Wireshark, попробуйте изменить имя с slcanX на canX (я подробно рассказываю об интерфейсах CAN в главе 2).

Если переименование интерфейса не помогло или вам просто нужно переместить CAN-пакеты с интерфейса, который Wireshark прочитать не может, на тот, который может, вы можете соединить два интерфейса. Для отправки пакетов с slcan0 на vcan0 вам потребуется использовать candump из пакета can-utils в режиме моста.

$ candump -b vcan0 slcan0

Обратите внимание, что на рисунке 5-1 раздел данных не декодирован и показывает только необработанные шестнадцатеричные байты. Это связано с тем, что декодер Wireshark обрабатывает только базовые заголовки CAN и не знает, как работать с пакетами ISO-TP или UDS. Выделенный пакет – это запрос UDS для VIN. (чтобы с пакетами было легче работать, я отсортировал их по идентификатору, а не по времени).

Рисунок 5-1 Wireshark на шине CAN

Использование candump

Как и в случае с Wireshark, candump не декодирует данные за вас; эта работа предоставляется вам, как реверс-инженеру. В листинге 5-1 в качестве сниффера используется slcan0.

$ candump slcan0
    slcan0➊  388➋  [2]➌  01 10➍
  slcan0   110   [8]    00 00 00 00 00 00 00 00
  slcan0   120   [8]    F2 89 63 20 03 20 03 20
  slcan0   320   [8]    20 04 00 00 00 00 00 00
  slcan0   128   [3]    A1 00 02
  slcan0   7DF   [3]    02 09 02
  slcan0   7E8   [8]    10 14 49 02 01 31 47 31
  slcan0   110   [8]    00 00 00 00 00 00 00 00
  slcan0   120   [8]    F2 89 63 20 03 20 03 20
  slcan0   410   [8]    20 00 00 00 00 00 00 00
  slcan0   128   [3]    A2 00 01
  slcan0   380   [8]    02 02 00 00 E0 00 7E 0E
  slcan0   388   [2]    01 10
  slcan0   128   [3]    A3 00 00
  slcan0   110   [8]    00 00 00 00 00 00 00 00
  slcan0   120   [8]    F2 89 63 20 03 20 03 20
  slcan0   520   [8]    00 00 04 00 00 00 00 00
  slcan0   128   [3]    A0 00 03
  slcan0   380   [8]    02 02 00 00 E0 00 7F 0D
  slcan0   388   [2]    01 10
  slcan0   110   [8]    00 00 00 00 00 00 00 00
  slcan0   120   [8]    F2 89 63 20 03 20 03 20
  slcan0   128   [3]    A1 00 02
  slcan0   110   [8]    00 00 00 00 00 00 00 00
  slcan0   120   [8]    F2 89 63 20 03 20 03 20
  slcan0   128   [3]    A2 00 01
  slcan0   380   [8]    02 02 00 00 E0 00 7C 00

Листинг 5-1: candump потокового трафика по CAN-шине.

Столбцы разбиты на части, чтобы показать устройство сниффера ➊, идентификатор арбитража ➋, размер CAN-пакета ➌, и сами данные CAN ➍. Теперь у вас есть несколько перехваченных пакетов, но их не так легко прочитать. Мы будем использовать фильтры, чтобы идентифицировать пакеты, которые мы хотим проанализировать более подробно.

Группировка потоковых данных из CAN-шины

Устройства в сети CAN шумят, часто пульсируют с заданными интервалами или запускаются при определенном событии, например, открытии двери. Этот шум может сделать бесполезной передачу данных из сети CAN без фильтра. Хороший сниффер CAN группирует изменения пакетов в потоке данных на основе их идентификатора арбитража, выделяя только те фрагменты данных, которые изменились с момента последнего просмотра пакета. Таким образом группировка пакетов упрощает обнаружение изменений, которые возникают непосредственно в результате манипуляций с транспортным средством, позволяя вам активно отслеживать секцию анализа инструмента, а также отслеживать изменения цвета, которые коррелируют с физическими изменениями. Например, если каждый раз, когда вы открываете дверь, вы видите одно и то же изменение байта в потоке данных, вы можете сказать, что, вероятно, определили, как минимум один байт, который управляет функцией отпирания дверей.

Группировка пакетов с помощью cansniffer

cansniffer – инструмент командной строки – группирует пакеты по идентификатору арбитража и выделяет байты, которые изменились с момента последнего просмотра этого идентификатора сниффером. Например, на рисунке 5-2 показан результат работы cansniffer на устройстве slcan0.

Рисунок 5-2 Пример вывода cansniffer

Вы можете добавить атрибут –c, чтобы раскрасить любые изменяющиеся байты.

cansniffer -c slcan0

Инструмент cansniffer также может удалять повторяющийся CAN-трафик, который не изменяется, уменьшив тем самым количество пакетов, которые вам нужно отслеживать.

Фильтрация отображаемых пакетов

Одним из преимуществ cansniffer является возможность отправки ему ввода с клавиатуры, чтобы фильтровать результаты по мере их отображения в терминале. (Обратите внимание, что пока cansniffer будет выводить результаты, вы не будете иметь возможности видеть вводимые команды). К примеру, чтобы при сборе пакетов вы видели только ID 301 и 308, введите следующее:

000000
+301
+308

 При вводе -000000 все пакеты отключаются, а при вводе +301 и +308 отфильтровываются все, кроме ID 301 и 308.

Команда -000000 использует битовую маску (bitmask), которая сравнивает битовый уровень с идентификатором арбитража. Любое двоичное значение 1, используемое в маске, – это бит, который должен быть true, а двоичное значение 0 – это подстановочный знак, который может соответствовать чему угодно. Битовая маска всех нулей сообщает cansniffer о том, что нужно сопоставить все идентификаторы арбитража. Знак минус (-) перед битовой маской удаляет все совпадающие биты, то есть каждый пакет.

Вы также можете использовать фильтр и битовую маску с cansniffer для того, чтобы получить диапазон идентификаторов. Например, следующая команда выводит на дисплей идентификаторы от 500 до 5FF, где 500 – это идентификатор, применяемый к битовой маске 700 для определения интересующего нас диапазона.

+500700

Чтобы отобразить все идентификаторы 5XX, вы должны использовать следующее двоичное представление:

ID  Binary Representation
500  101 0000 0000
700  111 0000 0000
——————
     101 XXXX XXXX
      5    X    X

Вместо 700 вы можете указать F00, но поскольку идентификатор арбитража состоит всего из 3 бит, все что требуется ввести – это 7.

Использование 7FF в качестве маски – то же самое, что не указывать битовую маску для идентификатора. Например:

+3017FF

то же самое что и

+301

Эта маска использует двоичную математику и выполняет операцию И (AND) над двумя числами: 0x301 и 0x7FF:

ID    Binary Representation
301   011  0000  0001
7FF   111  1111  1111
______________________________
      011  0000  0001
      3    0      1

Для тех, кто не знаком с операцией И, каждый двоичный бит сравнивается, и если оба равны 1, то на выходе будет 1. Например, 1 И 1 = 1, а 1 И 0 = 0.

Графический интерфейс, Kayak, о котором мы говорили в одноименной главе, представляет собой приложение для мониторинга шины CAN, которое также использует socketcand и раскрашивает отображение захваченных пакетов. Kayak, не удаляет повторяющиеся пакеты, как cansniffer, но он предлагает несколько уникальных функций, которые вы не сможете так легко повторить в командной строке, например, документирование идентифицированных пакетов в XML (файлы .kcd), которые могут использоваться Kayak для отображения виртуальных групп инструментов и картографических данных. (Смотрите рисунок 5-3).

Рисунок 5-3 Графический интерфейс Kayak

Использование записи и воспроизведения

После того, как вы использовали cansniffer или аналогичный инструмент для идентификации определенных пакетов, на которых нужно сосредоточиться, следующим шагом будет запись и воспроизведение пакетов для их последующего анализа. Для этого мы рассмотрим два разных инструмента: can-utils и Kayak. Они обладают примерно одинаковой функциональностью, а ваш выбор будет зависеть от того, на чем вы работаете и какой интерфейс вам окажется предпочтительней.

can-utils записывает пакеты CAN, используя простой формат ASCII, который вы можете просматривать с помощью самого простого текстового редактора, а большинство его инструментов поддерживают этот формат как для записи, так и для воспроизведения. Например, вы можете записывать пакеты с помощью candump, перенаправлять стандартный вывод или использовать параметры командной строки для записи в файл, а затем использовать canplayer для воспроизведения записей.

Рисунок 5-4 демонстрирует вид окна Kayak, эквивалентный cansniffer.

Рисунок 5-4 Запись Kayak в файл журнала

Чтобы записать пакеты CAN с помощью Kayak, сначала нажмите кнопку «Play» на вкладке «Log files» ➊. Затем перетащите одну или несколько шин из панели «Projects» в поле «Busses» на вкладке «LogOutput»➋. Чтобы начать или остановить запись нажмите кнопки «Record» или «Stop» в нижней части экрана LogOutput➌. Как только захват ваших пакетов будет завершен, логи должны отобразиться в выпадающем меню «Log directory» (смотрите рисунок 5-5).

Если вы откроете логфайл Kayak, вы увидите нечто вроде фрагмента кода в листинге 5-2. Значения в этом примере не будут напрямую коррелировать со значениями на рисунке 5-4, потому что GUI группирует их по ID, как в cansniffer, но логфайл ведется последовательно, как в candump.

PLATFORM NO_PLATFORM
DESCRIPTION “No description”
DEVICE_ALIAS OBD Port slcan0
(1094.141850)➊ slcan0➋  128#a20001➌
(1094.141863)  slcan0   380#02020000e0007e0e
(1094.141865)  slcan0   388#0110
(1094.144851)  slcan0   110#0000000000000000
(1094.144857)  slcan0   120#f289632003200320

Листинг 5-2: Содержимое лог файла Kayak

Рисунок 5-5: Правая панель настроек вкладки Log files

За исключением некоторых метаданных (PLATFORM, DESCRIPTION и DEVICE_ALIAS) логфайл почти такой же, как и тот, которые записываются пакетом can-utils: ➊ – это временная метка, ➋ – это ваша шина, и ➌ – это ваш идентификатор арбитража и данные, разделенные символом «#». Чтобы воспроизвести захваченные пакеты, щелкните ПКМ по Log Description на правой панели и откройте запись (смотрите рисунок 5-5).

В листинге 5-3 показан логфайл, созданный с помощью candump, с использованием параметра командной строки –l:

(1442245115.027238) slcan0 166#D0320018
(1442245115.028348) slcan0 158#0000000000000019
(1442245115.028370) slcan0 161#000005500108001C
(1442245115.028377) slcan0 191#010010A141000B

Листинг 5-3: лог файл candump

Обратите внимание, что логфайл candump почти идентичен тому, который формирует Kayak (Смотрите рисунок 5-4).

 Анализ пакетов

Теперь, когда мы захватили пакеты, пришло время определить, что делает каждый пакет, чтобы мы могли использовать его для разблокировки или использования CAN-шины. Давайте начнем с простого действия, которое, скорее всего, переключит только один бит, – код для разблокировки дверей – и посмотрим, сможем ли мы найти пакет, который контролирует это событие.

Использование Kayak для поиска средства управленем открытия дверей

На шине CAN очень много шума, поэтому обнаружение однобитного изменения может оказаться очень трудной задачей даже при наличии хорошего сниффера. Но вот универсальный способ определить функцию отдельного CAN-пакета:

  1. Нажмите «Record».
  2. Выполните физическое действие, например, откройте дверь.
  3. Остановите запись.
  4. Нажмите «Playback».
  5. Посмотрите, повторилось ли действие. Например, открылась ли дверь.

Если при нажатии кнопки «Playback» дверь не открылась, возможно, вы что-то сделали не так. Во-первых, вы могли пропустить действие в записи, поэтому попробуйте записать и выполнить действие еще раз. Если вам все еще не удается записать и воспроизвести действие, вероятно, оно привязано к физической кнопке замка, как это часто бывает с дверным замком водительской двери. Во время записи попробуйте открыть пассажирскую дверь. Если не сработало и это, значит команда разблокировки находится либо на CAN-шине, отличной от той, которую вы отслеживаете – вам нужно найти правильную – либо воспроизведение могло вызвать коллизию, что привело к остановке пакета. Чтобы убедиться наверняка, попробуйте провести еще несколько попыток.

Как только у вас появится запись, которая выполняет желаемое действие, используйте метод, показанный на рисунке 5-6, отфильтруйте шум и найдите точный пакет и биты, которые используются для открытия двери через шину CAN.

Продолжайте вдвое уменьшать размер захваченного пакета до тех пор, пока не останется только один, после чего вы сможете определить, какой бит или биты используются для отпирания дверей. Самый быстрый способ сделать это – открыть сниффер и отфильтровать выбранный вами идентификатор арбитража. Откройте дверь, и бит или байт, который изменился, должнен выделиться. Теперь попробуйте открыть задние двери авто и посмотрите, как изменятся байты. Вы должны уметь точно сказать, какой бит должен измениться после открытия каждой двери.

Рисунок 5-6 Диаграмма примера реверсирования

Использование can-utils для поиска контроллера открытия дверей

Чтобы идентифицировать пакеты с помощью can-utils, вы, как отмечалось ранее, должны использовать candump для записи и canplayer для воспроизведения логфайла. Затем вам понадобится текстовый редактор, чтобы сжать файл перед воспроизведением. Когда у вас останется один пакет, с помощью cansend, вы сможете определить, какой байт или биты контролируют целевую операцию. Например, удалая разные половины логфайла, вы можете точно установить идентификатор, который открывает дверь:

slcan0  300   [8]  00 00 84 00 00 0F 00 00

Теперь вы можете редактировать каждый байт и воспроизводить строку, или же можете использовать cansniffer с фильтром +300, чтобы выделить только 300 идентификаторов арбитража и отслеживать, какие байты меняются, когда вы открываете дверь. Например, если байт, который управляет открытием двери, является шестым байтом, (0x0F в нашем примере выше), то мы знаем, что, когда шестой байт равен 0x00 двери открываются, а когда 0x0F – двери закрываются.

Примечание

Этот пример предполагает, что мы выполнили все шаги для идентификации этого конкретного байта, ранее названные в этой главе. Специфика этого действия будет отличатся для каждого автомобиля.

Мы можем проверить наш результат с помощью cansend:

cansend slcan0 300#00008400000F0000

 Если после отправки все двери блокируются, значит мы успешно определили, какие пакеты управляют дверными замками.

Теперь, что происходит, когда вы меняете 0x0F? Чтобы узнать это откройте дверь и на этот раз отправьте 0x01:

cansend slcan0 300#0000840000010000

Обратите внимание, что запирается замок исключительно двери со стороны водителя, все остальные остаются открытыми. Если вы повторите этот процесс с 0x02, заблокируются только передние двери. Повторив это еще раз с кодом 0x03, заблокируются обе двери со стороны водителя и дверь переднего пассажира. Но почему 0x03 управляет именно этими дверьми? Ответ может иметь больше смысла, если вы посмотрите на двоичное представление:

0x00 = 00000000
0x01 = 00000001
0x02 = 00000010
0x03 = 00000011

Первый бит представляет водительскую дверь, а второй – переднюю пассажирскую. Когда бит равен 1, дверь блокируется, когда 0 – открывается. Отправляя 0x0F, вы устанавливаете все биты, которые могут повлиять на дверной замок, на двоичную единицу, тем самым блокируя все двери:

0x0F = 00001111

А как насчет остальных четырех битов? Лучший способ узнать это – просто установить их значение на 1 и проследить за изменениями в автомобиле. Мы уже знаем, что часть сигнала 0x300 относится к дверям, поэтому можно с уверенностью предположить, что оставшиеся четыре бита также относятся к дверям. В противном случае они могут управлять чем-то вроде багажника или капота.

Примечание

Если вы не получаете ответа при переключении бита, возможно, он может вообще не использоваться или просто быть зарезервированным.

Получение показаний тахометра

Получить информацию с тахометра (количество оборотов двигателя в минуту) можно ровно так же, как и отпереть дверь. Диагностические коды сообщают об оборотах двигателя, но их нельзя использовать для настройки отображения оборотов (и что в этом интересного?), поэтому нам нужно выяснить, что использует автомобиль для контроля показаний на комбинации приборов (IC).

Для экономии места значения числа оборотов в минуту не будут отображаться в шестнадцатеричном эквиваленте считывания; вместо этого значение сдвигается так, что 1000 об/мин могут выглядеть как 0xFA0. Это значение часто называют «сдвинутым» (shifted), потому что для выполнения эквивалента умножения или деления в коде разработчики используют битовый сдвиг. Для протокола UDS это значение соответствует следующему:

Что еще хуже, вы не можете отслеживать трафик CAN и запрашивать количество оборотов в минуту, чтобы одновременно искать изменяющиеся значения. Это связано с тем, что автомобили часто сжимают значение оборотов в минуту, используя собственный метод. Несмотря на то, что диагностические значения установлены, они не являются фактическими пакетами или значениями, которые использует автомобиль, поэтому нам нужно найти реальное значение, изменив необработанные пакеты CAN. (Перед тем как делать это обязательно поставьте автомобиль на ручник, или даже поднимите автомобиль над землей, чтобы он внезапно не раздавил вас).

Выполните те же шаги, которые вы проводили для поиска элемента управления открытием двери:

  1. Нажмите Record.
  2. Нажмите педаль газа.
  3. Остановите запись.
  4. Нажмите Playback.
  5. Посмотрите, не сдвинулся ли тахометр.

Вы, вероятно, обнаружите, что во время этого теста на приборке будут мигать и сходить с ума лампочки, это все потому, что этот пакет делает гораздо больше, чем просто отпирает дверь машины. Не обращайте внимания на все мигающие предупреждения и лампочки и следуйте блок-схеме, показанной на рисунке 5-6, чтобы найти идентификатор арбитража, ответственного за изменение тахометра. На этот раз у вас будет намного больше шансов словить коллизию, нежели, когда вы пытались открыть дверь, в данном случае все намного масштабней. Следовательно, вам, скорее всего, придется записывать и воспроизводить намного больше трафика. (Помните о преобразованиях значений, упомянутых ранее, и имейте в виду, что в этом идентификаторе арбитража, вероятно, контролировать сообщаемую скорость будет не один байт).

Начинаем работать с Kayak

Чтобы немного упростить работу с нахождением идентификаторов арбитража, которые управляют тахометром, вместо can-utils мы будем использовать Kayak. Опять же, убедитесь в полной безопасности, автомобиль должен находится в неподвижном состоянии на открытой местности с опущенным ручником. Начните запись и дайте двигателю хорошие обороты. Затем остановите запись и воспроизведите данные. Указатель оборотов двигателя должен двигаться; в противном случае, возможно, вы выбрали не ту шину, и вам нужно найти верную, как описано ранее в этой главе.

Как только у вас будет реакция, которую вы ожидаете от транспортного средства, повторите процесс уменьшения вдвое, используемый ранее для поиска идентификаторов разблокировки дверей, с некоторыми дополнительными опциями Kayak.

Интерфейс воспроизведения Kayak позволяет вам установить воспроизведение в бесконечном цикле и, что более важно, установить «входные» и «выходные» пакеты (смотрите рисунок 5-7). Ползунок отображает количество захваченных пакетов. Используйте ползунок для выбора пакета, который вы хотите запускать и останавливать во время воспроизведения. С помощью ползунка вы можете быстро перейти к середине или другому разделу записи, что упрощает воспроизведение половины раздела.

Рисунок 5-7 Интерфейс воспроизведения Kayak

Что касается тестирования, теперь вы не сможете отправить только один пакет, как это было при попытке разблокировать дверь, потому что автомобиль сообщает о своей скорости постоянно. Чтобы подавить этот шум, вам следует сообщать данные чаще, чтобы постоянно избегать коллизий. Например, если вы воспроизводите свои пакеты сразу после воспроизведения реального пакета, то последнее увиденное обновление будет измененным. Снижение шума на шине приводит к меньшему количеству коллизий и более чистым демонстрациям. Если вы сможете отправить ваш фальшивый пакет сразу после реального пакета, зачастую вы получите результат лучше, чем просто переполненная шина.

Чтобы с помощью can-utils отправлять пакеты непрерывно, вы можете использовать цикл while с cansend или cangen. (При использовании диалогового окна Send Frame для передачи пакетов обязательно установите флажок напротив Interval).

Создание фонового шума с помощью симулятора приборной панели

Симулятор комбинации приборов (ICSim) – один из самых полезных инструментов, созданных Open Garages, группой, которая способствует открытому сотрудничеству между механиками, специалистами по настройке производительности и аудиторами безопасности (см. приложение А). ICSim – это программная утилита, разработанная для генерации нескольких ключевых сигналов CAN c целью обеспечения большого количества, казалось бы, «нормального» фонового шума CAN – по сути она разработана для того, чтобы вы могли практиковать реверсирование шины CAN без необходимости возиться с автомобилем. (ICSim разработана исключительно под Linux так как в своей работе полагается на виртуальные устройства CAN). Методы, которые вы изучите, играя с ICSim, будут напрямую переведены на ваши целевые машины. ICSim был разработан как безопасный способ познакомится с реверсированием CAN, чтобы переход к реальному автомобилю был как можно более плавным.

Настройка ICSim

Возьмите исходный код ICSim с https://github.com/zombieCraig/ICSim и следуйте файлу README, прилагаемому к программе, чтобы скомпилировать программное обеспечение. Перед запуском ICSim в файле README вы должны найти пример скрипта с именем setup_vcan.sh, который вы можете запустить, чтобы настроить интерфейс vcan0 для использования ICSim.

ICSim загружается с двумя компонентами, icsim и controls, которые взаимодействуют друг с другом по шине CAN. Чтобы использовать ICSim, сначала загрузите приборную панель в устройство vcan следующим образом:

$ ./icsim vcan0

В ответ вы должны увидеть приборную панель ICSim с указателями поворотов, спидометром и изображением автомобиля, которое будет использоваться для показа блокировки и разблокировки дверей автомобиля (см. рисунок 5-8).

Рисунок 5-8 Приборная панель ICSim

Приложение icsim прослушивает исключительно сигналы CAN, поэтому при первой загрузке вы не должны увидеть никакой активности. Для управления симулятором загрузите панель управления CANBus следующим образом:

$ ./controls vcan0

Должна появиться панель управления CANBus, показанная на рисунке 5-9.

Рисунок 5-9 Интерфейс панели управления ICSim

Окно похоже на игровой контроллер; фактически, вы можете подключить игровой USB-контроллер, и он должен поддерживаться ICSim. (На момент написания книги вы также можете использовать инструменты sixad для подключения контроллера PS3 через Bluetooth). Вы можете использовать контроллер для управления ICSim тем же способом, что и управление автомобилем на игровой приставке. Также у вас есть возможность управлять программой с помощью соответствующих клавиш на клавиатуре (см. рисунок 5-9).

Примечание

После загрузки панели управления вы должны увидеть работу спидометра, скорость должна быть 0 миль в час. Если стрелка немного покачивается, значит, все работает. Управляющее приложение записывает только шину CAN и не имеет другого способа связи с icsim. Единственный способ управлять виртуальным автомобилем – посредством CAN.

Основные элементы управления на панели управления CANBus:

Ускорение (Стрелка вверх) Нажмите эту кнопку, чтобы увеличить скорость. Чем дольше вы удерживаете стрелку вверх, тем быстрее едет виртуальный автомобиль.

Поворот (Стрелки влево/вправо) Удерживайте кнопку поворота для включения указателей поворота.

Блокировка (Левый Shift), разблокировка (Правый Shift) Для этих действий необходимо нажатие двух кнопок одновременно. Удерживая левый Shift, нажмите кнопку (A, B, X или Y), чтобы заблокировать соответствующую дверь. Удерживая правый Shift, нажмите одну из кнопок, чтобы открыть соответствующую дверь. Если вы удерживаете левый Shift, а затем нажимаете правый Shift, он разблокирует все двери. Если вы удерживаете правый Shift и нажмете левый Shift, вы заблокируете все двери.

Чтение трафика шины CAN на ICSim

Когда вы уверитесь, что все работает как следует, запустите ваш сниффер и посмотрите на трафик шины CAN, как показано на рисунке 5-10. Попробуйте определить, какие пакеты управляют транспортным средством, и создайте скрипты для управления ICSim без использования панели управления.

Большая часть изменяющихся данных, которые вы увидите на рисунке 5-10, вызваны файлом воспроизведения реальной шины CAN. Чтобы определить подходящие пакеты, вам нужно будет отсортировать сообщения. С ICSim будут работать все методы воспроизведения и отправки пакетов, так что вы сможете проверить свои выводы.

Рисунок 5-10 Скрин окон ICSim

Изменение уровня сложности ICSim

Одна из замечательных возможностей ICSim заключается в том, что вы можете испытать свои знания, усложнив поиск целевого CAN-трафика. ICSim поддерживает 4 уровня сложности – с 0 до 3; по умолчанию стоит уровень 1. Уровень 0 – это супер простой пакет CAN, который выполняет намеченную операцию без какого-либо фонового шума, в то время как уровень 3 рандомизирует все байты в пакете. Чтобы симулятор выбирал разные идентификаторы и целевые позиции байтов, используйте опцию случайного выбора ICSim:

./icsim -r vcan0
Using CAN interface vcan0
Seed: 1419525427

Эта опция выводит на экран консоли рандомное начальное значение.

Передайте это значение в панель управления CANBus вместе с выбранным уровнем сложности:

./controls -s 1419525427 -l 3 vcan0

Вы также можете воспроизвести или поделиться определенным начальным значением. Если вы найдете значение, которое вам понравится, или если вы захотите посоревноваться с друзьями, чтобы узнать, кто первым сможет расшифровать пакеты, запустите ICSim с заданным начальным значением, например:

./icsim -s 1419525427 vcan0

Затем запустите панель управления CANBus, используя то же начальное значение, чтобы синхронизировать рандомизированную панель управления с ICSim. Если исходные значение не совпадут, они не смогут взаимодействовать.

При первом использовании ICSim вам может потребоваться некоторое время, чтобы найти нужные пакеты, но после нескольких попыток вы научитесь быстро определять ваши целевые пакеты.

Попробуйте выполнить следующие задачи в ICSim:

  1. Создайте «аварийные огни». Заставьте мигать оба указателя поворота одновременно.
  2. Создайте команду, которая будет блокировать только две задние двери.
  3. Установите спидометр как можно ближе к 220 милям в час.

Реверсирование CAN-шины с помощью OpenXC

В зависимости от вашего автомобиля одним из решений для реверс-инжениринга шины CAN является OpenXC, открытый стандарт оборудования и программного обеспечения, который переводит проприетарные протоколы CAN в удобный для чтения формат. OpenXC была инициирована Ford Motor Company – и когда я пишу это, OpenXC поддерживается только Ford – но он может работать с любым автопроизводителем, который поддерживает OpenXC. (Посетите http://openxcplatform.com/ для получения информации о том, как приобрести готовый ключ).

В идеале, открытые стандарты для данных CAN, такие как OpenXC, устранят необходимость наличия большого количества приложений для реверсинга трафика CAN. Если бы остальная часть автомобильной промышленности согласовала стандарт, определяющий, как работают их автомобили, это значительно улучшило бы способность автовладельцев чинить свои автомобили с использованием инновационных инструментов.

Перевод сообщений CAN-шины

Если автомобиль поддерживает OpenXC, вы можете подключить интерфейс автомобиля (VI) к шине CAN, и этот VI должен преобразовывать сообщения CAN, и отправлять их на ваш компьютер так, чтобы вы могли читать поддерживаемые пакеты без необходимости реверсить их. Теоретически OpenXC должен разрешать доступ к любому CAN-пакету через стандартный API. Этот доступ может быть только для чтения, или позволит вам передавать пакеты. Если бы в конечном счете OpenXC поддерживали больше автопроизводителей, он мог бы предоставить сторонним инструментам более прямой доступ к авто, чем они имели бы через стандартные диагностические команды UDS.

Примечание

OpenXC поддерживает Python и Android и включает такие инструменты как openxc-dump для отображения активности CAN.

Поля по умолчанию из API OpenXC:

• accelerator_pedal_position

• brake_pedal_status

• button_event (typically steering wheel buttons)

• door_status

• engine_speed

• fuel_consumed_since_last_restart

• fuel_level

• headlamp_status

• high_beam_status

• ignition_status

• latitude

• longitude

• odometer

• parking_brake_status

• steering_wheel_angle

• torque_at_transmission

• transmission_gear_position

• vehicle_speed

• windshield_wiper_status

Различные автомобили могут поддерживать сигналы, отличные от перечисленных выше, или вообще не поддерживать сигналы.

OpenXC также поддерживает вывод трассировки JSON для записи маршрута транспортного средства. JSON предоставляет общий формат данных, который легко использовать с большинством других современных языков, как показано в листинге 5-4:

{“metadata”: {
    “version”: “v3.0”,
    “vehicle_interface_id”: “7ABF”,
    “vehicle”: {
        “make”: “Ford”,
        “model”: “Mustang”,
        “trim”: “V6 Premium”,
        “year”: 2013
    },
    “description”: “highway drive to work”,
    “driver_name”: “TJ Giuli”,
    “vehicle_id”: “17N1039247929”
}

Листинг 5-4: Простой вывод файла JSON

Обратите внимание на то, как определения в JSON упрощают чтение и интерпретацию как людьми, так и языком программирования. Приведенный выше листинг JSON является файлом определений, поэтому запрос API будет еще меньше. Например, при запросе поля steering_wheel_angle, переведенные CAN-пакеты будут выглядеть следующим образом:

{“timestamp”: 1385133351.285525, “name”: “steering_wheel_angle”, “value”: 45}

Вы также можете взаимодействовать с OpenXC через OBD следующим образом:

openxc-diag –message-id 0x7df –mode 0x3

Запись в шину CAN

Если вы хотите записать обратно в шину, вы можете использовать что-то вроде следующей строки, которая записывает угол поворота руля обратно в автомобиль. Но вы обнаружите, что устройство повторно отправит на шину CAN только несколько сообщений.

openxc-control write –name steering_wheel_angle –value 42.0

Технически OpenXC также поддерживает необработанные записи CAN, например:

openxc-control write –bus 1 –id 42 –data 0x1234

Это возвращает нас от переведенного JSON к взлому необработанного CAN, описанному ранее в этой главе. Однако, если вы хотите написать приложение или встроенные графический интерфейс, чтобы только читать и влиять на поведение вашего авто, и у вас есть новый Ford, то это может быть самым быстрым путем к достижению этих целей.

Взлом OpenXC

Если вы уже реверсили CAN сигнал, вы можете создать свою собственную прошивку VI OpenXC. Компиляция собственной прошивки означает, что у вас более не будет никаких ограничений, поэтому вы можете читать и записывать все, что захотите, и даже сможете создавать «неподдерживаемые» сигналы. Например, вы можете создать сигнал для remote_engine_start (удаленного запуска двигателя) и добавить его в собственную прошивку, чтобы обеспечить простой интерфейс для запуска вашего автомобиля. Ура, открытый код!

Рассмотрим сигнал engine_speed (скорость двигателя). Листинг 5-5 устанавливает базовую конфигурацию для вывода сигнала engine_speed. Мы будем отправлять данные о количестве оборотов двигателя в минуту с двухбайтовым идентификатором сообщения 0x110, начиная со второго байта.

{  “name” : “Test Bench”,
     “buses”: {
        “hs”: {
            “controller”: 1,
            “speed”: 500000
        }
   },
    “messages”: {
       “0x110”: {
          “name”: “Acceleration”,
          “bus”, “hs”,
          “signals”: {
             “engine_speed_signal”: {
                “generic_name”: “engine_speed”,
                “bit_position”: 8,
                “bit_size”: 16
             }
          }
       }
   }
}

Листинг 5-5 Простой файл конфигурации OpenXC для определения engine_speed

Файлы конфигурации OpenXC, которые вы хотите изменить, хранятся в JSON. Сначала мы определим шину, создав файл JSON с помощью текстового редактора. В этом примере мы создадим конфигурацию JSON для сигнала на высокоскоростной шине со скоростью 500 Кбит/с.        

 После определения конфигурации JSON используйте следующий код, чтобы скомпилировать его в файл CPP, который затем можно будет скомпилировать в прошивку:

openxc-generate-firmware-code –message-set ./test-bench.json > signals.cpp

Затем перекомпилируйте прошивку VI с помощью следующей команды:

fab reference build

Если все прошло успешно, на выходе у вас должен быть .bin файл, который можно загрузить на ваше OpenXC-совместимое устройство. По умолчанию шина настроена на режим чтения/записи, который по умолчанию устанавливает встроенное ПО в ограниченный режим только для чтения, при условии, что сигналы или вся шина настроены на поддержку записи. Чтобы настроить их, при определении шины вы можете добавить raw_can_mode или raw_writable и установить для них значение на true.

Создав свои собственные файлы конфигурации OpenXC, вы можете обойти ограничения, установленные в предварительно выпущенной прошивке, и добавить поддержку других, помимо Ford, автомобилей. В идеале OpenXC начнут поддерживать и другие производители, но этот процесс не будет быстрым, а ограничения шины настолько строги, что вы, вероятно, захотите использовать кастомную прошивку.

Фаззинг шины CAN

Фаззинг шины CAN может быть хорошим способом найти недокументированные диагностические методы или функции. Фаззинг использует случайный, похожий на выстрел дробовика, подход к реверсированию. При фаззинге вы отправляете на вход случайные данные, ожидая некое необыкновенное поведение, которое в случае транспортного средства может быть физическими изменениями, такими как сообщения IC, или сбоями некоторых компонентов, например, их выключение или перезагрузка.

Хорошая новость заключается в том, что сделать CAN-фаззер не сложно. Плохая новость в том, что он редко оказывается полезным. Необходимые пакеты часто являются частью набора пакетов, используемых для того, чтобы вызвать конкретное изменение, например, диагностическую службу, которая может активироваться только после того, как ей будет передан успешный маркер безопасности, поэтому трудно сказать, на каком пакете стоит сфокусироваться при фаззинге. Кроме того, некоторые пакеты CAN становятся видимыми только в случае движения автомобиля, что очень опасно. Тем не менее, не исключайте фаззинг как потенциальный метод атаки, потому как вы можете использовать его для обнаружения недокументированных сервисов или сбоев целевого компонента, который вы хотите подменить.

Некоторые снифферы напрямую поддерживают фаззинг – функцию, обычно присутствующую в разделе передачи и представляющей собой способность утилиты передавать пакеты с увеличением байтов в разделе данных. Например, в случае SocketCAN вы можете использовать cangen для генерации случайного трафика CAN. Некоторые другие решения для сниффинга CAN с открытым исходным кодом позволяют легко создавать скрипты или программировать на таких языках, как Python.

Хорошей отправной точкой для начала фаззинга будет изучение команд UDS, особенно «недокументированных» команд производителя. При фаззинге недокументированных режимов UDS мы обычно ищем любой тип ответа от неизвестного режима. Например, при нацеливании на UDS диагностику ЭБУ вы можете отправить случайные данные на ID 0x7DF и получить ошибку от неожиданного режима. Однако, если вы используете брутфорс инструменты, такие как CaringCaribou, часто есть более чистые способы сделать то же самое, например, мониторинг или реверсирование самих диагностических инструментов.

Устранение неполадок

Шина CAN и ее компоненты являются отказоустойчивыми, что ограничивает ущерб, который вы можете нанести при реверсировании шины. Однако, что-то таки да может пойти не так, когда вы проводите фаззинг шины CAN или воспроизводите большой объем данных CAN обратно в действующей сети шины CAN. Далее будут представлены несколько распространенных проблем и их решения.

Мигающие индикаторы IC

Индикаторы IC обычно мигают при отправке пакетов на шину CAN, и зачастую их можно сбросить, перезапустив автомобиль. Если перезапуск авто по-прежнему не устраняет мигание световых индикаторов, попробуйте переподключить аккумулятор. Если и это не помогло, убедитесь в том, что аккумулятор должным образом заряжен, поскольку низкий заряд аккумулятора также может стать причиной мигающих индикаторов IC.

Автомобиль не заводится

Если ваш автомобиль заглох, и больше не заводится, чаще всего, это является следствием того, что, работая с CAN, вы разрядили его аккумулятор. На самом деле манипуляции с CAN могут разрядить аккумулятор намного быстрее, чем вы думаете. Чтобы завести автомобиль, зарядите аккумулятор, или поставьте запасной, если такой имеется.

            Если автомобиль по-прежнему не заводится, попробуйте вытащить и снова поставить предохранитель. Найдите предохранители двигателя по руководству к использованию вашего автомобиля и переподключите те, которые на ваше мнение являются «виновниками». Скорее всего, ваш предохранитель остался целым, поэтому просто вытащите его и вставьте обратно. Выбор предохранителей будет зависеть от типа вашего автомобиля, но, если и после этого ваш двигатель не будет заводиться, вам нужно будет провести более детальный осмотр транспортного средства. Ищите главные предохранители вокруг основной электроники. Определите компонент, вызывающий проблему, используя метод исключения.

Автомобиль не глушится

Вы можете столкнуться с тем, что банально не можете заглушить свой автомобиль. Это плохая, но, к счастью, редкая ситуация. Во-первых, убедитесь, что вы не зафлудили CAN-шину трафиком; если да, остановитесь и отключитесь от CAN-шины. Если вы отключились от шины, а автомобиль по-прежнему не глушиться, вам нужно будет вытаскивать предохранители, пока он не заглохнет.

Автомобиль ведет себя бесконтрольно

Такое происходит только в том случае, если вы вводите пакеты в движущийся автомобиль, что само по себе является ужасной идеей, никогда не делайте подобного! Если вам необходимо проверить автомобиль в движении, поднимите его на подъемнике.

Блокировка

Реверс-инжениринг шины CAN никогда не должен привести к полному отказу – то есть к тому, что автомобиль ломается полностью, настолько, что вы ничего не можете с ним сделать. Чтобы заблокировать автомобиль, вам необходимо возиться с прошивкой, что выполняется на ваш страх и риск и приводит к прекращению действия гарантии на автомобиль.

Резюме

В этой главе вы узнали, как в беспорядке проводов под приборной панелью находить провода CAN, и как использовать такие инструменты как cansniffer и Kayak для сниффинга трафика и определения того, что делают разные пакеты. Вы также узнали, как группировать трафик CAN, чтобы идентифицировать изменения легче, чем при использовании более традиционных инструментов анализа пакетов, таких как Wireshark.

  Теперь вы должны уметь просматривать трафик CAN и определять изменяющиеся пакеты. После идентификации пакетов вы можете писать программы для их передачи, создавать файлы Kayak, чтобы определять их, или создавать переводчики для OpenXC, чтобы упростить использование ключей-брелоков для взаимодействия с вашим автомобилем. Теперь у вас есть все инструменты, необходимые для идентификации и управления компонентами вашего автомобиля, работающими по CAN.

6 

Взлом ЭБУ 

by Dave Blundell 

Автомобиль обычно имеет до дюжины или более электронных контроллеров, большинство из которых объединены в сеть для связи друг с другом. Таких компьютеризированных устройств много, например, электронный блок управления или блок управления двигателем (ECU), блок управления трансмиссией (TCU) или модуль  управления трансмиссией (TCM).  

Хотя в формальной обстановке эти термины могут иметь свои определенные значения, на практике аналогичные термины часто используются взаимозаменяемо. То, что для одного производителя может быть TCU, для другого будет TCM, хотя оба этих электронных контроллера выполняют одинаковые или очень похожие функции.  

В большинстве автомобильных модулей управления предусмотрены меры, предотвращающие изменения их кода и работы; они варьируются от очень сложных до смехотворно простых. Вы не узнаете, с чем имеете дело, пока не исследуете конкретную систему. В этой главе мы более подробно рассмотрим конкретные механизмы безопасности, но сначала рассмотрим стратегии получения доступа к этим системам. Затем, в главе 8, мы рассмотрим некоторые более специфические методы взломы ECU, например, глитч-атаки и дебаггинг. Векторы атак на ЭБУ делятся на три класса: 

Атаки в лоб (front door) Взлом заводского механизма доступа 

Бэкдоры Применение более традиционных подходов к взлому оборудования 

Эксплоиты Обнаружение вариантов непреднамеренного доступа 

Мы рассмотрим каждый из этих классов атак, а затем проанализируем данные, которые с их помощью вам удастся получить. Стоит помнить, что, хотя цель взлома ЭБУ и других модулей часто одна и та же – получение возможности перепрограммирования и изменения поведения, маловероятно, что для всех модулей будет один универсальный “ключ”. Однако производители оригинального оборудования, как правило, не очень изобретательны и редко меняют свой подход, поэтому понимание одного контроллера, вероятно, будет универсально и применимо к аналогичным моделям от того же производителя. Кроме того, немногие из современных автопроизводителей разрабатывают собственные компьютеры с нуля, вместо этого отдавая предпочтения лицензированию готовых решений от третьих сторон, таких как Denso, Bosch, Continental и других. В следствии такой методологии проектирования довольно часто можно увидеть, что автомобили разных производителей часто используют очень похожие компьютерные системы, которые были разработаны на основе решений от одних и тех же поставщиков. 

Атаки в лоб 

Согласно стандарту OBD-ll, вы можете перепрограммировать автомобили через разъем OBD-ll, а реверс-инжениринг исходного метода программирования является гарантированным методом атаки. Мы рассмотрим J2534 и KWP2000 как примеры общих протоколов программирования. 

J2534: стандартизированный API связи транспортных средств 

Стандарт SAE J2534-1, или просто J2534, был разработан для обеспечения возможности взаимодействия между поставщиками цифровых инструментов за счет использования API J2534, который описывает рекомендуемый способ связи Microsoft Windows и автомобиля. (Вы можете приобрести API J2534 от SAE по адресу: http://standards.sae.org/j2534/1_200412/)До принятия стандарта J2534 для связи с автомобилем каждый поставщик программного обеспечения создавал собственное запатентованное оборудование и драйверы с целью выполнения компьютеризированного ремонта. Поскольку эти проприетарные инструменты не всегда были доступны для небольших магазинов, EPA в 2004 году обязало принять стандарт J2534, чтобы позволить независимым магазинам получить доступ к тем же специализированным компьютерным инструментам, что используются дилерскими центрами. J2534 представил серию библиотек DLL, которые сопоставляют стандартные вызовы API с инструкциями, необходимыми для связи с транспортным средством, тем самым позволяя нескольким производителям выпускать программное обеспечение, предназначенное для работы с J2534-совместимым оборудованием. 

Использование инструментов J2534 

Инструменты J2534 обеспечивают удобный способ наблюдения за EOM-инструментами, взаимодействующими с бортовыми компьютерами. Производители часто используют J2534 для обновления микропрограмм компьютеров, также, иногда для предоставления мощного диагностического программного обеспечения. Наблюдая и собирая информацию, которой обмениваются с автомобилем с помощью J2534, вы можете увидеть, как EOM (Original Equipment Manufacturer) выполняют определенные задачи, которые могут предоставить вам информацию, необходимую для открытия “входной двери”.  

При использовании инструментов J2534 для атаки на системы транспортных средств, основная идея заключается в наблюдении, записи, анализе и расширении функциональности. Разумеется, первым шагом является получение и настройка приложения J2534 и соответствующего ему аппаратного интерфейса для определенной задачи, за которой вы хотите наблюдать. Следующим шагом, после установки, будет наблюдение и запись связей. Это делается для использования инструментов J2534 с целью выполнения определенных действий, например, обновления параметра конфигурации. 

Существует два основных способа наблюдения за транзакциями J2534: наблюдение за вызовами API J2534 на ПК с использованием DLL библиотек, или наблюдение за фактическим трафиком шины с помощью отдельного средства сниффинга для сбора данных. 

Инструменты J2534 являются ключом к перехвату протоколов, встроенных в заводские системы автомобиля, и являются одним из основных способов атак в лоб. Успешный анализ этой коммуникации предоставит вам данные, необходимые для доступа к системам автомобиля, так, как это делают производители оригинального оборудования. Это также позволит вам писать собственные приложения с полным доступом к чтению и перепрограммирования систем, что, в свою очередь, позволит напрямую связываться с автомобилем без необходимости использования интерфейса J2534 или программного обеспечения J2534 от производителя оборудования. 

J2534 Shim DLLs 

Shim J2534 представляет собой программный интерфейс J2534, который подключается к физическому интерфейсу J2534, а затем передает и регистрирует все получаемые команды. Этот фиктивный интерфейс предоставляет собой своего рода атаку “человек посередине”, который позволяет записывать все вызовы API между приложением J2534 и целью. Затем вы можете изучить лог команд, чтобы определить фактические данные, которыми обмениваются интерфейс J2534 и устройство. 

Чтобы найти shim J2534 с открытым исходным кодом, поищите J2534-logger на code.google.com. Там же вы можете найти предварительно скомпилированные двоичные файлы. 

J2534 и сниффер 

Также вы можете использовать J2534 для генерации интересного трафика, который затем можно будет наблюдать и записывать с помощью сниффера. Здесь нет никакого волшебства: это просто отличный пример того, как генерировать сочные пакеты, которые иначе было бы сложно перехватить. (Для получения дополнительной информации о мониторинге сетевого трафика смотрите главу 5). 

KWP2000 и другие ранние протоколы 

До J2534 было много программируемых ЭБУ и других блоков управления, таких как Keyword Protocol 2000 (KWP2000 или ISO14230). С точки зрения сетевой модели OSI, в первую очередь это был протокол приложения. Его можно было использовать поверх CAN или ISO9141 в качестве физического уровня. Вы найдете огромное количество инструментов для прошивки KWP2000, которые взаимодействуют с ПК через последовательный/USB-последовательный интерфейс и поддерживают диагностику и прошивку с использованием этого протокола с помощью онлайн поиска. (Подробнее о KWP2000 смотрите главу 2). 

Использование подходов к атакам в лоб: алгоритмы seed-key 

Теперь, когда мы обсудили, как легитимные инструменты используют атаки в лоб, пришло время извлечь выгоду из этого вектора атаки, научившись управлять образным “замком на воротах”. Для этого мы должны понять, как устроен алгоритм, который встроенный контроллер использует для аутентификации пользователей; в большинстве случаев это алгоритм seed-key. Алгоритмы seed-key обычно генерируют псевдослучайное число и, прежде чем разрешить доступ, ожидают определенного ответа или ключа для каждого начального числа. Типичная верификация может проходить примерно так:  

ECU seed: 01 C3 45 22 84 
Tool key: 02 3C 54 22 48 

Или так: 

ECU seed: 04 57 
Tool key: 05 58 

К сожалению, стандартного алгоритма seed-key не существует. У вас может быть 16-разрядное начальное число и 16-разрядный ключ, 32-разрядное начальное число и 16-разрядный ключ, или 32-разрядное начальное число и 32-разрядный ключ. Алгоритм, который генерирует ключ из заданного начального числа, также варьируется от платформы к платформе. Большинство алгоритмов представляют собой комбинацию простых арифметических операций и одного или нескольких значений, используемых как часть вычислений. Для выяснения этих алгоритмов с целью предоставления вам доступа к ЭБУ есть несколько методов: 

Дополнительную информацию о реверс-инжениринге алгоритмов начальных ключей, используемых General Motors, вы можете найти на https://pcmhacking.net/forums/viewtopic.php?f=4&t=1566&start=10, а об алгоритмах, используемых VAG MED9.1 на http://nefariousmotorsports.com/forum/index.php?topic=4983.0

Бэкдор атаки 

Иногда атаки в лоб атаки могут оказаться слишком хорошими, и от этого запутанными; у вас может не быть подходящих инструментов, или “замок” окажется слишком сложным. Но не отчаивайтесь – помните, что автомобильные модули управления – это встроенные системы, поэтому вы можете использовать все обычные методы взлома оборудования. Фактически, использование более прямых аппаратных подходов с бэкдором часто имеет больше смысла, чем попытки реверс-инжениринга замков дверей, установленных на заводе, и уж тем более при попытках реверс-инжениринга двигателя. Если вы можете получить дамп модуля, часто вы можете проанализировать его, чтобы выяснить, как работают, к примеру, замки дверей. Первым шагом в атаке через аппаратный бэкдор – это анализ печатной платы. 

При реверсировании печатной платы любой системы первым делом вы должны начать с самых крупных микросхем. Эти более крупные процессоры и микросхемы памяти, вероятно, будут самыми сложными. Было бы отлично, если бы вы составили список номеров деталей, которые вбили бы в Google, datasheet.com или чем-то подобном, чтобы получить копию таблицы данных. Иногда можно встретить интегральные схемы специального назначения (ASIC) и одноразовые микросхемы, особенно в старых ЭБУ, которые будут более сложными, чем стандартные детали. Во многих случаях вам придется делать выводы о функциях этих частей на основе того, как они связаны с идентифицируемыми частями. 

Очень важно не забывать о микросхемах памяти – SRAM, EEPROM, FlashROM, одноразово программируемые ПЗУ, последовательная EEPROM, последовательная флеш-память, NVSRAM и так далее. Тип используемой памяти сильно различается от одной платформы к другой; все перечисленные выше разновидности были найдены на самых разных компьютерах. В более свежих разработках меньше шансов обнаружить параллельную память, и больше шансов найти там вместо нее последовательные микросхемы. У новых микроконтроллеров вероятность наличия хотя-бы какой-либо внешней памяти очень низкая, поскольку за последнее время их внутренняя емкость флеш-памяти резко возросла. Любую микросхему с энергонезависимой памятью можно демонтировать (с печатной платы), прочитать, а затем заменить. В главе 8 более подробно рассматривается реверс-инжениринг печатной платы. 

Эксплоиты 

Хотя, возможно, это всего лишь еще один пример бэкдора, эксплоиты заслуживают особого внимания. Вместо того, чтобы разбирать компьютер, эксплоиты предлагают ввод в систему тщательно созданных входных данных, выходящих за рамки нормальной работы. Обычно, фундаментом для разработки эксплоита становятся баги или какие-то проблемы. Такие баги могут вызвать сбой системы, ее перезагрузку или выполнение нежелательных действий с точки зрения пользователя автомобильного средства. Некоторые из ошибок предоставляют возможность для проведения атак на переполнение буфера (buffer overflow), которые открывают двери для захвата уязвимого устройства путем простой подачи неожиданных входных данных. Толково созданный набор входных данных вызывает ошибку, которая затем заставляет устройство выполнять код, предоставленный злоумышленником, вместо того, чтобы вызывать обычное состояние ошибки.  

Однако не все ошибки можно превратить в эксплоиты – некоторые баги только и могут, что вызвать некоторые проблемы или завершить работу основных систем. И хотя баги обычно обнаруживаются случайно, большинство эксплоитов требует к себе щепетильного отношения. Очень вряд ли, что вы сможете превратить известную ошибку в эксплоит, не имея при этом никаких знаний о системе, обычно получаемых в результате анализа их прошивки. Чтобы написать необходимый код, вам, как минимум, потребуются базовые знания архитектуры. Как правило, эти знания будут получены в следствии исследования, проведенного перед, непосредственно, написанием эксплоита. 

Найти ошибки, которые являются подходящими векторами атаки, трудно. И часто так же сложно написать для них эксплоиты, поэтому эксплоиты, основанные на багах – довольно редкое зрелище. Хотя глупо сбрасывать со счетов актуальность эксплоитов, другие методы, представленные здесь и в главе 8, в большинстве случаев являют собой гораздо более практичные пути к пониманию и перепрограммированию автомобильных систем.  

Реверсирование автомобильной прошивки 

Взлом автомобильного модуля управления в достаточной мере, чтобы получить его текущую прошивку и конфигурацию, на самом деле только начало приключения. На данный момент у вас, вероятно, имеется от 4 Кб до 4 Мб необработанного машинного кода со смесью различных параметров и фактического кода, который формирует программу, готовую для ее запуска процессором. Допустим, у вас есть двоичный blob-объект прошивки, полученный в результате одного из взломов, описанных в этой или последующих главах книги. Так вот, вам нужно дизассемблировать этот двоичный файл. 

Во-первых, вы должны знать, для какой микросхемы предназначен этот бинарный файл. В интернете есть несколько бесплатных декомпиляторов для разных чипов. В противном случае вы можете отдать немного своих кровных и купить IDA Pro, который поддерживает намного большее количество чипов. Эти тулзы преобразуют шестнадцатеричные значения двоичного кода в инструкции ассемблера. Следующий этап – выяснить, что вам конкретно нужно.  

Когда вы начинаете анализировать необработанные данные, понимание, на высоком уровне, функций устройств, которые вы подвергаете обратному проектированию, будет ключом к пониманию того, что искать и на что смотреть. Для начала вы можете проследить за несколькими “дорожками”, или подсказками; эти дорожки почти гарантировано приведут вас к интересному, и главное полезному материалу. Далее мы рассмотрим несколько конкретных примеров того, как использовать общие функции автомобильного контроллера, чтобы получить представление об их работе, что, уж надеюсь, позволит нам изменить их поведение. 

Система самодиагностики 

Каждый контроллер двигатель имеет систему самодиагностики, которая обычно отслеживает наиболее важные функции двигателя, и анализ этого – лучший способ понять устройство встроенного ПО. Хорошим первым шагом в дизассемблировании будет определение места нахождения этих процедур. Это даст вам представление о ячейках памяти, задействованных во всех датчиках и функциях, которые проверяются на наличие ошибок. Любой современный автомобиль должен поддерживать пакеты OBD-ll, которые стандартизируют сообщаемые диагностические данные. Даже контроллеры, созданные до стандартов OBD-ll, могут сообщать о неисправностях. В некоторых есть система, в которой аналоговый код закорочен на массу, из-за чего загорается либо внутренний светодиод, либо индикатор “проверьте двигатель”. Например, зная, что код 10 относится к неисправному датчику температуры забираемого воздуха, означает, что вы можете найти фрагмент кода, который устанавливает код ошибки 10, что поможет вам определить внутренние переменные, связанные с датчиком температуры воздуха. 

Для более подробной информации об использовании диагностики смотрите главу 4. 

Библиотечные процедуры 

Возможность изменить поведение блока управления часто является одной из основных целей реверс-инжениринга прошивки ЭБУ, а идентификация данных, используемых контроллером – важным шагом в этом процессе. Большинство ЭБУ для выполнения рутинных задач, связанных с кодом, имеют набор библиотечных функций. Поскольку они могут привести вас напрямую к интересующим параметрам, библиотечные функции, используемые для поиска в таблицах, заслуживают определения на ранних стадиях реверс-инжениринга. Каждый раз при использовании таблицы для получения результата вызывается функция. Вызов функций этого типа – одни из самых частых, поэтому их легко обнаружить.  

Обычно каждый тип данных, хранящихся в ЭБУ – одномерный массив байтов; двумерный массив слов; трехмерный массив неподписанных и подписанных значений с плавающей запятой; и так далее – имеет уникальную справочную функцию. При вызове каждой подпрограммы поиска, в таблицу необходимо передать, как минимум, индекс (или начальный адрес) и переменные оси. Часто процедуры поиска в таблице можно повторно использовать для передачи информации о структуре таблицы, например, о количестве имеющихся строк и столбцов.  

Данные калибровки обычно хранятся в памяти программ вместе с процедурами, обращающимися к ним. Микроконтроллеры обычно имеют специальные инструкции для доступа к программной памяти, которые обеспечивают сигнатуру для поиска и делают процедуры просмотра таблиц особенно легко обнаруживаемыми. Второй характеристикой этих процедур поиска является то, что они, как правило, содержат много математической интерполяции. Кроме того, процедуры поиска в таблицах часто тесно сгруппированы в памяти программ, что после нахождения одной из процедур упрощает поиск остальных. После определения ссылочных подпрограмм, поиск всех обращений к ним может дать ключ к идентификации подавляющего большинства данных, используемых контроллером для принятия решений. Аргументы, передаваемые этим функциям, обычно включают начальный адрес таблицы, ее структуру, форму, а также то, какие переменные индексируют элементы таблицы. Вооружившись этой информацией, вы заметно приблизитесь к возможности изменить поведение контроллера.  

Поиск известных таблиц 

Один из способов идентифицировать таблицы – использовать конкретные физические и электрические характеристики датчиков автомобиля, которые будут отображать идентифицируемые характеристики в прошивке ЭБУ.  Например, ЭБУ с датчиком MAF (массового расхода воздуха) будет иметь таблицу, которая переводит необработанные показания напряжения или частоты массового расхода воздуха в поток воздуха в двигатель, обеспечивая внутренне представление.   

К счастью для нас, выходной сигнал MAF определяется физикой, а точнее законом Кинга, поэтому кривая всегда будет иметь характерную форму, хотя она будет варьироваться от датчика к датчику. Это приведет к тому, что таблицы будут иметь характерный набор значений, которые можно будет наблюдать в ПЗУ. Понимая, что использоваться будут  универсальные данные, давайте более подробно рассмотрим, как данные калибровки отображаются в различных программах. 

На рисунках 6-1 и 6-2 показаны кривые датчиков Ford и Nissan аналогичной формы; сходство, которое они демонстрируют, распространяется на большинство производителей. 

 

Рисунок 6-1: График передачи MAF у Ford 
Рисунок 6-2: График MAF VQ у Nissan 

На рисунках с 6-2 по 6-6 показаны пять разных представлений одних и тех же данных. На рисунке 6-3 показано, как кривая VQ, изображенная на рисунке 6-2, будет выглядеть в шестнадцатеричном редакторе.  

Рисунок 6-3: Таблица VQ в шестнадцатеричном редакторе HxD: 128 байт или от 64- до 16- битные слова 

На рисунках 6-4 и 6-5 показана таблица VQ в analyze.exe, доступном по адресу: https://github.com/blundar/analyze.exe/. Будучи простым инструментом визуализации, analyze.exe окрашивает ячейки в соответствии с их числовыми значениями. Вы можете выбрать точность данных – например, 1 = 8-битный байт, 2 = 16-битное слово и 4 = 32-битное значение – и сколько строк и столбцов вы хотите представить. Такое простое визуальное оформление часто упрощает определение того, где находится код, а где данные, чем не может похвастаться шестнадцатеричный редактор, изображенный на рисунке 6-3.  

Рисунок 6-4: Таблица VQ в analyze.exe: значения от 48 до 65535 в первых четырех строках с 16 х 16-битными значениями. 
Рисунок 6-5: Первые четыре строки значений 16 х 16 бит. 

Посмотрите еще раз на первые четыре строки 16 х 16-битных значений на рисунках 6-4 и 6-5, заштрихованных в analyze.exe. Обратите внимание, насколько плавно нелинейная кривая на рисунках 6-1 и 6-2 имитирует плавную нелинейную последовательность значений. Рисунок 6-6 демонстрирует те же значения в шаблоне из 64 столбцов, так что вы сможете увидеть полный градиент первых четырех строк из рисунка 6-5. Тип автомобиля в данном случае не играет большой роли, общие структуры данных будут одинаковыми.  

Рисунок 6-6: от 64- до 16-битных слов в строке 

Инструменты визуализации, такие как шестнадцатеричные редакторы или analyze.exe, также могут быть полезны, если вы не знаете точной формы или паттерна, который ищете. В независимости от того, какой тип транспортного средства вы будете исследовать, структуры данных будут иметь шаблоны и порядки, которые обычно не видны в исполняемом коде. На рисунке 6-7 показан пример четкой визуальной схемы данных в analyze.exe – должны выделяться постепенно изменяющиеся и повторяющиеся значения. 

Рисунок 6-7: Образцы и постепенные изменения в табличных данных в ПЗУ ChevroletCamaro 2002 года, визуализированные с помощью analyze.exe. 

С другой стороны, если вы посмотрите на код, подобный изображенному на рисунке 6-8, вы увидите более рандомный и хаотичный вид. (На рисунках 6-7 и 6-8 точность (precision) установлена на 2, поскольку используемый микроконтроллер является 16-битным процессором, и будет разумно предположить, что хороший фрагмент данных также будет 16-битным).  

Рисунок 6-8: Этот рандомный код не имеет четких, упорядоченных шаблонов, которые присутствуют в большинстве таблиц. 

Немного о MCU 

Надеюсь, эти примеры помогут вам связать знания о табличных данных, которые вы ожидаете найти, с их представлением в двоичном blob-объекте. Изучение возможностей микроконтроллера (MCU), используемого в целевой системе, может пролить свет на типы данных, которые следует ожидать при анализе двоичных данных. 

Как правило, форматы представления данных определяются установленным оборудованием. Знание размера регистров MCU, может быть большим подспорьем для определения параметров. Большинство параметров имеют тенденцию быть одного и того же, либо немного меньшего размера, чем регистры данного MCU. 8-битный MCU, такой как 68РС11, скорее всего, будет иметь много 8-битных данных. Было бы странным увидеть в 8-битном MCU 4-байтные или 32-битные целые числа. В то время как 16-битные данные становятся все более распространенными в таких MCU как 68332, 32-битные данные становятся нормой для MCU вроде MPC5xx Power Architecture. Ровно так же дикостью окажутся данные с плавающей точкой в MCU, в котором отсутствует процессор с плавающей точкой. 

Сравнение байтов для определения параметров 

Часто можно получить несколько бинарных файлов, которые будут работать на одном физическом блоке управления двигателем. И чем их больше, тем лучше! Выполнение простого сравнения в шестнадцатеричном редакторе покажет, какие байты различаются для разных файлов. Обычно – но не гарантированно – при изменении параметров код остается неизменным. Если различаются менее 5% файлов, можно с уверенностью предположить, что эти 5% являются параметрами. Если вы знаете, что было изменено в двух бинарных файлах, и знаете, какие именно байты, у вас есть дополнительные подсказки, которые помогут сопоставить изменения в ПЗУ с изменениями параметров. 

На рисунках 6-9 и 6-10 сравниваются V8 Mustang 1996 года и V6 Thunderbird 1997 года, показывающие 6667 различий из 114688 байт. Это ярчайший пример наличия одного и того же кода с разными параметрами, но по сравнению с общим файлом разница по-прежнему составляет около 5 процентов. 

Большинство процессоров используют таблицу векторов прерываний, определяемую установленным процессором. Обращение к таблице данных процессора определит структуру подпрограмм обработки прерываний, что позволит вам быстро идентифицировать их обработчики. Отслеживание контактов прерывания на процессоре до схем в ЭБУ и контактов, на которые вы можете ссылаться на электрической схеме транспортного средства, может помочь вам определить блоки кода, используемые для обслуживания таких аппаратных функций как управление топливом и искрой, обработка сигнала кривошипа и кулачка, а также функции холостого хода. 

Рисунок 6-9: Сравнение V8 Mustang 1996 г. (DXE2.bin) и V6 Thunderbird 1997 г. (SPP3.bin) 
Рисунок 6-10: Функция сравнения файлов шестнадцатеричного редактора HxD.  

Определение данных ПЗУ с помощью WinOLS 

WinOLS – популярная коммерческая программа, предназначенная для модификации бинарных файлов. Она сочетает в себе ряд инструментов для вычисления и обновления контрольных сумм в ПЗУ с набором инструментов для идентификации таблиц. Рисунки 6-11 и 6-12 демонстрируют WinOLS в действии.  

Если тип ПЗУ известен, программа имеет большое количество шаблонов, которые автоматически определяют параметры конфигурации. Большинство известных типов встроенных ПЗУ ориентированы на ЭБУ от Bosch Motronic. Шаблоны и конфигурации можно сохранять, публиковать и продавать, так пользователи еще проще могут вносить изменения в определенные файлы. WinOLS, возможно, является наиболее распространенным программным обеспечением, используемым для выявления интересных данных в ПЗУ, которое не требует анализа кода. Программа разработана, чтобы облегчить быструю настройку контроллера. 

Рисунок 6-11: WinOLS, как показано на этих альтернативных представлениях, поддерживает как двумерные, так и трехмерные представления таблиц 
Рисунок 6-12: WinOLS, используемый на ЭБУ Volkswagen 2.0Tsi 

Анализ кода 

Анализ кода может быть довольно долгой и сложной задачей. Если вы начинаете с нуля и не имеете опыта, на анализ сложного фрагмента кода могут уйти сотни часов. Современные блоки управления часто содержат более одного или двух мегабайт кода, что является огромным объемом. ЭБУ из 1995 года с 32 килобайтами (не мегабайтами) кода будет иметь до 10 тысяч инструкций ассемблера. Подведя маленький итог, никогда не недооценивайте количество работы, которая может потребоваться для реализации этого подхода. У меня нет места для того, чтобы затронуть эту тему достаточно глубоко для тех, кто совсем не знаком с процессом, поэтому я кратко представлю вам несколько инструментов. (В конце концов, по анализу кода написаны целые книги). Здесь же я просто расскажу о конкретных методах и инструментах, применимых к автомобильным встроенным системам.  

Анализируя новую цель, сначала определите архитектуру, с которой вам предстоит работать. Знание того, какой процессор выполнял двоичный blob-объект, поможет вам выбрать подходящий программный инструмент, который вам понадобится в будущем. Если вы не можете определить процессор по маркировке на самом чипе, поищите спецификации в интернете.  

Для анализа кода вам может понадобится дизассемблер. Быстрый поиск в Google показывает, что таких имеется в достаточном количестве. Некоторые нацелены на единую архитектуру, например, Dis51, а некоторые написаны специально для автомобильной инженерии, например, Dis66k. Другие, такие как CATS dasm, IDA Pro, Hopper, ,dasmx и objdump из binutils GNU, нацелены на несколько процессоров. IDA Pro поддерживает больше встроенных целей, чем любая другая названая программа, но является также одним из самых дорогих дизассемблеров. GNU binutils также поддерживает довольно широкий спектр архитектур, но версия, имеющаяся в большинстве систем, будет работать только для “родной” архитектуры. Модифицирование binutils со всеми включенными архитектурами дополнительно откроет еще несколько дверей. Одним словом, ваш выбор дизассемблера зависит от бюджета и процессора, который тот должен поддерживать. 

Теперь выбросьте из головы все эти инструменты дизассемблирования и начните разбирать весь этот хаос, но, как я и предупреждал ранее, на это у вас могут уйти сотни часов. Лучше всего работает установка “разделяй и властвуй”: сосредоточьтесь на мелких задачах, а не на проекте в целом. Если вы получили двоичный файл с помощью бэкдора, вы, вероятно, уже поработали с ECU и сможете назвать модель используемого процессора.  Если вы взломали подпрограммы J2534, возможно, вы не имеете ни малейшего представления об установленном процессоре. В таком случае вам нужно будет снова и снова прогонять его через дизассемблер, используя разные настройки, пока вы не получите какого-то результата.  

Вы ищите ассемблерный код, который легко дизассемблируется, а это значит, что он должен выглядеть логично. Если вы дизассемблируете двоичный файл для неправильной архитектуры или используете неправильные настройки, вы все равно увидите инструкции ассемблера, но его действия при этом не будут иметь никакого смысла. Дизассемблер – это своего рода искусство, и для того, чтобы видеть “чистый” ассемблер нужно много и упорно практиковаться. Только практикуясь вы научитесь определять, когда дизассемблер дает правильный ответ, особенно когда по коду разбросаны неисполняемые таблицы и данные.  

Вот вам несколько советов для того, чтобы разобраться в дизассемблированном коде: 

Старый-добрый дизассемблер выдаст очень подробный текст. Анализируется каждая отдельная инструкция. Некоторые дизассемблеры будут пытаться выделить области, на которые ссылаются, как на данные, и избегать их дизассемблирования.  Остальным дизассемблерам необходимо указывать, какие области являются кодом, а какие – данными. 

Дизассемблер в работе 

Чтобы увидеть процесс дизассемблирования в действии мы рассмотрим простую разборку ROM Nissan 300ZX Twin Turbo. Его ЭБУ имеет 28-пиновое внешнее СППЗУ (ERPOM) 27С256, так что получить его содержимое будет довольно легко. Эта конкретная платформа использует микроконтроллер HD6303, производный от 8-битного контроллера Motorola 6800, который, по всей видимости, поддерживается бесплатным дизассемблером DASMx. Он поставляется с минимальным набором инструкций: для дизассемблирования foo.binсоздание файла, foo.sym, который описывает используемую платформу, и затем создание точки входа в память для размещения изображений, символов, и так далее. Время для ускоренного курса по архитектуре! 

Критическим моментом в структуре памяти является число байт, которые может адресовать MCU – 65535 (64 Кб). Эта информация говорит, чего вам стоит ожидать, глядя на адреса в вашем двоичном blob. Дальнейшее чтение предполагает, что таблица векторов прерываний находится в конце адресуемой памяти с вектором сброса – где каждый процесс запускается после сброса – в 0xFFFE/0xFFFF.  Предполагая, что полученный в следствии чтения EPROM двоичный blob размером 32 Кб (шестнадцатеричный 0x7FFF) содержит таблицу векторов прерываний, мы можем вычислить, что двоичное изображение должно начинаться с адреса памяти 0x8000, чтобы закончиться в адресе 0xFFFFF (0xFFFF – 0x7FFFF = 0x8000). Это также позволяет поискать информацию в интернете о том, не пытался ли кто-либо другой сделать что-то подобное. К примеру, в сообщении на http://forum.nistune.com/viewtopic.php?f=2&t=417  имеется двоичный файл размером 16 Кб на основе настроек для точки входа 0xC000. Чем больше вы будете напрягаться и исследовать до того, как начать использовать дизассемблер, тем у вас больше шансов получить удовлетворительные результаты.  

На рисунке 6-13 показана таблица символов для двоичного файла 300ZX. Рядом с каждым символом указан адрес памяти, используемый прошивкой. Эти адреса памяти могут содержать такие значения, как входящие данные с различных физических контактов на чипе или информацию, например, синхронизацию. 

Рисунок 6-13: Символьный файл для двоичного дизассемблирования 300ZX размером 32 Кб с помощью DASMx. 

Чтобы дизассемблировать бинарный файл мы будем использовать DASMx. Как показано на рисунке 6-14, DASMx сообщает о микроконтроллере MCU Hitachi 6303 с длинной или размером исходного файла 32 Кб, что составляет 32768 байт. 

Рисунок 6-14: Запуск DASMx для дизассемблирования бинарного файла 300ZX размером 32 Кб. 

Теперь скрестите ваши пальцы и надейтесь на вразумительный результат.  

Результатом является таблица векторов, показанная на рисунке 6-15, которая, к слову, выглядит обнадеживающее: все адреса находятся выше указанной точки входа 0x8000. Обратите внимание, что вектор сброса (0xFFFE, RES-vector) имеет указатель RESET_entry на 0xBE6D. 

Рисунок 6-15: Дизассемблированная векторная таблица 

Мы можем дизассемблировать код в 0xBE6D для вектора сброса, который также является точкой входа для кода. На рисунке 6-16 мы видим процедуру RESET_entry, которая выглядит так, как будто очищает часть оперативной памяти. Вероятно, это часть первоначальной последовательности сброса, потому что при загрузке, зачастую, микропрограммное обеспечение инициализирует область данных всеми нулями.  

Рисунок 6-16: Дизассемблирование вектора сброса. 

В этом примере мы дошли до получения дизассемблированного двоичного образа и поиска элементарной логики. Теперь перейдем к самой сложной части: следовании коду, разбиении его на подпрограммы и попытке понять, как это все работает. 

Интерактивные дизассемблеры  

На момент написания этой книги IDA Pro является самым популярным интерактивным дизассемблером. Он выполняет те же задачи, что и описанные выше простые дизассемблеры, и кроме того, также умеет многое другое. В частности, IDA Pro называет регистры и переменные; как только IDA Pro идентифицирует и называет переменную или адрес памяти – например, $FC50 – RPM – она дает всем ссылкам на эту переменную в коде описательное имя, а не менее понятный простой шестнадцатеричный адрес. IDA Pro также составляет графики кода для визуализации выполнения программы.  

Одним из преимуществ IDA Pro является возможность программирования дополнительного кода операций для настройки автомобильных процессоров и плагинов для дальнейшей обработки дизассемблированного кода (например, декомпиляции ассемблера в код более высоко языка программирования); она также позволяет использовать структуры, объединения, классы и другие типы данных, определяемые пользователем.  

Наконец, IDA Pro “из коробки” поддерживает большее количество встроенных платформ, чем любой другой доступный в настоящее время дизассемблер.  

Наличие этих функций не является обязательным для успешного анализа кода, но они значительно упрощают работу. На рисунках 6-17 и 6-18 представлены скриншоты реального анализа кода с помощью IDA Pro. Спасибо Мэтту Уоллэсу за любезное размещение этих примеров на форуме.  

На рисунке 6-18 пользователь с помощью комбинации подходов к взлому оборудования получил прошивку ЭБУ автомобиля Acura NSX, разобрал код, проанализировал его с помощью IDA Pro и переписал. Затем пользователь определил необходимые функции для регистрации данных с ЭБУ и изменения его работы. Результат позволил пользователю использовать принудительную индукцию, то есть турбокомпрессоры и нагнетатели, с заводским компьютером; без модификации ЭБУ это было бы невозможно.  

Рисунок 6-17: Схема IDA, показывающая специально написанную процедуру для программирования NVRAM в реальном времени. 
Рисунок 6-18: IDA-диаграмма кода для проверки топливных форсунок на блоке управления NSX. 

Резюме 

Поскольку для взлома ЭБУ часто используются процессоры меньшего размера, нежели даже те, которые используются в более мощных современных устройствах, таких как сотовые телефоны, инструменты, используемые для реверсирования прошивок, для каждой цели могут быть разными.  Используя комбинацию методов, таких как визуализация данных для поиска таблиц, и путем прямого реверсирования прошивки вы можете определить области, которые вы хотите модифицировать. Методы, обсуждаемые в этой главе, обычно используются специалистами по настройке производительности для топливной экономичности автомобиля. Вы же можете использовать всю эту информацию для разблокировки функций, скрытых в коде вашего автомобиля. Тюнинг производительности мы рассмотрим более подробно в главе 13.  

7 

Создание и использование испытательных стендов ЭБУ 

Наш испытательный стенд для ЭБУ, подобный тому, что показан на рисунке 7-1, будет состоять из ЭБУ, источника питания, дополнительного выключателя питания и коннектора OBD-ll. Вы также можете добавить приборную панель, или другие связанные с CAN системы для тестирования, но создание базового испытательного стенда ECU – лучший способ изучить шину CAN и понять, как создавать собственные инструменты. В этой главе мы шаг за шагом рассмотрим процесс создания испытательного стенда. 

Базовый испытательный стенд ЭБУ 

Самый простой испытательный стенд – это необходимое вам устройство и источник питания. Подавая ЭБУ необходимое количество энергии, вы можете начать тестирование его входов и коммуникаций. Например, на рисунке 7-1 показан базовый испытательный стенд, состоящий из блока питания ПК и ЭБУ. 

Рисунок 7-1: Самый простой испытательный стенд ЭБУ 

Однако часто, чтобы упростить использование и работу испытательного стенда вам придется добавлять хотя бы парочку компонентов или портов. Чтобы упростить включение и выключения устройства, к блоку питания вы можете добавить выключатель. Порт OBD позволяет специализированным механическим инструментам связываться с сетью автомобиля. Для того, чтобы он мог полностью функционировать, нам необходимо провести сетевые провода автомобиля от ECU до порта OBD. 

Поиски ЭБУ 

Как минимум одно место, где вы сможете найти ЭБУ – свалка. Обычно блок управления двигателем находится за магнитолой или бардачком. Если найти его там не удалось, попробуйте проследить ЭБУ по массивному жгуту проводов. Вытаскивая такой ЭБУ самостоятельно (он должен стоить около 150 долларов), не облажайтесь, и не вытащите его из автомобиля, не поддерживающего CAN. Чтобы помочь вам с определением подходящего автомобиля используйте справочные веб-сайты, например, http://www.auterraweb.com/aboutcan.html. Кроме того, при снятии блока управления двигателем не забудьте оставить хотя бы небольшой “хвостик” проводки; позже это упростит подключение.  

Если вариант с вытаскиванием ЭБУ из старых автомобилей не для вас, вы всегда можете заказать подходящую модель онлайн на сайте вроде https://www.car-part.com/ . Стоимость будет немного выше, потому что вы платите за то, чтобы кто-то другой нашел деталь для вас и отправил ее. Убедитесь, что в комплект поставки входят жгуты проводов. 

Примечание 

Одним из недостатков покупки ЭБУ в интернете является сложность приобретения деталей от одного и того же автомобиля, в случае, если вам их понадобится несколько. 

Вместо того, чтобы собирать или покупать поддержанный блок управления двигателем, вы также можете использовать готовый симулятор, такой как ECUsim 2000 от ScanTool (смотрите рисунок 7-2). Такой симулятор будет стоить около 200 долларов и будет поддерживать только связь OBD/UDS. Симуляторы могут генерировать неисправности и мигание световых индикаторов MIL, они также имеют возможность изменения общих параметров транспортного средства, таких как скорость. Однако, если вы не создаете приложение, которое будет использовать исключительно пакеты UDS, вариант с симулятором, вероятно, вам не подойдет.   

Рисунок 7-2: Симулятор ECUsim OBD 

Прозвонка проводов ЭБУ 

Когда у вас будут все детали, вам нужно будет найти электрическую схему вашего ЭБУ, чтобы определить, какие провода необходимо будет подключить, чтобы блок заработал. Чтобы найти электрическую схему вы можете посетить такие веб-сайты как ALLDATA (http://www.alldata.com/) или Mithcell1 (https://mitchell1.com/). Вы обнаружите, что в некоторых готовых руководствах иногда могут присутствовать электрические схемы, но, к сожалению, зачастую они оказываются неполными, либо содержат только общие области ремонта авто. 

Электрические схемы подключения не всегда легко читать, главным образом потому, что некоторые из них объединяют большое количество мелких элементов (смотрите рисунок 7-3). Чтобы лучше понять, на каких проводах следует сосредоточиться, попробуйте мысленно отделить каждый элемент.  

Рисунок 7-3: Пример схемы подключения ЭБУ 

Распиновка 

Распиновку для блоков управления нескольких различных автомобилей вы можете найти на сайте http://www.innovatemotorsports.com/resources/ecu_pinout.php и на коммерческих ресурсах, таких как ALLDATA и Mitchell1. Книги, такие как руководства по ремонту автомобилей Chilton, также включают в себя блок-схемы, но обычно они охватывают только самые распространенные вопросы по ремонту, но не весь ЭБУ.  

Блок-схемы 

Блок-схемы воспринимать легче, чем электрические схемы, на которых все компоненты показаны на одном листе. Блок-схемы обычно показывают проводку только для одного компонента и предлагают общий обзор основных компонентов, тогда как схемы показывают все детали на одном листе. Некоторые блок-схемы также включают легенду, показывающую соединители, находящиеся на этом модуле, а также, к какому соединительному блоку относится эта схема; зачастую легенда находится в одном из углов блок-схемы (смотрите таблицу 7-1) 

CONN ID Количество контактов Цвет 
C1 68 WH 
C2 68 L-GY 
C3 68 M-GY 
C4 12 BK 
Таблица 7-1: Пример легенды коннектора 

В легенде должен быть указан номер коннектора, количество контактов и его цвет. Например, линия С1 = 68 WH, в таблице 7-1 означает, что коннектор С1 имеет 68 контактов и белый цвет. L-GY, скорее всего, означает светло-серый и так далее. Номер разъема, например С2-55, относится к коннектору 2, пин 55. Обычно на разъемах есть номера на первом и последнем контактах в ряду. 

 Подключение оборудования 

Теперь, когда у вас есть информация о проводке коннектора, самое время подключить его. Подключите CAN к нужным портам на разъеме, как описано в разделе “Схема расположения выводов разъема OBD-ll“ в главе 2. Когда вы подадите питание – блока питания от старого ПК должно хватить – и добавите CAN сниффер, вы должны увидеть пакеты. Вы можете использовать простой диагностический прибор OBD-ll, который можно приобрести в любом автомобильном магазине. Если вы подключили все правильно, диагностический прибор должен идентифицировать автомобиль, предполагая, что ваш испытательный стенд включает в себя главный ЭБУ.  

Примечание 

Диагностический прибор/ЭБУ, скорее всего, сообщит вам об ошибке “проверьте двигатель”. 

Если вы подключили все оборудование, но по-прежнему не видите пакетов на шине CAN, возможно, у вас отсутствует терминирование. Решать эту проблему начните с добавления резистора на 120 Ом, поскольку шина CAN имеет резисторы на 120 Ом на каждом конце шины. Если это не сработает, добавьте второй резистор. Максимальное недостающее сопротивление должно быть 240 Ом. Если шина по-прежнему не работает, проверьте расположение проводов и попробуйте еще раз.  

Примечание 

Большинство компонентов обмениваются данными с ЭБУ просто посредством цифровых или аналоговых сигналов. Аналоговые сигналы легко имитировать с помощью потенциометра, вы также можете привязать потенциометр на 1 кОм к температуре двигателя и топливопроводам, чтобы контролировать их. 

Построение более продвинутого испытательного стенда 

Если вы готовы продолжить исследования в области взлома автомобилей, задумайтесь о создании более совершенного испытательного стенда для ЭБУ, например, как изображенный на рисунке 7-4.  

Этот стенд комбинирует ЭБУ и BCM, потому он также имеет оригинальные ключи для запуска автомобиля. Обратите внимание, что дополнительная приборная панель имеет два потенциометра на 1 кОм или переменные резисторы в нижней левой части, которые привязаны к температуре двигателя и топливопроводам. Эти потенциометры мы будем использовать, как вы узнаете в следующем разделе, для генерации сигналов датчиков. Конкретно этот испытательный стенд также включает в себя небольшой микроконтроллер (MCU), который позволяет имитировать отправку сигналов коленчатого и распределительного валов в ЭБУ. 

Рисунок 7-4: Более совершенный испытательный стенд 

Более сложный стенд, подобный тому, что показан на рисунке 7-4, значительно упрощает определение трафика: просто загрузите сниффер, отрегулируйте ручку и следите за изменением пакетов. Если вы знаете, какой провод вам нужен и тип сигнала, который он принимает, вы легко подделаете сигнал почти любого компонента. 

  Имитация сигналов датчиков 

Как я уже упоминал ранее, используя потенциометры, вы можете имитировать сигналы различных датчиков, включая нижеперечисленные: 

Если ваша цель – генерация более сложных или цифровых сигналов, используйте небольшой микроконтроллер, такой как Arduino или Raspberry Pi.  

На нашем испытательном стенде мы также хотим контролировать количество оборотов и/или стрелку спидометра. Для этого нам понадобится немного информации о том, как ЭБУ измеряет скорость.  

Датчики на основе эффекта Холла 

Датчики на эффекте Холла часто используются для определения частоты вращения двигателя и положения коленчатого вала, а также для генерации цифровых сигналов. На рисунке 7-5 для измерения скорости вращения датчик на эффекте Холла использует колесо затвора, или колесо с зазорами. Кристалл арсената галлия измеряет свою проводимость под воздействием магнитного поля. Когда колесо затвора вращается, кристалл обнаруживает магнит и посылает импульс, когда колесо не блокирует его. Измеряв частоту импульсов, вы можете определить скорость автомобиля.  

Рисунок 7-5: Схема колеса затвора для датчика эффекта Холла 

Для измерения скорости вы также можете использовать звездочку распределительного вала. Если вы посмотрите на эту звездочку, то магнит будет находится сбоку от колеса (смотрите рисунок 7-6). 

Рисунок 7-6: Звездочка привода распределительного вала 

С помощью осциллографа на сигнальном приводе вы можете увидеть, что датчик на эффекте Холла выдает прямоугольную волну. Обычно на датчике распределительного вала находится три датчика: питание, масса и сам датчик. Питание обычно составляет 12 В, но сигнальный провод, как правило, работает, на 5 В. Датчики распределительного вала также могут быть оптическими, они работают аналогичным образом, за исключением того, что светодиод находится с одной стороны, а фотоэлемент – с другой.  

Вы можете измерить время полного вращения по отсутствующему зубцу, называемому зубчатым колесом, или по метке синхронизации.  Очень важно знать, за сколько времени распределительный вал совершает полный оборот. Индуктивный датчик распределительного вала выдает синусоидальную волну, и чтобы определить полный оборот, часто имеет отсутствующий зуб. 

 На рисунке 7-7 мы можем увидеть, что сигнал распределительного вала повторяется примерно каждые 2 миллисекунды. Скачок или разрыв, который вы видите на волне на отметке примерно 40 миллисекунд, происходит, когда достигается отсутствующий зуб. Расположение этого разрыва отмечает точку, в которой распределительный вал совершил полный оборот. Чтобы подделать эти сигналы распределительного вала на испытательном стенде ЭБУ, вам нужно написать небольшой кусок кода для вашего микроконтроллера. При написании кода микроконтроллера для имитации этих датчиков важно знать, какой тип датчика используется в вашем автомобиле, чтобы знать, какой выход использовать при имитации зубьев: цифровой или аналоговый. 

Рисунок 7-7: Сигналы датчика распредвала под осциллографом 

Симуляция скорости автомобиля 

Теперь мы построим испытательный стенд для симуляции скорости автомобиля. Мы будем использовать этот испытательный стенд вместе с приборной панелью, показанной на рисунке 7-4, чтобы получить VIN автомобиля через OBD-ll. Это даст нам точный год производства, марку, модель и тип двигателя. (Мы рассмотрели, как сделать это вручную, в разделе “Единые диагностические услуги” в главе 4). Результаты можем увидеть в таблице 7-2. 

VIN Модель Год Марка Кузов Двигатель 
1G1ZT53826F109149 Malibu 2006 Chevrolet Седан, 4 двери 3.5L V6 OHV 12V 
Таблица 7-2: Информация об автомобиле

Как только мы узнаем год выпуска и тип двигателя нашего автомобиля, мы можем найти электрическую схему, чтобы определить, какой из проводов ЭБУ регулирует частоту вращения двигателя (смотрите рисунок 7-8). Затем, чтобы измерить эффекты, мы можем отправить симулированные данные показателей скорости в ЭБУ. Использование электрических схем для имитирования реального поведения двигателя может упростить идентификацию целевых сигналов на шине CAN.  

Рисунок 7-8: Схема подключения, показывающая пин скорости двигателя.  

На схеме подключения на рисунке 7-8 показано, как можно отследить провод от датчика положения коленчатого вала, так мы можем видеть, что коннектор С2, пин 27 принимает частоту вращения двигателя от датчика коленчатого вала. Определив этот контакт на электрической схеме, мы находим соответствующий провод на ЭБУ. Мы можем подключить этот провод к цифровой точке ввода-вывода на Arduino. В этом примере мы будем использовать пин 2, а затем добавим потенциометр на А0, чтобы с его помощью контролировать скорость “зубцов” датчика положения коленчатого вала, идущую в ECM. Пин 2 отправит вывод на С2, пин 27.  

С целью симулировать скорость двигателя, отправляемую датчиком положения коленчатого вала, мы пишем фрагмент кода на Arduino для отправки высоких и низких импульсов с интервалом задержки, отображаемым в положении потенциометра (смотрите листинг 7-1). 

int ENG_SPD_PIN = 2; 
long interval = 500; 
long previousMicros = 0; 
int state = LOW; 
 
// the setup routine runs once when you press reset 
void setup() { 
  pinMode(ENG_SPD_PIN, OUTPUT); 

 
// the loop routine repeats forever 
void loop() { 
  unsigned long currentMicros = micros(); 
 
  // read the input on analog pin 0 
  int sensorValue = analogRead(A0); 
  interval = map(sensorValue, 0, 1023, 0, 3000); 
 
  if(currentMicros – previousMicros > interval) { 
    previousMicros = currentMicros; 
 
    if (state == LOW) 
      state = HIGH; 
    else 
      state = LOW; 
 
    if (interval == 0) 
      state = LOW;  // turning the pot all the way down turns it “off” 
 
    digitalWrite(ENG_SPD_PIN, state); 
  } 

Листинг 7-1: Фрагмент кода Arduino, предназначенный для имитации оборотов двигателя 

Теперь мы вставляем этот фрагмент кода в Arduino, включаем испытательный стенд, и когда мы поворачиваем ручку на потенциометре, вместе с ней должна крутиться стрелка оборотов двигателя на приборной панели. На рисунке 7-9 вторая строка трафика cansniffer показывает байты 2 и 3 – 0x0B и 0x089, изменяющиеся при повороте ручки потенциометра для арбитража ID 0x110 (столбец с надписью “ID”).  

Рисунок 7-9:  cansniffer, идентифицирующий количество об/мин.  

Примечание 

0x0B и 0x89 напрямую не переводятся в об/мин; скорее, это стенография. Другими словами, если у вас будет 1000 об/мин, вы не увидите шестнадцатеричное значение 1000. Когда вы запрашиваете у двигателя количество об/мин, алгоритм конвертирования этих двух байтов в об/мин обычно следующий:  

– это первый байт, а B, соответственно, второй. Если вы примените этот алгоритм к тому, что показано на рисунке 7-9 (преобразовано с шестнадцатеричного в десятичное), вы получите следующее: 

Вы можете дополнительно упростить этот метод, взяв 0xB89, что в десятичной форме составляет 2953. Разделив это значение на 4, вы получите заветный ответ – 738,25 об/мин. 

Когда был сделан этот скриншот, стрелка находилась на холостом ходу немного ниже значения 1 на тахометре, так что вероятно, это тот же алгоритм. (Иногда вы можете обнаружить, что значения в настоящих CAN пакетах не всегда соответствуют алгоритмам, используемым стандартными диагностическими инструментами, использующими UDS, но все-таки хорошо, когда они совпадают). 

Чтобы убедиться, что идентификатор арбитража 0x110 с байтами 2 и 3 управляет количеством об/мин, мы отправим наш собственный кастомный пакет. Зафлудив шину циклами, которые будут передавать следующую строку, мы зафиксируем стрелку тахометра на максимальных оборотах. 

cansend slcan0 110#00ffff3500380000 

Хотя этот метод работает и после подключения, для определения CAN-пакета, отвечающего за кол-во об/мин, требуется всего несколько секунд, все же есть некоторые ощутимые проблемы. Время от времени появляется сигнал CAN, который сбрасывает значения на 00 00, и останавливает движение стрелки спидометра. Таким образом, хотя ECM вполне “уверен” в том, что коленчатый вал вращается, он обнаруживает проблему и пытается выполнить сброс. 

Для извлечения данных вы можете использовать инструменты ISO-TP, описанные в главе 3. Используя два окна терминала, мы можем проверить, где находится диагностический код. (Вы также можете использовать диагностический прибор).  

В одном терминале введите следующее: 

isotpsniffer -s 7df -d 7e8 slcan0 

А в другом терминале отправьте следующую команду: 

echo “03” | isotpsend -s 7DF -d 7E8 slcan0 

Вы должны увидеть вывод в первом терминале: 
slcan0 7DF [1] 03 – ‘.’
slcan0 7E8 [6] 43 02 00 68 C1 07 – ‘C..h..’
Похоже, у нас установлен код неисправности. Запрос PID 0x03 вернул 4-байтовый код неисправности (0x0068C107). Первые два байта составляют стандартный код неисправности (0x00 0x68). Они преобразуются в P0068, который согласно руководству Chilton расшифровывается как “производительность воздушного потока корпуса дроссельной заслонки”. Быстрый поиск в Google сообщит вам, что это просто общий код ошибки, возникающий из-за несоответствия между тем, что думает PCM, и данными, которые он получает из впускного коллектора. Если бы мы хотели подделать и эти данные, нам нужно было бы подделать три дополнительных датчика: датчик массового расхода воздуха (MAF), положения дроссельной заслонки и давления воздуха в коллекторе (MAP). Исправив это, однако, проблема может остаться. PCM может продолжать думать, что автомобиль работает плавно, но, если вам действительно не наплевать на подделку всех данных, вы можете найти другие способы обмана сигналов, которые вы хотите получить с PCM, без необходимости быть невосприимчивыми к появлению кодов неисправности.  

Если для отправки сигналов вы не хотите использовать Arduino, вы также можете купить генератор сигналов. Профессиональный инструмент будет стоить не менее 150 долларов, но вы также можете приобрести такой в SparkFun примерно в 3 раза дешевле (https://www.sparkfun.com/products/11394/). Еще одна отличная альтернатива – Megasquirt от JimStim. Его можно приобрести в виде комплекта или полностью собрать за 90 долларов в компании DIYAutoTune (https://www.diyautotune.com/product/jimstim-1-5-megasquirt-stimulator-w-wheel-simulator-assembled/).  

Резюме  

В этой главе вы узнали, как построить свой собственный испытательный стенд ECU в качестве доступного решения для безопасного тестирования защиты транспортных средств. Мы рассмотрели, где вы можете получить детали для сборки и как читать схемы подключения, так что теперь вы знаете, как собрать все части воедино. Вы также узнали, как создать более продвинутый испытательный стенд, который может моделировать сигналы двигателя, заставляя компоненты думать, что все это происходит в настоящем автомобиле. 

Собирая испытательный стенд впервые, вы можете потратить на сборку достаточно много времени, но будьте уверены, в будущем это с лихвой окупится.  Мало того, что проводить тестирование на испытательном стенде безопаснее, эти устройства также отлично подходят для обучения и могут быть доставлены туда, куда вы пожелаете. 
 

8 

АТАКИ НА ЭБУ И ДРУГИЕ ВСТРОЕННЫЕ СИСТЕМЫ 

ЭБУ – обычная цель реверс-инжениринга, иногда называемого чип-тюнингом. Как упоминалось в главе 7, самым популярным путем взлома ЭБУ является модификация топливной системы – изменение топливной эффективности и производительности, – что может дать прирост производительности автомобиля. В эти типы модификаций вовлечено большое количество людей и сообществ, а мы более подробно рассмотрим модификацию прошивки в главе 13.  

В этой главе основное внимание будет уделено методам атак на встроенные системы, а также атакам по побочным каналам. Эти методологии можно применять к любым встроенным системам, а не только к ЭБУ, кроме того, они могут использоваться для модификации транспортного средства с помощью инструментов со вторичного рынка. Здесь мы сосредоточимся на отладке интерфейсов для оборудования, а также на выполнении анализа атак по побочным каналам и глитч-атакам. 

Примечание 

Чтобы извлечь максимальную пользу из этой главы, вы должны хорошо разбираться в основах электроники, но в любом случае, я приложил все усилия, чтобы объяснить вещи максимально простым языком.  

Анализ печатных плат 

Первым шагом в атаке на ЭБУ или любую другую встроенную систему будет анализ целевой печатной платы. Я коснулся анализа печатных плат в главе 7, но в этой главе я более подробно расскажу о том, как устроена электроника и микросхемы. Также я познакомлю вас с методами, которые вы сможете применить к любой встроенной системе автомобиля.  

Определение номеров моделей 

При реверсированнии печатной платы сначала обратите внимание на номера моделей чипов микроконтроллеров платы. Эти номера моделей могут помочь вам найти ценную информацию, которая может сыграть ключевую роль в вашем анализе. Большинство микросхем, которые вы найдете на печатных платах транспортных средств, являются широко используемыми – компании редко производят свои кастомные микросхемы, поэтому поиск в интернете номера модели микросхемы с большой долей вероятности предоставит вам полную спецификацию этого чипа. 

Как я уже упоминал в главе 7, иногда вы будете сталкиваться с процессорами ASIC с кастомными опкодами, особенно в старых системах, перепрограммировать которые будет труднее. Чтобы прочитать прошивку старых микросхем, подобных описанным выше, снимите их с платы и подключите к программатору EPROM. Вы должны уметь перепрограммировать современные системы напрямую через программное обеспечение для отладки, такое как JTAG.  

Найдя спецификацию, попытайтесь определить микроконтроллеры и расположенную на них память, чтобы иметь представление о том, как все соединено и где найти диагностические выводы – потенциальный путь внутрь. 

Вскрытие и идентификация чипа 

Если вы не можете найти номер модели, иногда все, что вам нужно – лого чипа (через некоторое время вы обнаружите, что начинаете узнавать замечать логотипы чипов на автомате) и несколько кодов. Логотип, показанный на рисунке 8-1, принадлежит STMicroelectronics. В верхней части микросхемы указан номер модели – в данном случае STM32F407, он может оказаться трудночитаемым, поскольку является выгравированным. Часто лупа с подсветкой или дешевый USB-микроскоп могут оказаться очень удобными для рассмотрения этих маркировок. Перейдите на https://www.st.com/content/st_com/en.html, чтобы найти технические характеристики микросхем серии STM32F, в частности, модификации 407. Как и номер VIN, номера моделей часто разбиваются на разделы, представляющие номер модели и различные модификации. Однако общего стандарта для разбиения этих маркировок нет, и каждый производитель представляет свои данные по-своему.  

Рисунок 8-1: чипсет STM32 

Под номером модели микросхемы находится код – в данном случае VGT6 – который сообщает вам о конкретных функциях, таких как поддержка USB, доступных на микросхеме. Если вы посмотрите спецификацию номера модели с кодом ST, вы узнаете, что серия STM32F407Vx представляет собой чип ARM Cortex M4 с поддержкой Ethernet, USB, двух CAN и LIN, а также JTAG и Serial Wire Debug.  

Чтобы определить функцию различных пинов, просмотрите спецификацию, найдите схемы распиновки и пакет, который соответствует вашему по количеству пинов. Например, как вы можете видеть на рисунке 8-1, каждая сторона микросхемы имеет 25 контактов, всего 100, что соответствует распиновке LQFP100 в спецификации, показанной на рисунке 8-2.   

Рисунок 8-2: спецификация распиновки STM32F4 

Отладка оборудования с помощью JTAG и Serial Wire Debug 

Для отладки микросхем, так же как и программного обеспечения, вы можете использовать различные протоколы отладки. Чтобы определить протокол, который поддерживает ваша целевая микросхема, вам необходимо использовать ее техническое описание. Вы должны иметь возможность использовать порт отладки микросхемы для перехвата ее обработки и загрузки/выгрузки модификаций прошивки микросхемы.  

JTAG 

JTAG – это протокол, который позволяет выполнять отладку на уровне чипа, а также загружать и выгружать микропрограммное обеспечение в чип. Найти JTAG-соединение на микросхеме вы можете с помощью, конечно же, листа спецификаций.  

JTAGulator 

Вы часто можете найти контактные площадки на плате микросхемы, которые были выломаны из самой микросхемы. Они могут дать вам доступ к контактам JTAG. Чтобы проверить открытые контактные площадки на наличие соединений JTAG используйте инструмент под названием JTAGulator, показанный на рисунке 8-3. Подключите все открытые контакты микросхемы к JTAGulator и установите напряжение, соответствующее микросхеме. JTAGulator должен найти любые контакты JTAG и даже пройти по цепочке JTAG – метод соединения чипов через JTAG – чтобы увидеть, подключены ли какие-либо другие чипы.  

Рисунок 8-3: JTAGulator с кабелем Bus Pirate. 

Для проверки JTAGulator поддерживает либо винтовые клеммы, либо использование кабеля Bus Pirate (как показано на рис. 8-3). И JTAGulator и кабель Bus Pirate используют последовательный интерфейс для настройки и взаимодействия с чипом. 

Serial Wire Debug 

Хотя JTAG является наиболее часто используемым протоколом отладки оборудования, некоторые микроконтроллеры, такие как серия STM32F4, которая обычно используется в автомобильных приложениях, поскольку имеют встроенную поддержку CAN, в основном используют Serial Wire Debug (SWD). Хотя IC серии STM32F4 могут поддерживать JTAG, они часто включают поддержку исключительно SWD, поскольку SWD требует только два контакта вместо пяти, используемых JTAG. SWD также позволяет повторять выводы JTAG, поэтому эти микросхемы могут поддерживать параллельно как JTAG, так и SWD, используя выводы, помеченные как TCK и TMS. (В спецификации эти пины обозначены как SWCLK и SWIO). При отладке микросхем ST вы можете использовать инструмент ST-Link, с помощью которого можно подключать, отлаживать и перепрограммировать процессоры. По сравнению с некоторыми аналогами JTAG, ST-Link дешев (около 20 долларов). Вы также можете использовать плату STM32 Discovery.  

Комплект STM32F4DISCOVERY  

Кит STM32F4DISCOVERY (продается STM) – еще один инструмент, который вы можете использовать для отладки и программирования чипов. Это, на самом деле, платы для разработчиков со своим программатором. Они стоят около 15 долларов и просто обязаны быть в вашем наборе инструментов для взлома автомобилей. Преимущество использования набора Discovery заключается в том, что это и дешевый программатор, и плата для разработки, которую можно использовать для тестирования модификаций прошивки чипа.  

Чтобы использовать набор Discovery в качестве универсального программатора, снимите перемычки с контактов, помеченных ST-Link, а затем подключите шесть контактов на противоположной стороне, помеченных SWD (смотрите рисунок 8-4). Пин 1 начинается рядом с белой точкой на разъеме SWD. 

Таблица 8-1 показывает распиновку. 

STM32 chip STM32F4DISCOVERY kit 
VDD_TARGET Pin 1 
SWLCK Pin 2 
GND Pin 3 
SWDIO Pin 4 
nRESET Pin 5 
SWO Pin 6 
Таблица 8-1: распиновка кита STM32F4DISCOVERY
Идет вставка изображения...
Рисунок 8-4: программирование микросхемы STM32 с помощью комплекта STM32F4DISCOVERY 

Скорее всего, на целевое устройство придется подать питание, но вместо использования пин 1 на коннекторе SWD, используйте пин 3V из платы Discovery , как показано на рисунке 8-4. (Обратите внимание на распиновку, комплект Discovery не использует все шесть контактов для SWD; контакты nRESET и SWO не являются обязательными).  

После того, как вы все подключите, скорее всего, вы захотите читать и записывать прошивку. Если вы используете Linux, вы можете загрузить ST-Link из GitGub по адресу https://github.com/stlink-org/stlink. После загрузки и установки этих утилит вы сможете не только читать и записывать данные во флеш-память чипа, но также использовать gdbserver в качестве отладчика в реальном времени.  

Дебаггер для продвинутых 

Renesas – популярный автомобильный чипсет, используемый в ЭБУ (смотрите рисунок 8-5). У него есть собственная реализация, построенная на базе JTAG, которая называется Advanced User Debugger (AUD). AUD обеспечивает ту же функциональность, что и JTAG, но использует собственный интерфейс. Как и в случае с SWD, для связи с наборами микросхем Renesas, AUD потребуется специальный интерфейс.  

Рисунок 8-5: ЭБУ Acura TL 2005  с Renesas SH MCU и портом AUD 

Nexus 

Nexus от Freescale/Power Architecture (теперь NXP) – еще один проприетарный интерфейс JTAG. Подобно AUD и SWD, для взаимодействия этому внутрисхемному отладчику требуется собственное устройство. Имея дело с чипами Freescale, такими как серия MCO5xxx, имейте в виду, что его отладчиком может быть Nexus.  

Интерфейс Nexus использует специальный набор пинов, который должен быть определен в технических характеристиках микросхемы. В разделе вспомогательных портов в спецификации посмотрите на контакты EVTI/O.  

Анализ побочных каналов с помощью ChipWhisperer  

Анализ побочных каналов – это еще одна аппаратная атака, используемая для обхода защиты ЭБУ и других микроконтроллеров и взлома встроенной криптографии. Вместо того, чтобы напрямую нацеливаться на конкретное оборудование или программное обеспечение, этот тип атаки использует преимущества различных характеристик встроенных электронных систем.  Атаки по побочным каналам могут принимать разные формы, некоторые из которых могут стоить от 30 до 100 тысяч долларов, поскольку для них требуется специальное оборудование, такое как электронные микроскопы. Подобные дорогостоящие атаки по побочным каналам часто бывают инвазивными, что означает, что они навсегда перепрограммируют цель.  

Мы рассмотрим более простые и дешевые атаки по побочным каналам с помощью ChipWhisperer, неинвазивного инструмента от NewAE Technologies (https://www.newae.com/chipwhisperer). ChipWhisperer – это инструмент для анализа и фреймворк с открытым исходным кодом, который стоит немного больше тысячи долларов – значительно меньше, чем его аналоги без открытого исходного кода, стоимость которых обычно составляет около 30 тысяч.  

Примечание 

Атаки, о которых я вам расскажу, можно выполнить и с меньшими затратами, самостоятельно изготовив специальный инструмент, но ChipWhisperer – самый дешевый инструмент, охватывающий все базовые вещи. Кроме того, туториалы по ChipWhisperer нацелены на проекты с открытым исходным кодом, что делает их идеальными для этой книги, поскольку мы не можем использовать примеры от конкретных производителей из-за авторских прав. При демонстрации каждой атаки в этой главе я буду интегрировать уроки от NewAE 

ChipWhisperer имеет дополнительный пакет, который включает в себя целевую плату разработки, называемую MultiTarget Victim Board (смотрите рисунок 8-6). Эта плата, в основном, используется для обучения и тренировок, мы также будем использовать ее в качестве цели для наших демонстраций.  

Рисунок 8-6: MultiTargetVictim Board 

Плата MultiTarget Victim Board состоит из трех отдельных систем: ATmega328, XMEGA и устройства чтения смарт-карт. (ChipWhisperer может выполнять атаки типа “человек посередине” на смарт-картах, но поскольку автомобили на самом деле не используют смарт-карты, мы не будем рассматривать эту функцию). 

Меняя перемычки на плате, вы можете передавать питание для включения или отключения различных систем, но будьте осторожны, активируйте только секцию за раз, иначе вы рискуете закоротить плату. Перед тестированием обратите внимание на настройки перемычек.   

Установка программного обеспечения 

Сначала установите программное обеспечение ChipWhisperer. Следующие инструкции будут предназначены для пользователей Linux, но вы можете найти подробные указания по установке на Windows по адресу http://www.newae.com/sidechannel/cwdocs/

Для работы ПО ChipWhisperer требуется наличие Python 2.7 и некоторых дополнительных библиотек Python. Сначала введите следующее: 

$ sudo apt-get install python2.7 python2.7-dev python2.7-libs python-numpy 
python-scipy python-pyside python-configobj python-setuptools python-pip git 
sudo pip install pyusb-1.0.0b1 

Для загрузки ПО ChipWhisperer, вы можете либо загрузить стабильную версию в виде ZIP-файла с сайта NewAE, либо скачать копию из GitHub репозитория, как показано ниже: 

$ git clone git://git.assembla.com/chipwhisperer.git 
cd chipwhisperer 
git clone git://git.assembla.com/openadc.git 

Вторая git команда загружает OpenADC. Плата OpenADC ChipWhisperer является осциллографом, который измеряет сигналы напряжения и, по сути, является сердцем системы ChipWhisperer.  Для настройки программного обеспечения используйте следующие команды (вы должны быть в root каталоге ChipWhisperer): 

$ cd openadc/controlsw/python 
sudo python setup.py develop 
cd software 
sudo python setup.py develop 

Оборудование уже изначально поддерживается Linux, но вам следует добавить группу для обычного пользователя, которую вы будете тестировать, чтобы пользователь мог иметь доступ к устройству без root прав. Чтобы разрешить non-root пользователям использовать оборудование, создайте файл udev, например /etc/udev/rules.d/99 –ztex.rules, и в этот файл добавьте следующее: 

SUBSYSTEM==”usb”, ATTRS{idVendor}==”04b4″, ATTRS{idProduct}==”8613″, 
MODE=”0664″, GROUP=”plugdev” 
SUBSYSTEM==”usb”, ATTRS{idVendor}==”221a”, ATTRS{idProduct}==”0100″, 
MODE=”0664″, GROUP=”plugdev” 

Также создайте файл для программатора AVR с именем /etc/udev/rules.d/ 99-avrisp.rules: 

SUBSYSTEM==”usb”, ATTRS{idVendor}==”03eb”, ATTRS{idProduct}==”2104″, 
MODE=”0664″, GROUP=”plugdev” 

Теперь добавьте себя (чтобы новые разрешения вступили в силу, вам нужно будет выйти и снова войти): 

$ sudo usermod -a -G plugdev <YourUsername> 
$ sudo udevadm control –reload-rules 

Подключите ChipWhisperer к своей машине, подключив кабель mini-USB к боковой стороне платы ChipWhisperer. Сверху должен загореться зеленый индикатор состояния системы, и теперь ваш ChipWhisperer должен быть настроен.  

Подготовка Victim Board 

Чтобы подготовить Victim Board – или тестируемое устройство (DUT), как оно упоминается в документации ChipWhisperer – загрузите библиотеку AVR Crypto (библиотека по умолчанию не включена в ChipWhisperer из-за экспортных законов), введя следующее: 

$ cd hardware/victims/firmware 
sh get_crypto.sh 

Чтобы запрограммировать нашу Victim Board, мы будем использовать графический интерфейс AVRDUDESS. Загрузить AVRDUDESS вы можете из репозитория GitHub по адресу https://github.com/zkemble/avrdudess/ или с сайта https://blog.zakkemble.net/avrdudess-a-gui-for-avrdude/. Чтобы это заработало вам нужно установить mono: 

$ sudo apt-get install libmono-winforms2.0-cil 

Затем убедитесь, что Victim Board настроена на использование ATmega328, изменив для этого настройки перемычек в соответствии со схемой на рисунке 8-7. 

Идет вставка изображения...
Рисунок 8-7: Настройки перемычек для MultiTargetVictim Board 

Ваш ChipWhisperer с коробки должен поставляться с 20-контактным ленточным кабелем. Подключите этот кабель к задней части ChipWhisperer, а кабель USB A/B сбоку, как показано на рисунке 8-8. Dmesg должен сообщить о подключении AVRISP mkII, являющегося программатором, который мы и будем использовать для программирования платы. Это позволит нам проводить тестирование, не отключая устройство.  

Рисунок 8-8: Подключение MultiTargetVictim Board 

Наконец, подключите кабель SMA от VOUT на целевой плате к разъему LNA в CH-A на передней панели ChipWhisperer. Таблица 8-2 показывает распиновку. Для наших демонстраций мы по умолчанию будем использовать именно эту распиновку, если не будет указана другая.  

Victim Board ChipWhisperer Компонент 
20-pin connector Задняя панель ChipWhisperer 20-контактный ленточный кабель 
VOUT LNA на CH-A Кабель SMA 
Компьютер Боковая панель ChipWhisperer Кабель Mini USB 
Таблица 8-2: Распиновка MultiTarget Victim Board 

Брутфорс безопасных загрузчиков в атаках по энергопотреблению 

Теперь, когда вы настроили свою Victim Board, мы рассмотрим использование атак по энергопотреблению для брутфорса пароля. Этот тип атак включает изучение энергопотребления различных наборов микросхем для определения уникальных характеристик мощности. Контролируя потребление энергии для каждой инструкции, можно определить тип выполняемой инструкции. Например, NOP-инструкция будет потреблять меньшее количество энергии, нежели, например, MUL-инструкция. Эти различия могут показать, как настроена система, или даже верен ли пароль, поскольку на правильный символ может потребоваться больше энергии, чем на неправильный. 

В следующем примере мы рассмотрим TinySafeBoot (http://jtxp.org/tech/tinysafeboot_en.htm), небольшой загрузчик с открытым исходным кодом, разработанным для систем AVR. Для внесения изменений загрузчику требуется пароль. Чтобы воспользоваться уязвимостью в его методе проверки пароля и получить пароль от чипа, мы будем использовать ChipWhisperer. Эта уязвимость была исправлена в более новых версиях TinySafeBoot, но для практики старая версия включена в папку жертвы в фрейморке ChipWhisperer. Это руководство основано на статье NewAE “Timing Analysis with Power for Attacking TSB”.  

Подготовка к тесту с AVRDUDESS 

Чтобы начать, откройте AVRDUDESS и в выпадающем меню Programmer выберите пункт AVR ISP mkII. Убедитесь, что в поле MCU вы выбрали ATmega 328P, а затем нажмите Detectчтобы убедиться, что вы подключены к ATmega328P (смотрите рисунок 8-9). Выберите флеш-файл hardware/victims/firmware/tinysafeboot-20140331 в поле Flash 

Рисунок 8-9: Программирование TinySafeBoot в AVRDUDESS 

Щелкните Programи AVRDUDESS должен записать программу TinySafeBoot в ATmega. 

Настройка ChipWhisperer для последовательной связи 

Теперь мы готовы к тестированию! Мы будем использовать ChipWhisperer для установки и отслеживания потребления энергии, когда загрузчик будет проверять пароль. Затем мы используем эту информацию, чтобы создать инструмент, который будет взламывать пароль намного быстрее, чем традиционный метод брутфорса. Для начала настройте ChipWhisperer для связи с загрузчиком через его последовательный интерфейс, например, вот так: 

$ cd software/chipwhisperer/capture 
python ChipWhispererCapture.py 

 ChipWhiperer имеет множество опций, поэтому мы шаг за шагом рассмотрим каждый параметр, который вам нужно изменить. 

  1. В ChipWhispererCapture перейдите на вкладку General Settings и для Scope Module установите значение ChipWhisperer/OpenADC, а для Target Module – значение Simple Serial, как показано на рисунке 8-10. 
Рисунок 8-10: Настройки модулей Scope и Target. 
Рисунок 8-11: Настройка соединения и скорости   
  1. Перейдите на вкладку Target Settings (внизу окна) и измените настройку Connection на ChipWhisperer. Затем в разделе Serial Port Settings для TX Baud и RX Baud установите значение 9600, как показано на рисунке 8-11. 
  1. В верхней части экрана нажмите на красный кружок рядом со Scope с DIS внутри. Круг должен стать зеленым и отобразить CON.  
  1. ChipWhisperer имеет простой интерфейс последовательного терминала. Выберите Tools ▸Open Terminal  и откройте его. Вы должны увидеть терминал, подобный изображенному на рисунке 8-12.  
Рисунок 8-12: Последовательный терминал ChipWhisperer 
  1. Установите TX on Enter в нижней части терминала на None, и установите флажок RX: Show non-ASCII as hex (смотрите рисунок 8-12). Теперь нажмите Connect, чтобы активировать текстовые области. 
  1. Введите @@@ (пароль запуска TinySafeBoot) в текстовое поле слева от кнопки Send, и нажмите SendЗагрузчик должен начинать с TSB и содержать информацию о версии прошивки и настройках AVR. TSB – это просто идентификатор, используемый TinySafeBoot, скорее всего, это его аббревиатура. Результат должен совпадать с рисунком 8-12.  

Установка собственного пароля  

Теперь нам нужно установить собственный пароль, при вводе которого мы сможем отслеживать уровни мощности.  

Сначала закройте последовательный терминал. Затем в окно консоли Python, которое находится в центре нижней части главного окна ChipWhisperer, введите следующие строки:  

>>> self.target.driver.ser.write(“@@@”) 
>>> self.target.driver.ser.read(255) 

Последовательную команду self.target.driver.ser.write(“@@@”) мы используем, чтобы отправить в загрузчик текущий пароль. Затем мы вводим последовательную команду self.target.driver.ser.read(255) для чтения следующих 255 байт из загрузчика, чтобы увидеть его ответ на нашу отправку пароля (смотрите рисунок 8-13).  

Рисунок 8-13: Отправка @@@ через консоль Python в ChipWhisperer 

Для удобства присвойте команды чтения и записи их собственным переменным, так вам не нужно будет вводить длинные команды вручную (в следующих примерах предполагается, что вы выполнили этот шаг): 

>>> read = self.target.driver.ser.read 
>>> write = self.target.driver.ser.write 

Пароль хранится на последней странице флэш-памяти устройства. Мы возьмем эту страницу, удалим подтверждение ! из ответа и запишем новый пароль – og –для прошивки. 

Примечание  

Вы найдете более подробное объяснение этой процедуры в руководствах от NewAE (https://www.newae.com/sidechannel/cwdocs/tutorialtimingpasswd.html) или мануалах Python. 

Вернитесь в консоль Python и введите Листинг 8-1: 

>>> write(‘c’) 
>>> lastpage = read(255) 
>>> lastpage = lastpage[:-1] 
>>> lastpage = bytearray(lastpage, ‘latin-1’) 
>>> lastpage[3] = ord(‘o’) 
>>> lastpage[4] = ord(‘g’) 
>>> lastpage[5] = 255 
>>> write(‘C’) 
>>> write(‘!’) 
>>> write(lastpage.decode(‘latin-1’)) 

Листинг 8-1: Изменение последней страницы флэш-памяти для установки пароля на og 

Если время сессии истекло, повторно отправьте @@@, вот так: 

>>> write(“@@@”) 

После того, как вы записали в память новые символы, убедитесь, что og – это новый пароль, используя команду write(“og”), за которой следует read(255) в консоли Python. Обратите внимание, что на рисунке 8-14 мы сначала пытаемся отправить @@@, но не получаем ответа от TinySafeBoot, пока не введем новый пароль – og

Рисунок 8-14: Установка пароля на og 

Сброс AVR 

Сменив пароль, мы можем приступить к считыванию сигналов питания. Сначала нам нужно получить возможность выйти из бесконечного цикла, в который входит система, когда мы вводим неверный пароль. Для этого напишите небольшой скрипт для сброса AVR. Находясь в консоли Python, для создания вспомогательной функции resetAVR, введите следующие команды:  

>>> from subprocess import call 
>>> def resetAVR: 
      call([“/usr/bin/avrdude“, “-c”, “avrispmkII“, “-p”, “m328p”]) 

Настройка АЦП ChipWhisperer 

Теперь необходимо настроить АЦП ChipWhisperer так, чтобы он знал, как записывать кривую мощности. Вернитесь в главное окно ChipWhisperer, выберите вкладку Scope и установите значения, как показано в таблице 8-3 и рисунке 8-15. 

Поле Категория Настройки Значение 
OpenADC Gain Setting Setting 40 
OpenADC Trigger Setup Mode Falling edge 
OpenADC Trigger Setup Timeout 
OpenADC ADC Clock Source EXTCLK x1 via DCM 
CW Extra Trigger Pins Front Panel A Uncheck 
CW Extra Trigger Pins Target IO1 (Serial TXD) Check 
CW Extra Trigger Pins Clock Source Target IO-IN 
OpenADC ADC Clock Reset ADC DCM Push button 
Таблица 8-3: Параметры вкладки Scope для настройки OpenADC для Victim Board 
Рисунок 8-15: Значения АЦП для запуска по последовательной передаче (Serial TX) 

Мониторинг использования энергии при вводе пароля 

Теперь мы будем отслеживать потребление энергии при вводе пароля, чтобы увидеть, сможем ли мы определить разницу в мощности между вводом корректного и некорректного пароля. Мы посмотрим, что произойдет, если мы введем неправильный пароль, который стоит по умолчанию – @@@. Вспомните, что, когда вы вводите неправильный пароль, загрузчик заходит в бесконечный цикл, так что мы можем отслеживать потребление энергии в этот момент. Конечно, вам нужно будет выйти из этого бесконечного цикла, поэтому после того, как вы попробуете неверный пароль и попадете в цикл, сбросьте девайс и попробуйте ввести другой пароль. Для этого перейдите к запросу пароля в консоли Python следующим образом: 

>>> resetAVR() 
>>> write(“@@@”) 

Теперь введите следующую команду с правильным паролем, но пока не нажимайте Enter

>>> write(“og“) 

Щелкните 1 на зеленом значке воспроизведения на панели инструментов, чтобы записать один график мощности. Сразу после этого в консоли Python нажмите Enter. Должно открыться окно Capture Waveform на котором должна отобразиться запись графика питания для корректного пароля (смотрите рисунок 8-16). 

Рисунок 8-16: График мощности корректного пароля 

Детали рисунка 8-16 не так важны; главное, чтобы увидели, как выглядит “хороший” сигнал. Плотные линии, которые вы видите, соответствуют нормальному процессу обработки, а при изменении инструкций обработки наблюдается падение около 8 тысяч на шкале Samples. (Это может быть какой-то процесс при проверке пароля, но на данном этапе мы не будем зацикливаться на деталях).  

Теперь введите неверный пароль – ff: 

>>> resetAVR() 
>>> write(“@@@”) 
>>> write(“ff“) 

Рисунок 8-17 показывает диаграмму мощности для этого пароля.  

Рисунок 8-17: График мощности для пароля без корректных символов 

Вы можете видеть, что программа зависает в своем бесконечном цикле, показания мощности меняются с нормального на почти постоянное нулевое значение.  

Теперь давайте попробуем ввести пароль с первым корректным символом, посмотрим, как изменится график: 

>>> resetAVR() 
>>> write(“@@@”) 
>>> write(“of“) 

На рисунке 8-18 перед там как устройство входит в бесконечный цикл мы можем видеть еще один активный промежуток. Мы видим нормальное потребление энергии, за которым на 8000 следует провал, который мы видели при первом корректном чтении, затем еще некоторое нормальное энергопотребление, прежде чем устройство снова входит в бесконечный цикл с  энергопотреблением 0. 

Рисунок 8-18: График мощности пароля с первым корректным символом 

Примечание  

Вы можете определить размер семплов, используемых для одного корректного символа, измерив длину между провалом на 8000 и бесконечным циклом, который начинается на 16000. В этом случае мы можем грубо приблизиться к тому, что размер выборки для проверки одного символа составляет около 8000. 

Создание скриптов для ChipWhisperer с помощью Python 

Поскольку ChipWhisperer написан на Python, он хорошо поддерживает скрипты, поэтому вы можете легко создать сценарии эти графиков питания для создания брутфорсера, который может очень быстро получить пароль от загрузчика. Установив сценарий проверки того, превышают ли точки данных графика мощности установленный порог, ваш брутфорсер сможет сразу определять, корректен ли целевой символ. Посмотрев на значения данных по оси Y на рисунке 8-18, мы можем увидеть, что при активности значения достигают отметки в 0.1, в то время как находясь в бесконечном цикле это значение колеблется вокруг отметки в 0. Если целевой символ окажется корректным, по оси Y мы увидим значение 0.1, но если никакие данные в диапазоне выборки не достигают 0.1, то мы можем сделать вывод, что устройство находится в бесконечном цикле, а подбираемый символ оказался некорректным. 

Например, если пароль состоит из 255 различных символов с максимальной длинной 3, пароль будет одним из 2553, или 16,581,375 возможных комбинаций. Однако, поскольку мы можем мгновенно определить правильный символ, брутфорсеру, в худшем случае, придется перебрать только 225 * 3, или 765 вариантов. Если символ не соответствует установленному паролю, загрузчик переходит в бесконечный цикл. С другой стороны, этот тип брутфорса не будет иметь никакого успеха, если процедура проверки пароля будет ожидать весь пароль, независимо от корректности некоторых символов. Тот факт, что небольшой код во встроенных системах часто разрабатывается так, чтобы быть максимально эффективным, может сделать его уязвимым для разрушительных тайминг-атак.  

Примечание 

Для получения подробной информации о написании собственного брутфорсера для ChipWhisperer, смотрите туториалы от NewAE. Образец брутфорсера доступен по адресу https://nostarch.com/carhacking/. 

Для этого типа атак могут будут уязвимы загрузчики и любые встроенные системы, которые проверяет корректность введенного кода. Некоторым автомобильным системам для доступа к лоу-левел функциям требуется ответ на запрос или корректный код доступа. Подбор этих паролей может занять неприлично много времени, что делает традиционные методы брутфорса нереальными. Используя анализ мощности для отслеживания процесса проверки паролей или кодов, вы можете получить пароль, сделав то, что раньше казалось нереальным.  

Внесение неисправностей  

Внесение неисправностей, также известное как сбой (glitching), включает в себя атаку на чип, нарушая его нормальные операции, вызывая пропуск выполнения определенных инструкций, например, используемых для обеспечения безопасности. При чтении спецификации любой из микросхем вы увидите, что к диапазону тактовых частот и уровней мощности прилагается предупреждение о том, что несоблюдение этих диапазонов может привести к непредсказуемым результатам – именно этим вы и воспользуетесь при вызове сбоя. В этом разделе вы узнаете, как инжектить ошибки в тактовые частоты и уровни мощности. 

Сбой часов 

Любой ЭБУ или чип, отсчитывая время своих инструкций, будет полагаться на внутренние часы. Каждый раз, когда микроконтроллер получает импульс от часов, он загружает инструкцию, и пока эта инструкция декодируется и выполняется, загружается следующая инструкция. Это означает, что для загрузки и корректного выполнения инструкций необходим стабильный ритм импульсов. Но что, если во время одного из этих тактовых импульсов возникнет сбой? Рассмотрим сбой часов на рисунке 8-19.  

Рисунок 8-19: Нормальный тактовый цикл (вверху) и тактовый цикл со сбоем (внизу) 

Поскольку счетчик команд успевает увеличиться на 1, но не успевает декодировать и выполнить инструкцию до загрузки следующей, микроконтроллер обычно пропускает эту инструкцию. В нижнем цикле на рисунке 8-19 инструкция 3 будет пропущена, поскольку для ее выполнения, перед тем будет выдана следующая инструкция, не хватит времени. Это может быть полезным для обхода некоторых методов защиты, выхода из бесконечных циклов или повторного включения JTAG. 

Чтобы выполнить сбой часов, вам нужно использовать систему быстрее, чем она может работать. Для тренировки идеально подойдет плата программируемой вентильной матрицы (FPGA), но вы также можете проделать этот трюк с множеством других микроконтроллеров. Чтобы выполнить сбой, вам необходимо синхронизироваться с целевыми часами, и во время выдачи инструкции, которую вы хотите пропустить, подать импульс.  

Для демонстрации атаки со сбоем часов мы будем использовать ChipWhisperer и некоторое демонстрационное программное обеспечение, предназначенное для такого рода атак. Настойка Victim Board останется почти такой же, как и для атак по энергопотреблению, за исключением того, что вам нужно изменить перемычки на вывод Clock (в центре платы), которые должны быть установлены только для FPGAOUT (смотрите рисунок 8-20). 

Рисунок 8-20: MultiTargetVictimBoard, установленная для глитч-атак 

Мы настроим ChipWhisperer для управления часами ATmega328. И общие, и целевые настройки останутся такими же, как и в атаке по энергопотреблению, описанной в разделе “Настройка ChipWhisperer для последовательной связи”; единственное исключение – мы установим скорость передачи для TX и RX на 38400. Включите и Scope, и Target, переключившись DIS на CON, как обсуждалось ранее. Рисунок 8-21 и таблица 8-4 показывает полные настройки.  

Рисунок 8-21: Настройки Scope для глитч-атаки 
Поле Категория Настройки  Значение 
OpenADC ADC Clock Frequency Counter Src CLKGEN Output 
OpenADC CLKGEN Settings Desired Frequency 7.37 MHz 
OpenADC CLKGEN Settings Reset CLKGEN DCM Push button 
Glitch module Clock Source   CLKGEN 
CW Extra Trigger Pins Target HS IO-Out Glitch Module 
Таблица 8-4: Настройка главного окна ChipWhisperer для атаки сбоя часов 

Эти настройки дают ChipWhisperer полный контроль над часами целевой платы, и позволят нам загрузить демонстрационную прошивку с ошибками. Прошивку для целевой платформы в структуре ChipWhisperer вы найдете в этом каталоге: hardware/victims/firmware/avr-glitch-examplesОткройте glitchexample.c в вашем любимом редакторе, и перейдите к методу main( внизу кода. Измените glitch1() на glitch3(), и перекомпилируйте прошивку glitchexample для ATmega328p:  

$ make MCU=atmega328p 

Теперь, через AVRDUDESS, как мы это делали в разделе “Подготовка к тесту с помощью AVRDUDESS”, загрузите файл glitchexample.hexПосле загрузки прошивки переключитесь в главное окно ChipWhiperer и откройте последовательный терминал. Нажмите Connectзатем переключитесь на AVRDUDESS и щелкните DetectЭто должно сбросить микросхему, а в терминале вы должны увидеть hello. Введите пароль и нажмите SendЕсли вы ввели неправильный пароль, терминал должен показать FOff и зависнуть, как показано на рисунке 8-22. 

Рисунок 8-22: Пример с введением неверного пароля 

Теперь вернитесь в свой редактор и просмотрите исходный код glitchexample. Как показано в листинге 8-2, это простая проверка пароля: 

for(cnt = 0; cnt < 5; cnt++){ 
    if (inp[cnt] != passwd[cnt]){ 
        passok = 0; 
    } 

 
if (!passok){ 
    output_ch_0(‘F’); 
    output_ch_0(‘O’); 
    output_ch_0(‘f’); 
    output_ch_0(‘f’); 
    output_ch_0(‘\n’); 
} else { 
    output_ch_0(‘W’); 
    output_ch_0(‘e’); 
    output_ch_0(‘l’); 
    output_ch_0(‘c’); 
    output_ch_0(‘o’); 
    output_ch_0(‘m’); 
    output_ch_0(‘e’); 
    output_ch_0(‘\n’); 

Листинг 8-2: Метод проверки пароля для glitch3() 

При введении неверного пароля, passok присваивается значение 0, а на экран выводится сообщение Foff; в противном случае на экран выводится приветствие Итак, наша цель – выполнить сбой часов, которой поможет нам пропустить проверку пароля, либо пропуская инструкцию, которая устанавливает passok на 0 (она никогда не установится на 0), либо переходя непосредственно к приветственному сообщению. Мы выполним последнее, манипулируя шириной и процентами смещения в настройках глитча. 

На рисунке 8-23 показаны некоторые возможные места обнаружения сбоя. Различные микросхемы и инструкции реагируют по-разному, в зависимости от того, где находится ваш глитч, поэтому поэкспериментируйте, чтобы определить, какое место лучше всего подходит в конкретно вашей ситуации. На рисунке 8-23 также показано, как выглядит нормальный тактовый цикл на осциллографе.  Если в настройках ChipWhipserer мы используем положительное смещение, это вызовет кратковременное падение в середине такта. Если мы используем отрицательное смещение, это вызовет кратковременный подъем перед тактовым циклом.  

Мы используем следующие параметры глитча в ChipWhisperer, чтобы вызвать кратковременный подъем перед тактовым циклом, будем использовать смещение на -10%: 

Glitch width %: 7 
Glitch Offset %: -10 
Glitch Trigger: Ext Trigger: Continuous 
Repeat: 1 

Рисунок 8-23: Пример размещения глитчей 

Теперь вернитесь в главное окно ChipWhisperer и настройте CW Extra как показано на рисунке 8-24. Это настроит ChipWhisperer так, чтобы он вызывал сбой часов только когда получит сигнал от триггерной линии.  

Рисунок 8-24: Настройка глитча в настройках CW Extra 

Примечание  

Сбои (glitching) – наука неточная. Разные чипы реагируют на них по-разному, и чтобы выбрать правильные тайминги вам придется много поэкспериментировать с настройками. Даже если вам не удастся использовать сбой часов постоянно, часто одного удачного раза хватает для того, чтобы начать эксплуатировать устройство.  

Установка триггерной линии 

Теперь, когда наш ChipWhisperer настроен для прослушивая сигнала на триггерной линии (trigger line), нам нужно изменить код для использования этой самой линии. Триггерная линия – это пин 16 на коннекторе ChipWhisperer. Когда триггерная линия получает сигнал (пики напряжения), она запускает работу программного обеспечения ChipWhisperer. 

Триггерная линия – это общий метод ввода, используемый ChipWhisperer. Цель состоит в том, чтобы триггерная линия получала сигнал непосредственно перед точкой, которую мы хотим атаковать. Если бы речь шла о каком-то оборудовании, и скажем, мы заметили, что непосредственно перед областью, которую мы хотим атаковать, загорается свет, мы могли бы припаять светодиод к триггерной линии, чтобы ChipWhisperer ожидал до подходящего момента (в этом случае света лампочки).  

В этой демонстрации мы модифицируем прошивку, чтобы триггерная линия срабатывала в той области, где мы хотим внедрить глитч. Сначала мы добавим код к примеру glitch3, показанному в листинге 8-2. Далее, используя ваш любимый редактор добавьте определения из листинга 8-3 в верхнюю часть файла glitchexample.c. 

#define trigger_setup() DDRC |= 0x01 
#define trigger_high()  PORTC |= 0x01 
#define trigger_low()   PORTC &= ~(0x01) 

Листинг 8-3: Установка определений триггеров в glitchexample.c 

Поместите trigger_setup() внутри метода main() непосредственно перед тем, как он напечатает hello,  затем оберните вашу цель триггером, как показано в листинге 8-4: 

  for(cnt = 0; cnt < 5; cnt++){ 
        if (inp[cnt] != passwd[cnt]){ 
            trigger_high(); 
            passok = 0; 
            trigger_low(); 
        } 
    } 

Листинг 8-4: Добавление trigger_high и trigger_low вокруг passok для внедрения глитча 

Теперь перекомпилируйте make MCU=atmega328p и повторно загрузите программу в Victim Board. (Перед загрузкой прошивки обязательно для параметра Glitch Trigger установите значение Manualиначе вы можете случайно вызвать сбой при загрузке микропрограммы). После загрузки микропрограммы переключите опцию Glitch Trigger обратно на Ext TriggerContinous. Теперь введите любой пароль. Если вы получили приветственное сообщение, поздравляю, вы успешно внедрили ошибку, как показано на рисунке 8-25. 

Рисунок 8-25: Успешный обход пароля с помощью внедрения ошибки 

К сожалению, в реальном мире вы, вероятно, не сможете использовать триггерную линию таким же образом, потому что у вас не будет доступа к целевому источнику или событие триггера не будет достаточно близко к месту, где вы захотите внедрить глитч. В таких случаях вам придется поиграть с другими настройками и смещением триггера Ext. Откройте Glitch Monitor в разделе Tools, чтобы поэкспериментировать с различными настройками. 

Сбой питания 

Сбой питания выполняется как и сбой часов: на целевую плату вы подаете надлежащую постоянную мощность, а когда хотите вызвать неожиданные результаты по определенным инструкциям, вы либо понижаете, либо повышаете напряжение, чтобы прервать эту инструкцию. Снижение напряжения часто оказывается безопаснее, поэтому сначала пробуйте снижать. Как и в случае со сбоем часов, каждый микроконтроллер по-разному реагирует на сбой питания, поэтому играйте с разными точками и уровнями мощности, чтобы выстроить профиль сбоя и посмотреть, какие типы поведения можно контролировать.  

Примечание 

Некоторые микроконтроллеры вообще не подвержены сбоям питания, поэтому, прежде чем использовать эту атаку на реальном автомобиле, проверьте ее на своих микросхемах.  

Сбой питания также может влиять на чтение и запись в память. В зависимости от того, какая инструкция выполняется во время сбоя питания, вы можете заставить контроллер заставить считать неверные данные или забыть записать значение.  

 Инвазивное внесение неисправностей 

Поскольку инвазивные атаки с внесением неисправностей требует больше времени и затрат, чем атаки со сбоями, здесь мы их рассмотрим лишь кратко. Однако, если вам нужно выполнить определенную работу и у вас есть ресурсы, инвазивное внедрение ошибок часто является лучшим способом. Загвоздка лишь в том, что он не только не заботится о безопасности цели, но и может ее уничтожить. 

Инвазивное внедрение неисправностей включает в себя физическое вскрытие чипа, обычно с кислотой (азотной кислотой или ацетоном), и использование электронного микроскопа для получения изображения чипа.  Вы можете работать только с верхним или нижним слоем микросхемы или разделить каждый слой и расшифровать каждый из них по отдельности, а также внутреннее устройство чипа в целом. Вы также можете использовать микрозонды и микрозондовую станцию, чтобы направить на цель точный сигнал. Точно также вы можете использовать точечные лазеры или даже направленное обогревание, чтобы вызвать оптические неисправности и замедлить процессы в этой области. Например, если предполагается, что инструкция перемещения занимает два тактовых цикла, вы можете замедлить этот процесс так, чтобы он опаздывал на один цикл.  

Резюме 

В этой главе вы узнали несколько продвинутых методов атаки на встроенные системы; и по мере повышения уровня безопасности автомобилей эти методы атак будут ставать все более ценными. Вы узнали, как определять микросхемы и контролировать потребление энергии, чтобы создать профиль нужных операций. Мы проверили обход пароля путем мониторинга выходной мощности некорректных символов в паролях, чтобы в конечном счете создать приложение для брутфорса, основанное на использовании анализа мощности, чтобы сократить брутфорс пароля до считанных секунд. Вы также увидели, как сбои часов и питания могут приводить к пропуску инструкций в ключевых точках выполнения прошивки, например, во время проверок безопасности или при настройке безопасности JTAG.   

R E D
R E D Автор и переводчик

Отлично переводит книги и статьи.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *