Аппаратные атаки представляют большую угрозу для всех устройств с микроконтроллерами (далее – МК), поскольку с их помощью можно обойти разные механизмы безопасности. От таких атак тяжело защититься программными или аппаратными средствами. Для примера можно прочитать статью от STMicroelectronics про различные виды аппаратных атак и методы защиты МК.
Мы – команда Raccoon Security – заинтересовались этой темой, поскольку одним из направлений деятельности нашей компании является разработка embedded-устройств, в том числе содержащих механизмы защиты информации. По большей части нас интересуют glitch-атаки, поскольку они позволяют проскользнуть мимо исполняемых инструкций МК. Это серьезная угроза для конфиденциальной информации, содержащейся в МК, и самое опасное последствие таких атак – считывание закрытой прошивки в обход механизмов безопасности, предусмотренных разработчиками МК.
На конференциях Hardwear.io 2018 в Гааге и EmbeddedWorld 2019 в Нюрнберге компания NewAE демонстрировала устройство ChipWhisperer, позволяющее реализовать ту часть неинвазивных аппаратных атак, которые не требуют глубинных знаний наноэлектроники и наличия специфического оборудования. При помощи этого устройства мы изучили безопасность embedded-устройств и поняли, как минимизировать результат подобных атак. Под катом – что у нас получилось.
ChipWhisperer
Комплект ChipWhisperer представляет собой набор инструментов с открытым исходным кодом для анализа безопасности наиболее популярных МК (STM, Xmega, Intel D2000, SAM, LPC, MSP, 78K и других) и ПЛИС. Проект стартовал 27 февраля 2015 года на Kickstarter. На данный момент существуют разные версии ChipWhisperer (все варианты можно найти в каталоге). Они имеют разный набор инструментов, но в целом заточены на следующие виды аппаратных атак:
• атаки side-channel (SCA);
• glitch-атаки.
Для дальнейшего анализа мы выбрали ChipWhisperer-Pro (CW1200), который является самой старшей моделью ChipWhisperer на данный момент и имеет широкий функционал и большую комплектацию:
Комплект ChipWhisperer (CW1200)
На борту у CW1200 имеется осциллограф, который состоит из регулируемого усилителя и АЦП с выборкой 105 MSPS. Такой набор инструментов позволяет зарегистрировать уровень сигнала в сотые доли милливольта и получить хорошую временную развертку. Также в CW1200 имеются порты для организации CLK-glitch и Vcc-glitch, GPIO-порты, которые можно назначить как входные триггеры для отслеживания происхождения какого-либо события (запрос ввода пароля, статус загрузки и т.д.). CW1200 подключается к ПК по USB и имеет два протокола обмена с МК: UART и SPI.
Для работы с ChipWhisperer необходимо установить драйверы, скачать Python-библиотеки и рабочие примеры с GitHub либо загрузить подготовленный образ виртуальной машины на Linux, в которой предустановлены все библиотеки и рабочие примеры. В этих открытых библиотеках содержатся:
• протокол общения с ChipWhisperer;
• математические алгоритмы обработки атак на популярные методы шифрования;
• протоколы общения с загрузчиками (bootloader) популярных МК;
• подготовленные прошивки для прохождения обучения на платах с МК, идущих в комплекте.
Мы решили пройти все руководства (tutorials), размещенные на старом сайте NewAE. Сейчас разрабатывается еще один ресурс, где представлена более актуальная информация и есть форум.
В данной статье мы представим лишь несколько примеров руководств от разработчиков ChipWhisperer и реализуем их не на платах с МК, идущих в комплекте, а на STM32F103RBT6:
Плата STM32F103RBT6
Также мы написали код, идентичный их подготовленным примерам, но с библиотеками HAL, сгенерированными из CubeMX. Все эти действия нужны для подтверждения того, что атаки с ChipWhisperer могут быть реализованы на любых случайных устройствах, а не только на платах, присутствующих в комплекте.
Далее представим краткий обзор и примеры SCA-атаки и glitch-атак.
SCA-анализ
В основе SCA-атак лежит отслеживание изменений внешних факторов состояния МК (ток потребления МК, температура, электромагнитное поле) при отработке им различных инструкций. В ChipWhisperer реализованы каналы наблюдения за питанием при помощи АЦП и за электромагнитным полем при помощи антенны.
SCA-анализ эффективен при обнаружении паролей, ключей шифрования и т.д. На сайте NewAE представлено много различных
полезных руководств по нахождению ключей шифрования и по SCA-атакам, но мы приведем лишь один пример SCA-анализа, поскольку для нас наибольший интерес представляют именно glitch-атаки.
Пример SCA-атак – анализ сигнатур по питанию
В этом руководстве демонстрируется один из видов SCA-атак – отслеживание посимвольного ввода пароля путем наблюдения за сигнатурами по каналу питания. По повторяющимся сигнатурам питания можно выявить отработку различных программных инструкций внутри МК. В приведенном примере представлена отработка МК ввода пароля при помощи отслеживания сигнатуры операции break
.
Приступим к подготовке. В первую очередь необходимо выполнить подключения согласно рисунку:
Подключение МК для SCA-анализа
На схеме зачеркнуты компоненты, которые не нужно подключать (в отличие от стандартного подключения МК). Стрелками обозначены места подключения ChipWhisperer, а подписями – его пины.
Подготовим прошивку МК. В главном цикле while(1)
находится следующая функция:
028 void password_check() {
029 char passwd[32];
030 char correct_passwd[] = "Vulkan";
031 HAL_Delay(10);
032 uart_send("WARNING: UNAUTHORIZED ACCESS WILL BE PUNISHEDn");
033 led_off();
034
035 //Get password
036 uart_send("Please enter password to continue: ");
037 uart_receive(passwd, 32);
038
039 uint8_t passbad = 0;
040
041 led_on();
042
043 for(uint8_t i = 0; i < sizeof(correct_passwd); i++)
044 {
045 if (correct_passwd[i] != passwd[i])
046 {
047 passbad = 1;
048 break;
049 }
050 }
051
052 if (passbad)
053 {
054 //Stop them fancy timing attacks
055 int wait = rand() % 100000;
056 for(volatile int i = 0; i < wait; i++)
057 {
058 ;
059 }
060 HAL_Delay(4);
061 uart_send("PASSWORD FAILn");
062 }
063 else
064 {
065 uart_send("Access granted, Welcome!n");
066 }
067 while(1)
068 {
069 ;
070 }
071 }
В строке 030 задан пароль для входа – Vulkan. Далее включается светодиод
led_on()
и отсылается сообщение по UART о запросе пароля. Функция led_on()
активирует GPIO-пин PA12 МК и оповещает о событии, относительно которого ChipWhisperer начнет накапливание осциллограмм. Именно к этому пину и должен быть подключен CW_TRIG. Все это «засинтезировано» для удобства, но и в реальных случаях разница будет незначительной, поскольку можно ввести временную задержку по количеству тактов CLOCK относительно любого события, к которому подключается CW_TRIG. Например, это может быть начало загрузки МК, прием/передача сообщения, включение светодиода и т.д.
Далее МК ожидает ввода пароля, который он будет проверять посимвольно. Если какой-либо символ в очереди не совпадет, например три символа верны, а четвертый – нет, тогда нужно выйти из цикла for оператором break
и сообщить о неверном пароле. В строках 055–059 реализован генератор случайной задержки. Такая конструкция чаще всего применяется для усложнения проведения временных атак (т. е. отслеживания изменения времени отклика всей системы). Эта конструкция включена для понимания того, что подбор пароля методом временных атак нами не производился.
Программный код руководства в Jupyter Python размещен на соответствующем ресурсе. На рисунке ниже приведен пример ввода пароля с выводом осциллограммы питания МК с каждым новым верным символом. Отметим, что с посимвольным вводом верного пароля (вводимый пароль приведен в верхней части рисунка) сдвигается сигнатура операции break
в строке 046 (на рисунке ниже выделено оранжевым цветом). В этом заключается «слабость» прерывания операцией break
при посимвольной проверке пароля.
Осциллограммы пароля
В результате ознакомления с этим руководством мы выяснили, насколько просто обойти защиту паролем при таком подходе к его проверке с применением SCA-анализа. Достаточно закомментировать в этой прошивке операцию break
в строке 048 и в целом проверка пароля будет проходить так же успешно, но отслеживание отработки сигнатур уже усложнится. Поэтому, чтобы снизить эффективность подобных атак, стоит избегать операций немедленных прерываний циклов проверки.
Сложность подобного анализа заключается в обнаружении необходимых сигнатур. Поэтому проведение подобных атак может значительно усложнить введение временных конструкций rand()
в момент проверки пароля, добавление дополнительных вычислений или добавление шума другими компонентами.
Glitch-атаки
Glitch-атаки проводятся серией кратковременных импульсов в точный момент времени по определенному методу воздействия. Наиболее популярные методы: по тактовому сигналу (CLK-glitch), питанию (Vcc-glitch) и при помощи электромагнитного поля. Электромагнитное поле порождается высоковольтной искрой вблизи МК. Для этого компания NewAE использует оборудование ChipSHOUTER. Мы его не закупали, поэтому провели только атаки CLK-glitch и Vcc-glitch.
Glitch-атаки осуществляются добавлением импульса по напряжению: для CLK-glitch – во внешний CLOCK-сигнал МК (от внешнего кварца или генератора), для Vcc-glitch – по питанию.
В целом glitch-атаки позволяют обойти какую-либо инструкцию МК, например, ввод пароля, запрос на доступ, лицензионное соглашение и т.д. Glitch-атаки относятся к более сложным, кропотливым и требуют больших временных затрат. Кроме того, необходимо неоднократно повторять glitch-атаку, поскольку ее успешность имеет вероятностный характер и зависит от параметров импульса. Ниже перечислены параметры glitch:
• scope.glitch.width – ширина импульса в процентах относительно CLOCK;
• scope.glitch.offset – смещение импульса в процентах относительно CLOCK;
• scope.glitch.repeat – количество повторений импульсов атак;
• scope.glitch.ext_offset – количество пропущенных тактов после срабатывания триггера события.
Отображение параметров glitch для CLK-glitch и Vcc-glitch приведены на временных диаграммах:
Временная диаграмма для CLK-glitch
Временная диаграмма для Vcc-glitch
Все параметры glitch-импульса подбираются так, чтобы ядро МК работало в нестабильном режиме (за счет чего и происходит пропуск инструкций).
По результатам проведения glitch-атак было выявлено, что при слишком малом значении параметра scope.glitch.repeat не происходит «проскальзывание» инструкций. Если же задать большое значение, то можно пропустить не только необходимую инструкцию, но и все последующие. В большинстве случаев достаточно искать scope.glitch.repeat в районе 5–25. В отношении остальных параметров все зависит от вида атаки и условий подключений.
CLK-glitch
CLK-glitch-атаки осуществляются добавлением в сигнал CLOCK МК импульсов более короткой длительности. Поэтому CLOCK необходимо отключить от МК и подать его из ChipWhisperer уже с CLK-glitch-атакой.
Сначала необходимо подключить ChipWhisperer к МК:
Схема подключения для проведения CLK-glitch
Весь Python-код и подробное описание руководства представлены на ресурсе. Далее в STM32F103RBT6 «зальем» прошивку, где в основной цикл while(1)
добавлена следующая функция:
075 void glitch_password(void)
076 {
077 char inp[16];
078 char c = 'A';
079 unsigned char cnt = 0;
080 uart_send("Password:");
081
082 while((c != 'n') & (cnt < 16))
083 {
084 c = getch();
085 inp[cnt] = c;
086 cnt++;
087 }
088
089 char passwd[] = "Vulkan";
090 char passok = 1;
091
092 led_on();
093 led_off();
094
095 //Simple test - doesn't check for too-long password!
096 for(cnt = 0; cnt < 5; cnt++)
097 {
098 if (inp[cnt] != passwd[cnt])
099 {
100 passok = 0;
101 }
102 }
103 if (!passok){
104 uart_send("Deniedn");
105 }
106 else
107 {
108 uart_send("Wow! Vulkan win!n");
109 }
110 }
Наша цель – обойти инструкцию if
в строке 103 при введении неверного пароля и попасть в случай else
на строке 106. Самое важное в этой атаке – оказаться в момент проверки переменной passok
в строке 103. Для этого необходимо подобрать параметр scope.glitch.ext_offset. Это проще всего сделать, подключив осциллограф к UART и выставив glitch по местоположению помех, поскольку glitch просачивается через весь МК:
Местоположение glitch
Код атаки и методика взяты из этого руководства (раздел Attack loop, блоки 9–10). Единственное, что мы изменили в коде – включили вывод всех сообщений print(response)
без фильтрации, поскольку важные события часто пропускаются из-за настроенных фильтров типа:
if need_response not in response:
pass
else:
print ("УРА!")
На рисунках ниже приведены примеры журнала вывода сообщений, отображающихся при близкой к успеху CLK-glitch-атаке или далекой от успеха. При приближении к правильным параметрам glitch начинают появляться нестабильности в работе МК (обрываются сообщения, МК переходит в перезагрузку). Это может быть подсказкой при поиске.
Вывод сообщений при glitch-атаке при параметрах, далеких от успешных (а) и близких к успеху (б)
Результат успешной атаки CLK-glitch
В результате проведения атак было выявлено, что параметры CLK-glitch-импульса могут «плавать» в зависимости от качества подключения ChipWhisperer к CLOCK МК. Например, при установлении щупа осциллографа на пин CLOCK параметр scope.glitch.offset становился другим для успешной атаки, поскольку у щупа есть свои емкостно-индуктивные параметры, которые вносят коррективы в высокочастотный glitch. Так что подключение через длинный неэкранированный кабель может преподнести свои сюрпризы. В остальном атаки CLK-glitch можно назвать стабильными, т.к. их параметры менялись незначительно для различных инструкций (были проверены if, for, while).
Метод защиты от подобных атак заключается в использовании внутреннего сигнала CLOCK МК, но он имеет худшую температурную и временную стабильность. Также эффективным методом может оказаться введение случайной временной задержки перед важными инструкциями и после них (проверки паролей, личных данных и т.д.), что может усложнить точное попадание импульса CLK-glitch в нужный момент.
Vcc-glitch
Vcc-glitch, как и CLK-glitch, вносит высокочастотную помеху в работу МК, только уже кратковременным замыканием питания МК на землю. При проведении Vcc-glitch-атак необходимо учитывать, что параметры успешного импульса зависят от множества факторов, таких как:
• особенности конструкции печатной платы для МК и наличие разнообразной обвязки;
• длина коаксиального кабеля подключения МК и glitch-порта ChipWhisperer (чем длиннее кабель, тем меньше вероятность успешной атаки, оптимальная длина – 10–15 см);
• серия МК;
• инструкция, которую необходимо пропустить;
• оптимизация компилятора МК;
• тип MOSFET-транзистора (связано с различием высокочастотных составляющих S-параметров).
Поэтому при проведении атак необходимо следить за тем, чтобы эти параметры не изменялись.
Сначала следует подключить ChipWhisperer к МК:
Схема подключения для проведения Vcc-glitch-атак
Далее «зашиваем» прошивку в МК, где в главном цикле while(1)
находится следующая функция:
115 void glitch_while()
116 {
117 volatile uint8_t infinity = 0;
118 uart_send(" Hello habr!");
119 led_on();
120 led_off();
121
122 while(infinity != 2)
123 {
124 ;
125 }
126 uart_send("WOW!!! Vcc Glitch work!");
127 while(1)
128 {
129 ;
130 }
131 }
МК после передачи сообщения «Hello habr!» уходит в бесконечный цикл в строке 122. Наша задача – вывести МК из этого цикла при помощи Vcc-glitch. В этом цикле в качестве условия используется переменная volatile uint8_t infinity
, которая при нормальном течении программы никогда не будет равна двум. Если бы мы поставили while(1)
вместо while(infinity != 2)
, то компилятор проигнорировал бы код ниже, включая и наше сообщение, извещающее о выходе из бесконечного цикла. Из-за переменной типа volatile
компилятор не сможет этого сделать. Цикл while(1)
в строке 127 добавляется, чтобы после сообщения WOW!!! Vcc Glitch work! у нас не отобразилось вновь Hello habr!
Мы использовали Python-код для управления ChipWhisperer из этого руководства. Вот какие сообщения от МК были получены:
Результат успешной Vcc-glitch-атаки
Как видно из рисунка, Vcc-glitch-атака прошла успешно.
Сложность в проведении Vcc-glitch-атаки заключается в подборе верных параметров импульса. Реализация этой атаки заняла больше всего времени по сравнению с остальными, поскольку успешное проведение Vcc-glitch-атак зависит от факторов, описанных выше.
Методом защиты от подобных атак также может быть введение случайной временной задержки перед важными инструкциями и после них (проверки паролей, личных данных и т. д.). Это может усложнить точное попадание Vcc-glitch-импульса в нужный момент. Также может незначительно помочь увеличение емкостной связи между питанием и землей при разводке печатной платы.
Выводы
Проведенные атаки позволяют обойти инструкции в МК. Пример SCA-анализа показал, что даже самый простой вид такой атаки может угрожать безопасности ваших данных (паролей, ключей шифрования). Мы убедились, что glitch-атаки позволяют обойти различные инструкции и предусмотренные в устройствах программные методы защиты. Универсальным методом защиты от атак в рассмотренных руководствах может быть введение случайных временных задержек при исполнении в МК важных инструкций.
На этом наше исследование аппаратных атак не заканчивается. В дальнейшем мы планируем изучить возможность обхода проверки байта защиты прошивки МК с помощью Vcc-glitch-атак. Доступ к прошивке МК может открыть большие возможности для злоумышленника: от клонирования устройства с целью перепродажи до полного доступа ко всей закрытой информации и контроля над МК.
В своих экспериментах с Vcc-glitch мы попробовали обойти защиту прошивки, и у нас это получилось. Мы убедились, что это возможно. Эксперименты, демонстрирующие чтение скрытой прошивки МК, мы представим в следующей статье.
Raccoon Security – специальная команда экспертов НТЦ «Вулкан» в области практической информационной безопасности, криптографии, схемотехники, обратной разработки и создания низкоуровневого программного обеспечения.
Автор: RaccoonSecurity