Часть III. Техники защиты и криминалистики

Глава 17. Как работает Безопасный запуск UEFI

Содержание

Глава 17. Как работает Безопасный запуск UEFI
Что представляет собой Безопасный запуск?
Подробности реализации Безопасного запуска UEFI
Последовательность запуска
Аутентификация исполнения при помощи цифровых подписей
База данных db
База данных dbx
Аутентификация на основе времени
Ключи Безопасного запуска
Ключ обмена ключами
Ключ платформы
Безопасный запуск UEFI: полная картина
Политики Безопасного запуска
Защита от буткитов при помощи безопасной загрузки
Атаки на Безопасный запуск
Исправление встроенного ПО PI для запрета Безопасного запуска
Модификация переменных UEFI для обхода проверок безопасности
Защита Безопасного запуска через Подтверждённый и выверенный запуск
Подтверждённый запуск
Выверенный запуск
Защитник запуска Intel
Поиск необходимого ACM
Эксплуатация FIT
Настройка защитника запуска Intel
Доверенная плата запуска ARM
Зона доверия ARM
Загрузчики запуска ARM
Поток Доверенного запуска
Подтверждённый запуска против руткитов встроенного ПО
Заключение

В предыдущих главах мы рассуждали относительно введения определённой политики подписей кода режима ядра, что способствует разработчиками вредоносного программного обеспечения (ПО) перемещаться с использования руткитов к применению буткитов, смещая направление атаки с ядра ОС в сторону незащищённых компонентов запуска. Такой вид вредоносного ПО выполняется до загрузки соответствующей ОС, а потому он обладает способностью обхода или отключения механизмов безопасности ОС. Для усиления безопасности и гарантии сохранности, в таком случае, ОС должна иметь возможность загружаться в некую доверенную среду, компонентам которой не был нанесён ущерб.

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

Однако, предлагаемая безопасным запуском UEFI защита обладает уязвимостями к руткитам встроенного ПО, самой современной и наиболее быстро растущей технологии вредоносного ПО. Как результат, вам требуется иной уровень безопасности для покрытия всего процесса запуска, с самого начала. Вы можете достичь этого путём реализации Безопасного запуска (Secure Boot), носящего название Verifed and Measured Boot (Подтверждённого и выверенного запуска).

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

Как это часто происходит в устоявшейся индустрии безопасности, тем не менее, очень небольшое число решений в области безопасности способно обеспечивать предельную защиту от атак; нападающие и обороняющиеся блокированы вечной гонкой вооружений. Мы завершим эту главу обсуждением потоков Безопасного запуска UEFI, способов их обода и того как защищать его при помощи двух версий Подтверждённого и выверенного запуска от Intel и ARM.

Что представляет собой Безопасный запуск?

Основная цель Безопасного запуска состоит в предотвращении кем бы то ни было исполнения кода без авторизации в некой имеющейся среде предзагрузки (preboot environment); тем самым допускается выполнение исключительно кода, который отвечает политике целостности данной платформы. Эта технология очень важна для платформ с высокой степенью гарантии и она также часто применяется во встроенных устройствах и мобильных платформах, поскольку она позволяет производителям ограничивать платформы подтверждённым производителем программным обеспечением, например операционной системы iOS на iPhones или Windows 10.

Безопасный запуск поставляется в трёх формах, которые зависят от значения уровня иерархии самого процесса запуска, на котором выполняется принуждение к нему:

Безопасный запуск ОС

Реализуется на уровне начальной загрузки соответствующей ОС. Он проверяет загружаемые начальным загрузчиком ОС компоненты, такие как соответствующее ядро ОС и загрузочные драйверы.

Безопасный запуск UEFI

Реализуется во встроенном ПО UEFI. Он проверяет драйверы DXE и приложения UEFI, предлагаемые ПЗУ и начальные загрузчики ОС.

Безопасный запуск платформы (Подтверждённого и выверенного запуска)

Закреплён в аппаратных средствах. Проверяет инициализацию встроенного ПО платформы.

Мы уже обсуждали безопасность процесса запуска в Главе 6, а потому в данной главе мы сосредоточимся на безопасном запуске UEFI и Подтверждённом и выверенном запуске

Подробности реализации Безопасного запуска UEFI

Мы начнём данное обсуждение с того как работает Безопасный запуск UEFI. Прежде всего, важно отметить, что безопасный запуск UEFI является частью общей спецификации UEFI, которую можно найти в http://www.uefi.org/sites/default/files/resources/UEFI_Spec_2_7.pdf. Мы будем применять данную спецификацию в качестве справочного материала - иными словами, основного описания того как Безопасный запуск UEFI предполаает выполнять работу - хотя различные производители платформ могут иметь различные детали реализации.

[Замечание]Замечание

Когда мы начиная с текущего момента в данном разделе ссылаемся на "Безопасный запуск", мы подразумеваем Безопасный запуск UEFI, если не оговорено обратное.

Мы начнём с рассмотрения самой последовательности запуска чтобы увидеть где вступает в действие Безопасный запуск. Затем мы рассмотрим как Безопасный запуск выполняет аутентификацию исполняемого кода и обсудим вовлекаемые в это базы данных.

Последовательность запуска

Давайте по- быстрому повторно пройдёмся по имеющейся последовательности запуска UEFI, описанной в Главе 14 чтобы увидеть в какой момент вступает в действие Безопасный запуск. Если вы пропустили эту главу, будет не лишним посетить её сейчас.

Если вы обратитесь назад к Как работает встроенное ПО UEFI, вы увидите, что самой первой выполняемой кодом после прохождения системой сброса вещью является инициализация платформенного (PI, platform initialization) встроенного ПО, которая выполняет базовую инициализацию оборудования данной платформы. После осуществления PI, её набор микросхем и контроллер памяти всё ещё пребывают в неком состоянии без инициализации: Ещё пока никакая оперативная память (ОЗУ, DRAM) не доступна для данного встроенного ПО, а периферийные устройства на имеющейся шине PCIе пока ещё не было пронумерованы. (Такая шина PCIe является высокоскоростной последовательной шиной, стандартно применяемой практически во всех современных ПК; мы обсудим её дополнительно в последующих главах.) В данный момент времени Безопасный запуск ещё пока не задействован, что означает, что эта часть PI встроенного ПО рассматриваемой системы не защищено в это время.

После того как этот PI встроенного ПО обнаружит и настроит ОЗУ, а также выполнит инициализацию своей платформы, он продолжит загружать драйверы DXE и приложения UEFI, которые в свою очередь продолжат инициализацию оборудования своей платформы. Именно здесь вступает в игру Безопасный запуск. Заякоренный в этом PI встроенного ПО, Безопасный запуск применяется для аутентификации тех модулей UEFI, которые загружаются с установленного флеша SPI (Serial Peripheral Interface, Последовательного интерфейса периферии) или из предлагаемого ПЗУ периферийных устройств.

Сам применяемый в Безопасном запуске механизм аутентификации представляет, по существу, некий процесс удостоверения цифровой подписи. Исполнение разрешается исключительно в надлежащем виде подписанным образам. Безопасный запуск для управления ключами проверки подписи полагается на PKI (public key infrastructure, инфраструктуру открытых ключей).

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

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

[Замечание]Реализации реальной практики: компромиссы

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

Аутентификация исполнения при помощи цифровых подписей

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

Дя исполняемых файлов UEFI, которые являются образами PE (Portable Executable, {формат Windows}), значения цифровых подписей содержатся в неких особых структурах данных с названием signature certifcates (сертификаты подписи). Местоположение этих сертификатов в их двоичном представлении определяется специальным полем в структуре данных заголовка данного PE с наименованием Certifcate Table Data Directory (Каталог данных таблицы сертификатов), проиллюстрированном на Рисунке 17-1. Не лишним будет отметить, что для одного файла может иметься множество цифровых подписей, выработанных с различными ключами подписей для разнообразных целей. Просмотрев это поле, наше встроенное ПО UEFI может определить местоположение сведений о необходимой подписи, применяемых для аутентификации данного исполняемого кода.

 

Рисунок 17-1


Местоположение цифровых подписей в образах UEFI

Другие типы исполняемых образов UEFI, таких как образы TE (Terse Executable) не имеют встроенных цифровых подписей по причине специфики своих форматов. такой формат образа TE был производным от формата PE/ COFF в попытке снижения размера получаемого TE с тем, чтобы он занимал меньшее пространство. Тем самым, образы TE содержат лишь те поля, которые требуются для исполнения в некой среде PE соответствующего формата PE, что подразумевает что они не содержат подобных Certifcate Table Data Directory полей. Как результат, встроенное ПО UEFIне имеет возможности напрямую выполнять аутентификацию подобных образов, проверяя их цифровую подпись. Те не менее, Безопасный запуск предоставляет возможности для аутентификации подобных образов при помощи криптографического хэширования, некого механизма, который более подробно описан в нашем следующем разделе.

Схема встроенного сертификата подписи зависит от его типа. Мы бы не хотели вдаваться в подробности схемы здесь, но вы можете ознакомиться с ними в разделе Расположение подписей драйвера.

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

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

Однако простой проверки на соответствие данной подписи не достаточно для установления доверия в неком исполняемом кодеUEFI. Встроенное ПО UEFI также должно обеспечить что этот исполняемый код подписан неким авторизованным ключом. В противном случае ничто не препятствует кому бы то ни было выработать какой- то индивидуальный ключ подписи и подписать им образ вредоносного ПО с тем чтобы он прошёл проверку Безопасного запуска.

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

База данных db

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

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

В соответствии с имеющейся спецификацией UEFI такая база данных подписей хранится в переменной энергонезависимой памяти (NVRAM), которая неизменна между перезагрузками данной системы. Конкретная реализация переменных NVRAM является специфической для платформ и различные головные изготовители оборудования (OEM, original equipment manufacturers) может реализовывать их различными способами. Как правило, эти переменные хранятся в том же самом флеше SPI, который содержит и встроенное ПО платформы, например, в самом BIOS. Как вы увидите в разделе Модификация переменных UEFI для обхода проверок безопасности, это приводит к уязвимостям, которые вы можете применять для обхода Безопасного запуска.

Давайте проверим имеющееся содержимое конкретной базы данных db в вашей собственной системе выводя дамп содержимого той переменной NVRAM, которая удерживается вашей базой данных. Мы воспользуемся для своего примера платформой Lenovo Thinkpad T540p, но вам надлежит применять любую из платформ, с которой вы работаете. Вы выдадим дамп имеющееся содержимое своей переменной NVRAM при помощи инструментария с открытым исходным кодом Chipsec, с которым вы уже встречались в Главе 15. Этот инструментарий обладает богатой функциональностью, полезной для криминалистического анализа, и мы будем обсуждать его более подробно в Главе 19.

Выгрузите инструментарий Chipsec с GitHub. Этот инструментарий имеет зависимостью winpy (расширений Python для Windows), которую вам потребуется выгрузить и установить перед запуском Chipsec. После получения и того и другого, откройте приглашение командной строки или иной интерпретатор командной строки и перейдите в тот каталог, который содержит выгруженный вами инструмент Chipsec. Затем для получения списка переменных вашего UEFI введите такую команду:


$ chipsec_util.py uefi var-list
		

Эта команда выводит дамп всех переменных UEFI из вашего текущего каталога в подкаталог ef_variables.dir и декодирует содержимое некоторых из них (Chipsec декодирует лишь содержимое известных переменных). Перейдите в этот каталог и вы должны обнаружить нечто схожее с Рисунком 17-2.

 

Рисунок 17-2


Выводимые дампом Chipsec переменные UEFI

Каждая запись в этом каталоге соответствует отдельной переменной NVRAM UEFI. Названия этих переменных обладают установленной структурой VarName_VarGUID_VarAttributes.bin, в которой VarName это название данной переменной, VarGUID является значением переменной GUID (16- байтового глобально уникального идентификатора), а VarAttributes это список атрибутов этой переменной в краткой форме. На основании имеющейся спецификации UEFI здесь у нас на Рисунке 17-2 представлены некоторые значения атрибутов соответствующих записей.

NV

Энергонезависимая (Nonvolatile), что означает что содержимое переменной остаётся неизменным при перезагрузках.

BS

Может быть доступной из служб запуска (boot service) UEFI. Службы запуска UEFI обычно доступны на протяжении времени запуска до того как запустится загрузчик ОС. После запуска загрузчика ОС эти службы запуска UEFI более недоступны.

RT

Может иметь доступ из служб времени исполнения (runtime) UEFI. В отличии от служб запуска UEFI, 'nb' службы времени исполнения остаются на протяжении загрузки соответствующей ОС и в процессе времени исполнения этой ОС.

AWS

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

TBAWS

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

Когда в данной платформе настроен Безопасный запуск и имеется необходимая переменная db, вам надлежит отыскать подчинённую папку в данном каталоге с названием, начинающимся с db_D719B2CB-3D3A-4596-A3BC-DAD00E67656F. Когда Chipsec выводит дамп соответствующей переменной UEFI db, он автоматически декодирует содержимое этой переменной в такой подкаталог, который содержит файлы, относящиеся к сертификатам общедоступных ключей и хэш- значений авторизованных для исполнения образов UEFI. В нашем случае мы обладаем пятью файлами - четыре сертификата и один хэш SHA256, что отражено на Рисунке 17-3.

 

Рисунок 17-3


Содержимое переменной UEFI базы данных подписей

Эти сертификаты закодированы посредством X.509, некого криптографического стандарта, который определяет устанавливаемый формат сертификатов общедоступного ключа. Мы можем декодировать эти сертификаты для получения сведений относительно их эмитента, что сообщит нам чья подпись будет передана проверке Безопасного запуска. Для этого мы воспользуемся инструментарием openSSL, описанном в блоке Инструментарий OpenSSL. Установите этот инструментарий из GitHub, а затем запустите его нашей следующей командой, заменив certificate_file_path на тот каталог, в котором содержится openSSL в вашем компьютере:


$ openssl x509 -in certificate_file_path
		

В операционной системе Windows просто замените расширение полученного файла сертификата X.509 с bin на crt и откройте этот файл Проводником (Explorer) для просмотра полученного результата своего декодирования. Таблица 17-1 отображает наши результаты с соответствующими эмитентами и предметами имеющихся сертификатов.

Таблица 17-1. Декодированные сертификаты и хэши из рассматриваемой переменной UEFI
Filename Issued to Issued by

X509-7FACC7B6-127F-4E9C-9C5D-080F98994345-03.bin

Thinkpad Product CA 2012

Lenovo Ltd. Root CA 2012

X509-7FACC7B6-127F-4E9C-9C5D-080F98994345-04.bin

Lenovo UEFI CA 2014

Lenovo UEFI CA 2014

X509-77FA9ABD-0359-4D32-BD60-28F4E78F784B-01.bin

Microsoft Corporation UEFI CA 2011

Microsoft Corporation Third-Party Marketplace Root

X509-77FA9ABD-0359-4D32-BD60-28F4E78F784B-02.bin

Microsoft Windows Production PCA 2011

Microsoft Root Certifcate Authority 2010

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

 
[Замечание]Инструментарий OpenSSL

OpenSSL является библиотекой с открытым исходным кодом, которая реализует протоколы Secure Socket Layer и Transport Layer Security, а также криптографические примитивы общего назначения. Под лицензией в стиле Apache OpenSSL часто используется в коммерческих и некоммерческих приложениях. Эта библиотека предлагает богатые функциональные возможности для работы с сертификатами X.509, будете ли вы выполнять синтаксический разбор имеющихся сертификатов, или вырабатывать свои собственные. Сведения об этом проекте вы можете найти на https://www.openssl.org/.

База данных dbx

В противовес db, база данных dbx содержит сертификаты общедоступных ключей и хэш- значений исполняемых кодов UEFI, которым запрещено выполнение в момент запуска. Эта база данных также имеет название Revoked Signature Database (базы данных отозванных подписей) и она в явном виде перечисляет образы, которым будет отказано в проверке Безопасным запуском, что предотвращает запуск модуля с с известной уязвимостью, которая способна скомпрометировать общую безопасность всей платформы целиком.

Мы изучим содержимое своей базы данных dbx тем же самым способом, который мы применяли для базы данных подписей db. Среди тех папок, которые были выработаны когда вы запускали инструмент Chipsec, вы обнаружите папку ef_variables.dir, которая должна содержать вложенную папку, начинающуюся с dbx_D719B2CB-3D3A-4596-A3BC-DAD00E67656f. Эта папка содержит сертификаты и хэши запрещённых образов UEFI. В нашем случае, эта папка содержит 78 хэшей и никаких сертификатов, что отображено на Рисунке 17-4.

 

Рисунок 17-4


Содержимое переменной UEFI базы данных dbx (базы данных отозванных подписей)

Рисунок 17-5 отображает общий алгоритм проверки подписи образа, применяющий обе базы данных, db и dbx.

 

Рисунок 17-5


Алгоритм проверки Безопасного запуска UEFI

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

Аутентификация на основе времени

Дополнительно к своим базам данных db и dbx, Безопасный запуск применяет две другие базы данных с названиями dbt и dbr. Первая из них, dbr, содержит сертификаты общедоступных ключей, применяемые для проверки значений подписей своего загрузчика восстановления ОС. Мы не будем его много обсуждать.

Вторая, dbx, содержит сертификаты с временными отметками, применяемыми для проверки значения временной отметки цифровой подписи некого исполняемого кода UEFI, тем самым делая возможной аутентификацию на основании времени (TBAWS, time-based authentication) в Безопасном запуске. (Вы уже видели ранее TBAWS, когда мы рассматривали соответствующие атрибуты переменных UEFI.)

Значение цифровой подписи исполняемого кода UEFI порой содержит некую временную отметку, эмитируемую имеющейся службой TSA (Time Stamping Authority, авторизации временных отметок). Значение временной отметки подписи отражает тот момент времени, в который была выработана данная подпись. Сопоставляя значение временной отметки подписи с временной соответствующей отметкой срока истечения её ключа подписи, Безопасный запуск определяет была ли данная подпись выработана до истечения срока действия её подписи, или после. Обычно значение даты истечения срока действия данного ключа подписи является той датой, после которой этот ключ подписи рассматривается скомпрометированным. В результате, значение временной отметки данной подписи позволяет Безопасному запуску проверять, что такая подпись была выработана в то момент, когда её ключ подписи не являлся скомпрометированным, обеспечивая легитимность этой подписи. Таким образом, аутентификация на основании времени снижает общую сложность PKI когда она касается сертификатов db Безопасного запуска.

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

Ключи Безопасного запуска

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

Итак, для защиты баз данных db и dbx от видоизменения без авторизации, производитель самих платформы или ОС обязан подписывать сами базы данных. Когда встроенное ПО UEFI собирается считывать имеющееся содержимое таких баз данных, оно вначале выполняет их аутентификацию, проверяя их цифровые подписи с неким общедоступным ключом, носящим название KEK (key exchange key, ключа обмена ключами). Далее оно выполняет аутентификацию каждого ключа KEK неким вторичным ключом с названием PK (platform key, ключа платформы).

 

Ключ обмена ключами

Как и в случае с db и dbx, полный список общедоступных KEK хранится в некой NVRAM переменной UEFI. Мы изучим соответствующее содержимое такой переменной KEK при помощи результатов своего предыдущего исполнения команды chipsec. откройте тот каталог, который содержит полученные результаты и вы должны обнаружить некую вложенную папку, помеченную как- то подобно KEK_8BE4DF61-93CA-11D2-AA0D-00E098032B8C, которая содержит сертификаты общедоступных ключей KEK (Рисунке 17-6). Данная переменная UEFI также является аутентифицированной, как вы увидите в следующем разделе.

 

Рисунок 17-6


Содержимое переменной UEFI KEK

Только обладатель тех частных ключей, которые соответствуют любому из этих сертификатов способен видоизменять имеющееся содержимое соответствующих баз данных db и dbx. В данном примере у нас имеется лишь два сертификата KEK, от Microsoft и Lenovo, на что указывает Таблица 17-2.

Таблица 17-1. Сертификаты в переменной KEK UEFI
Filename Issued to Issued by

X509-7FACC7B6-127F-4E9C-9C5D-080F98994345-00.bin

Lenovo Ltd. KEK CA 2012

Lenovo Ltd. KEK CA 2012

X509-77FA9ABD-0359-4D32-BD60-28F4E78F784B-01.bin

Microsoft Corporation KEK CA 2011

Microsoft Corporation Third-Party Marketplace Root

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

 

Ключ платформы

Значение PK является самым последним ключом подписи в общей иерархии ключей PKI Безопасного запуска. Как вы могли предвидеть, этот ключ применяется для аутентификации KEK через подпись соответствующей переменной UEFI KEK. Согласно спецификации UEFI, каждая платформа обладает неким отдельным PK. Обычно этот ключ совпадает с ключом производителя этой платформы.

Вернёмся к вложенной в ef_variables.dir папке PK_8BE4DF61-93CA-11D2-AA0D-00E098032B8C, которая была создана при выполнении вами chipsec. Здесь вы можете обнаружить необходимый сертификат такого общедоступного PK. Ваш сертификат будет соответствовать вашей платформе. Итак, поскольку мы применяем платформу Lenovo Thinkpad T540p, мы бы ожидали, что наш сертификат PK относится к Lenovo ( Рисунке 17-7).

 

Рисунок 17-7


Сертификат PK

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

Безопасный запуск UEFI: полная картина

Теперь, когда мы изучили полную иерархию той инфраструктуры PKI, которая применяется при Безопасном запуске UEFI, давайте соберём всё воедино чтобы обозреть полную картину, отображаемую на Рисунке 17-8.

 

Рисунок 17-8


Поток проверок Безопасного запуска UEFI

В самой вершине данного рисунка вы можете наблюдать что основной корень доверительных отношений (тот компонент, которому в своей основе доверяет Безопасный запуск и на котором зиждутся все его последующие проверки) это встроенное ПО инициализации данной платформы и её ключ платформы. Такое встроенное ПО инициализации платформы выступает самым первым фрагментом исполняемого кода после того как ЦПУ проходит через сброс (reset), а имеющийся Безопасный запуск в неявном виде доверяет этому коду. Если какой- то злоумышленник скомпрометирует PI (инициализацию платформы), будет разрушена вся цепь доверительных отношений, к которой принуждает Безопасный запуск. В таком случае подобный злоумышленник способен вставить заплатку в любой из модулей UEFI, который реализуется процедурой проверки своего образа Безопасного запуска с тем, чтобы он всегда был успешным и, как результат, допуская всякому поставляемому модулю UEFI проходить аутентификацию.

Именно по этой причине имеющаяся модель доверительных отношений Безопасного запуска предполагает что вы верно реализовали свой механизм Безопасного обновления встроенного ПО, который предполагает, что всякое обновление вашей прошивки (встроенного ПО) должно иметь подпись значением надлежащего ключа подписи (который обязан отличаться от значения PK). Тем самым, только имеют место только авторизованные обновления встроенного ПО PI и сам корень доверительных отношений остаётся не скомпрометированным.

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

В самой вершине Рисунка 17-8 вы можете обнаружить, что сам ключ платформы, который предоставляется производителем, обладает тем же самым уровнем врождённых доверительных отношений, что и встроенное ПО инициализации платформы (PI). Данный ключ применяется для установления доверия между имеющимся встроенным ПО PI и производителем этой платформы. После того как предоставлен подобный ключ платформы, встроенное ПО данной платформы допускает этому производителю обновлять значение KEK и, в результате, управлять тем какие из образов проходят проверки Безопасного запуска, а какие нет.

Одним уровнем ниже, вы можете видеть соответствующий KEK, который устанавливает доверительные отношения между имеющимся встроенным ПО инициализации платформы (PI) и той ОС, которая запускается на данной платформе. После того как KEK данной платформы представлен в надлежащей переменной UEFI, соответствующая ОС способна определять какой из образов способен проходить проверку Безопасного запуска. Например, соответствующий производитель ОС способен применять KEK чтобы разрешать имеющемуся встроенному ПО UEFI выполнять начальный загрузчик его ОС.

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

Политики Безопасного запуска

Как вы могли видеть, сам по себе, Безопасный запуск использует переменные PK, KEK, db, dbx и dbt чтобы сообщать своей платформе является или нет некий исполняемый образ заслуживающим доверия. Тем не менее, тот способ, которым интерпретируется получаемый результат проверки Безопасным запуском (иначе говоря, исполнять или нет некий образ), в основном зависит от имеющей место конкретной политики.

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

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

Политики Безопасного запуска не определены досконально в имеющейся спецификации UEFI, а следовательно, остаются специфическими для каждой реализации. На практике политики могут разнится между реализациями встроенного ПО UEFI у разных производителей. В этом разделе мы изучим некоторые элементы политик Безопасного запуска, реализуемых в исходном коде EDK2 Intel, который мы применяли в Главе 15. Сейчас выгрузите или склонируйте исходный код EDK2 из репозитория GitHub, если вы ещё не сделали этого.

Одним из элементов, который Безопасный запуск, согласно реализации EDK2, принимает во внимание, состоит в самом происхождении подлежащих аутентификации исполняемых образов. Эти образы могут поставляться с различных устройств хранения, часть которых по своей сути могут обладать доверием. Например, когда определённый образ загружается с самого флеша SPI, что означает, что он располагается в том же самом устройстве хранения, что и прочее встроенное ПО UEFI, тогда данная платформа может автоматически доверять ему. (Тем не менее, если какой- то злоумышленник способен видоизменить сам образ во фдеше SPI, он может также вмешиваться и в прочее имеющееся встроенное ПО и запретить целиком Безопасный запуск. Мы обсудим подобную атаку позднее в разделе Исправление встроенного ПО PI для запрета Безопасного запуска.) С другой стороны если соответствующий образ загружается с какого- то внешнего PCI устройства - например, какого- то дополительного ПЗУ, особое встроенное ПО загружается из внешних периферийных устройств в общую среду предзагрузки - тогда он может рассматриваться в качестве не имеющего доверия и выступать предметом для проверки Безопасным запуском.

Здесь мы обрисуем основные определения некоторых имеющихся политик, которые определяют как обрабатывать образы относительно их происхождения. Вы можете найти эти политики в своём файле SecurityPkg\SecurityPkg.dec, расположенном в рассматриваемом репозитории EDK2. Каждая из политик назначает некое действие по умолчанию для соответствующих образов, отвечающих её критерию.

PcdOptionRomImageVerificationPolicy

Определяет необходимую политику для образов, загружаемых в качестве необязательных ПЗУ, подобных расположенным в устройствах PCI (значение по умолчанию: 0x00000004).

PcdRemovableMediaImageVerificationPolicy

Определяет необходимую политику для образов, располагаемых на удаляемых носителях, которые включают в себя CD- ROM, USB и сетевые устройства (значение по умолчанию: 0x00000004).

PcdFixedMediaImageVerificationPolicy

Определяет необходимую политику для образов, находящихся на фиксированных устройствах данных, таких как жёсткие диски (значение по умолчанию: 0x00000004).

Дополнительно к этим политикам, имеются две дополнительные политики, которые не определены однозначно в SecurityPkg\SecurityPkg.dec, но применяются в реализации Безопасного запуска EDK2:

SPI flash ROM policy

Определяет необходимую политику для образов, располагаемых на флеше SPI (значение по умолчанию: 0x00000000).

Other origin

Определяет необходимую политику для образов, находящихся на устройствах, отличных от тех, что были описаны (значение по умолчанию: 0x00000004).

[Замечание]Замечание

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

Вот соответствующие описания для значений устанавливаемых по умолчанию политик:

0x00000000

Всегда доверять данному образу вне зависимости от того подписан он или нет и вне зависимости от того присутствует или нет его хэш в соответствующей базе данных db или dbx.

0x00000001

Никогда не доверять данному образу. Будут отвергаться даже образы с допустимыми подписями.

0x00000002

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

0x00000003

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

0x00000004

Отклонять исполнение если Безопасный запуск отказывает в аутентификации данного образа при использовании своих баз данных db и dbx.

0x00000005

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

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

Защита от буткитов при помощи Безопасного запуска

Теперь, когда вы ознакомились с тем как работает Безопасный запуск, давайте рассмотрим особый пример того как он выполняет защиту от буткитов, которые имеют целью общее протекание запуска ОС. Мы не будем обсуждать буткиты, которые имеют целью MBR и VBR, ибо, как это объяснялось в Главе 14, встроенное ПО UEFI больше не пользуется объектами, подобными MBR и VBR (за исключением случая с режимом совместимости UEFI), поэтому традиционные буткиты не способны скомпрометировать системы на основании USFI.

Как уже упоминалось в Главе 15, самым первым общедоступным буткитом проверки концепции, имеющей целью системы на основании UEFI, был буткит DreamBoot. В некой системе UEFI, не имеющей на месте Безопасного запуска, этот буткит работает следующим образом:

  1. Автор этого буткита заменил в разделе запуска оригинальный начальный загрузчик UEFI Windows, bootmgfw.efi, на вредоносный запускающий загрузчик, bootx64.efi.

  2. Этот вредоносный запускающий загрузчик помещает первоначальный bootmgfw.efi, вносит в него код правки для получения контроля над загрузчиком Windows winload.efi и исполняет его, как это показано на Рисунке 17-9.

     

    Рисунок 17-9


    Протекание атаки DreamBoot на запускающую загрузку ОС

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

Такой вид атаки является возможным, поскольку по умолчанию сам запускающий загрузчик ОС не обладает аутентификацией в общем процессе запуска UEFI. Встроенное ПО UEFI получает значение местоположения соответствующего запускающего загрузчика ОС из некой переменной UEFI, которая для Microsoft Windows располагается в \EFI\Microsoft\Boot\bootmgfw.efi раздела запуска. Некий злоумышленник с системными полномочиями запросто может подменить или видоизменить этот запускающий загрузчик.

Тем не менее, когда включён Безопасный запуск, эта атака более невозможна. Поскольку Безопасный запуск проверяет имеющуюся целостность образов UEFI, исполняемых во время запуска, а необходимый запускающий загрузчик ОС является одним из исполняемых кодов, проверяемых в процессе запуска, Безопасный запуск проверит подпись этого запускающего загрузчика ОС в имеющихся базах данных db и dbx. Наш вредоносный запускающий загрузчик не подписан надлежащим ключом подписи, а потому он потенциально не пройдёт проверку и не будет выполнен (в зависимости от установленной политики запуска). Это один из способов, коим Безопасный запуск осуществляет защиту от буткитов.

Атаки на Безопасный запуск

Теперь давайте рассмотрим некоторые атаки, которые могут преуспеть в борьбе с Безопасным запуском UEFI. Поскольку Безопасный запуск полагается на встроенное ПО инициализации платформы (PI) и ключ платформы (PK) в качестве основного корня доверительных отношений, когда один из этих компонентов скомпрометирован, вся цепочка проверок Безопасного запуска становится бесполезной. Мы рассмотрим возможности как руткитов, так и буткитов по подрыву Безопасного запуска.

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

В Главе 15 мы представляли разнообразные атаки, которые устанавливают постоянные руткиты во встроенном ПО флеша, а потому здесь мы бы не хотели снова вдаваться в эти подробности, хотя те же самые атаки (проблемы обработки SMI, сценарий запуска S3, защита на запись BIOS и тому подобные) могут применяться и против Безопасного запуска. Для рассматриваемых в этом разделе атак мы будем предполагать, что злоумышленник уже обладает возможностью внесения изменений в содержимое памяти флеша, содержащей встроенное ПО UEFI. Давайте рассмотрим что они могут делать дальше!

Исправление встроенного ПО PI для запрета Безопасного запуска

Раз злоумышленник способен изменять имеющееся содержимое флеша SPI, он запросто способен отключить Безопасный запуск внося исправления кода во встроенное ПО инициализации платформы (PI). На Рисунка 17-8 вы наблюдали, что Безопасный запуск UEFI зацеплен якорем в установленном встроенном ПО UEFI, а потому если мы изменим те модули своего встроенного ПО PI, которые реализуют Безопасный запуск, мы способны действенно отключить их функционирование.

Для изучения этого процесса мы снова воспользуемся исходным кодом EDK2 Intel в качестве примера реализации UEFI. Вы обнаружите где реализуется функциональность проверки такого Безопасного запуска и как вы можете его нарушить.

Внутри соответствующей папки SecurityPkg/Library/DxeImageVerifcationLib из рассматриваемого репозитория вы обнаружите файл исходного кода DxeImageVerifcationLib.c , который реализует собственно код функционирования проверки целостности. В частности, этот файл реализует соответствующую процедуру DxeImageVerificationHandler, которая принимает решение будет ли некий исполняемый код UEFI обладать доверием и следует ли его исполнить, либо завершить проверку отказом.

 

Листинг 17-1. Определение процедуры DxeImageVerificationHandler


EFI_STATUS EFI_API DxeImageVerificationHandler (
  IN  UINT32                           AuthenticationStatus, (1)
  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *File, (2)
  IN  VOID                             *FileBuffer, (3)
  IN  UINTN                            FileSize, (4)
  IN  BOOLEAN                          BootPolicy (5)
);
 	   

В качестве своего первого параметра наша процедура получает переменную AuthenticationStatus(1), которая указывает является или нет этот образ подписанным. Следующий параметр File(2) является указателем на значение пути к устройству, где расположен этот файл. Параметры FileBuffer(3) и FileBuffer(4) представляют для проверки некий указатель на соответствующий образ UEFI и его размер.

Наконец, BootPolicy(5) выступает параметром, который указывает будет ли данный запрос на загрузку этого подлежащего аутентификации образа поступать от своего диспетчера запуска UEFI и являться выбором запуска (что подразумевает этот образ в качестве избранного запускающего загрузчика ОС). Мы подробно обсуждали соответствующий диспетчер запуска UEFI в Главе 14.

По завершению своих проверок, эта подпрограмма возвращает одно из следующих значений:

EFI_SUCCESS

Аутентификация успешно пройдена и этот образ будет исполнен.

EFI_ACCESS_DENIED

Данный образ не прошёл аутентификацию по причине того, что политика данной платформы диктует что её встроенное ПО не может использовать данный файл образа. Это может произойти когда данное встроенное ПО предпринимает попытку загрузить некий образ с какого- то удаляемого носителя, а политика данной платформы запрещает выполнение с удаляемого носителя во время запуска, причём вне зависимости от того, будут или нет они обладать подписями. В таком случае данная процедура немедленно возвращает EFI_ACCESS_DENIED без какой бы то ни было проверки подписи.

EFI_SECURITY_VIOLATION

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

EFI_OUT_RESOURCE

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

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

Модификация переменных UEFI для обхода проверок безопасности

Другой способ атак на установленную реализацию Безопасного запуска состоит в модификации переменных NVRAM UEFI. Как мы обсуждали ранее в этой главе, Безопасный запуск использует определённые переменные для хранения его параметров настройки, подробностей подобных тому включён ли Безопасный запуск, значений PK и KEK, баз данных установленных подписей, а также значений политик платформы. Если некий злоумышленник сможет изменять эти переменные, он будет способен запрещать или обходить проверки подлинности Безопасного запуска.

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

Раз злоумышленник обладает доступом к установленным переменным NVRAM UEFI, он способен, к примеру, подделывать PK, KEK, db и dbx добавляя индивидуальные злонамеренные сертификаты, которые будут допускать прохождение проверок безопасности вредоносного модуля. Другим вариантом было бы добавление значения хэша его вредоносного файла в имеющейся базе данных db и удалении такого из установленной базы данных dbx (в случае, когда такое значение хэша находилось изначально в базе данных dbx). Как показано на Рисунке 17-10, через изменение значения переменной PK для включения в неё ключа сертификата злоумышленника, этот нападающий способен добавлять и удалять KEK из переменной UEFI KEK, что, в свою очередь, предоставляет ему контроль над базами данных подписей db и dbx, разрушая защиту Безопасного запуска..

 

Рисунок 17-10


Атаки на цепочку доверительных отношений установленного Безопасного запуска UEFI

В качестве третьего варианта, вместо изменения значения PK и компрометации всей лежащей в основе иерархии PKI, некий злоумышленниц способен просто разрушить значение PK в его переменной UEFI. Для надлежащей работы Безопасному запуску требуется допустимый PK, зачисленный во встроенное ПО платформы; в противном случае защита отключена.

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

Защита Безопасного запуска через Подтверждённый и выверенный запуск

Как мы уже обсуждали, Безопасный запуск сам по себе не способен выполнять защиту от атак, которые вовлекают изменения во встроенном ПО платформы. Итак, существует ли какая бы то ни было защита для технологии Безопасного запуска самой по себе? Ответ - да. В данном разделе мы сосредоточимся на технологиях безопасности, предназначенных для защиты встроенного ПО системы от видоизменений без авторизации - а именно, Подтверждённого и выверенного запуска (Verified and Measured Boot). Подтверждённый запуск проверяет что встроенное ПО данной платформы не было изменено или модифицировано, в то время как Выверенный запуск вычисляет криптографические хэши определённых компонентов, вовлечённых в общий процесс запуска и хранящих их в Регистрах конфигурации платформы Доверенного модуля платформы, или TPM PCR (Trusted Platform Module Platform Confguration Registers).

Функции Подтверждённого запуска и Выверенного запуска независимы и имеется возможность обладания платформами лишь со встроенной одной из них, или с обеими. Тем не менее, они обе, и Подтверждённый запуск, и Выверенный запуск выстыпают частями одной и той же цепи доверительных отношений (как это отображено на Рисунке 17-11).

 

Рисунок 17-11


Протекание Подтверждённого и выверенного запуска

Как вы уже видели на Рисунке 17-8, встроенное ПО инициализации платформы (PI), является самым первым фрагментом кода, выполняемого после прохождения ЦПУ сброса (reset). Безопасный запуск UEFI без каких бы то ни было условий доверяет этому встроенному ПО PI, а потому это делает существенным то, что атаки наших дней на Безопасный запуск полагаются на его изменение без авторизации.

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

Подтверждённый запуск

Когда некая система с Подтверждённым запускам включается, её логика оборудования запускает функциональность проверки её запуска, которая реализована в неком ПЗУ запуска или в микрокоде внутри её ЦПУ. Данная логика неизменна, что означает, что программное обеспечение не способно изменять её. Обычно Подтверждённый запуск исполняет некий модуль, обеспечивающий что данная система будет выполнять своё аутентичное встроенное ПО без вредоносных изменений. Для проверки своего встроенного ПО, Подтверждённый запуск полагается на криптографию общедоступного ключа; как и Безопасный запуск UEFI, он проверяет установленную цифровую подпись встроенного ПО данной платформы для гарантии её аутентичности. После успешного выполнения своей аутентификации, исполняется встроенное ПО этой платформы и продолжается проверка прочих компонентов встроенного ПО (например, дополнительных ПЗУ, драйверов DXE и запускающих загрузчиков ОС) для сопровождения надлежащей доверительной цепочки. Именно в этом состоит часть Подтверждения в Подтверждённом и выверенном запуске. Теперь относительно части Поверки.

Выверенный запуск

Выверенный запуск работает над измерением встроенного ПО своей платформы и запускающих загрузчиков ОС. Это означает, что он вычисляет значения криптографических хэшей тех компонентов, которые вовлечены в сам процесс запуска. Эти хэши хранятся в неком наборе TPM PCR (Регистрах конфигурации платформы Доверенного модуля платформы). Сами по себе эти хэш значения не сообщают вам являются ли поверенные компоненты безопасными или вредоносными, но они предоставляют вам сведения относительно того, были ли конфигурация и компоненты запуска изменены в некий момент. Когда некий компонент запуска был видоизменён, его хэш значение будет отличаться от того, которое вычислено для первоначальной версии данного компонента запуска. Тем самым, Выверенный запуск отмечает любые модификации своих компонентов запуска.

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

Теперь, когда мы знаем в целом как работает Подтверждённый и выверенный запуск, давайте взглянем на пару его реализаций, начав с Защитника запуска Intel.

Защитник запуска Intel

Защитник запуска Intel (Intel BootGuard) является технологией Подтверждённого и выверенного запуска Intel. Рисунке 17-12 показывает поток запуска в некой платформе с с включённым Защитником запуска Intel.

 

Рисунок 17-12


Протекание Защитника запуска Intel

В процессе инициализации, прежде чем ЦПУ начнёт выполнять свой первый код, расположенный в его векторе сброса, он выполняет код из своего ПЗУ запуска. Этот код выполняет всю необходимую инициализацию состояния своего ЦПУ, затем загружает и выполняет Модуль кода аутентификации (ACM, Authenticated Code Module) Защитника запуска.

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

Такой ACM Защитника запуска реализует функциональность Подтверждённого и выверенного запуска. Этот модуль загружает встроенного ПО загрузчика первого этапа, имеющего название блока начального запуска (IBB, initial boot block), в оперативную память и, в зависимости от своей применяемой политики запуска, подтверждает и/ или поверяет его. Такой IBB является частью того встроенного ПО, которое содержит код, исполняемый из установленного вектора сброса.

Строго говоря, на данный момент в данном выполняемом процессе запуска оперативная память отсутствует. Имеющийся контроллер памяти ещё не был проинициализирован, а доступа к ОЗУ нет. Тем не менее, данный ЦПУ настраивает свой кэш последнего уровня с тем, чтобы он мог применяться в качестве ОЗУ, помещая его в режим Кэша- в качестве- ОЗУ ( Cache-as-RAM), до того самого момента в этом процессе запуска, пока эталонный код памяти его BIOS не сможет настроить свой контроллер памяти и обнаружить ОЗУ.

Установленный ACM передаёт управление своему IBB после того как этот IBB успешно проверен и/ или измерен. В случае отказа проверки данного IBB, имеющийся ACM ведёт себя согласно той политике, которая задействована: данная система может быть немедленно остановлена, либо допустить восстановление встроенного ПО после некоторого таймаута.

Данный IBB затем загружает весь остаток имеющегося встроенного ПО UEFI с флеша SPI и подтверждает и/ или поверяет его. После того как данный IBB получил управление, Защитник запуска Intel больше не отвечает за сопровождение надлежащей доверительной цепи, так как его цель состоит просто в подтверждении и поверке своего IBB. Сам IBB отвечает за продолжение доверительной цепочки до того момента, как Безопасный запуск UEFI берёт на себя всё подтверждение и поверку образов встроенного ПО.

Поиск необходимого ACM

Давайте рассмотрим подробности реализации технологии Защитника запуска Intel для настольных платформ, начав с самого ACM. Поскольку ACM является одним из самых первых исполняемых компонентов Защитника запуска Intel после включения его системы, самый первый вопрос таков: как именно конкретный ЦПУ находит необходимый ACM после включения питания?

Точное местоположение искомого ACM предоставляется в особой структуре данных с названием FIT (Firmware Interface Table, Таблица взаимодействия встроенного ПО), хранимой в установленном образе встроенного ПО. Данная FIT организована в виде некого массива записей FIT, причём каждая из них описывает местоположение определённого объекта в своём встроенном ПО, таком как сам ACM или файлы обновления микрокода. Рисунок 17-13 отображает общую схему некой FIT в памяти системы после сброса.

 

Рисунок 17-13


Расположение FIT в памяти

После включения данного ЦПУ, он считывает необходимые адреса своей FIT из местоположения 0xFFFFFFC01 в своей памяти. Поскольку пока ещё нет ОЗУ, когда данный ЦПУ отправляет транзакцию чтения памяти для своего физического адреса 0xFFFFFFC0, логика его внутреннего набора микросхем распознаёт что этот адрес относится к особому диапазону адресов и, вместо того чтобы отправлять эту транзакцию в свой контроллер памяти, декодирует его. Транзакции чтения памяти для такой таблицы FIT направляются в установленный контроллер флеша SPI, который считывает FIT из памяти флеша.

Мы подробнее рассмотрим данный процесс, вернувшись в установленный репозиторий EDK2. В его каталоге IntelSiliconPkg/Include/IndustryStandard/ вы обнаружите соответствующий файл заголовка FirmwareInterfaceTable.h, который содержит некоторые определения кода, относящиеся к обсуждаемой структуре FIT. Схема записей FIT показана в Листинг 17-2

 

Листинг 17-2. Схема записей FIT


typedef struct {
  UINT64 Address; (1)
  UINT8  Size[3]; (2)
  UINT8  Reserved;
  UINT16 Version; (3)
  UINT8  Type : 7; (4)
  UINT8  C_V  : 1; (4)
  UINT8  Chksum; (6)
} FIRMWARE_INTERFACE_TABLE_ENTRY;
 	   

Как уже упоминалось, каждая запись FIT описывает определённый объект в своём образе встроенного ПО. Сама природа каждого объекта закодирована в поле Type этой FIT. Данные объекты могут быть, например, файлами обновления микрокода, неким ACM Защитника запуска или какой- то политикой Защитника запуска. Значения полей Address(1) Size(2) предоставляют искомое местоположение самого объекта в памяти: Address содержит значение физического адреса этого объекта, а Size определяет его размер, выраженный в dwords (4- байтовом значении). Значение поля C_V(5) представляет допустимость его контрольной суммы: если оно установлено в 1, значение поля Chksum(6) содержит некую допустимую контрольную сумму этого объекта. Значение суммы всех составляющих байт в данном компоненте складываются по модулю с 0xFF и значения из самого поля Chksum должно быть равным нулю. Значения поля Version(3) содержит номер версии данного компонента в двоично кодированном десятичном формате. Для записи заголовка рассматриваемой FIT, величина значения в этом поле будет указывать номер его ревизии для этой структуры данных FIT.

Сам заголовок FirmwareInterfaceTable.h содержит значения, которые может принимать поле Type(4). Эти значения типа по большей части не документированы, причём доступна лишь небольшие сведения, однако представленное определение типов записи FIT достаточно обширное и вы можете вывести их значения из указанного контекста. Вот те типы, которые относятся в Защитнику запуска:

  • Запись FIT_TYPE_00_HEADER предоставляет общее число записей FIT в данной таблице FIT в своём поле Size. Её поле Address содержит особую 9- байтовую подпись, '_FIT_ ' (в ней имеются три пробела после '_FIT_').

  • Запись с типом FIT_TYPE_02_STARTUP_ACM предоставляет значение местоположения искомой ACM Защитника запуска, для которой выполняется синтаксический разбор кодом запуска ПЗУ для определения местоположения этого ACM в системной памяти.

  • Записи с типом FIT_TYPE_0C_BOOT_POLICY_MANIFEST (манифест политики запуска Защитника запуска) и FIT_TYPE_0B_KEY_MANIFEST (манифест ключа Защитника запуска) снабжают Защитник запуска той политикой, которая применяется, а также те сведения о настройке, которые мы кратко обсудим в разделе Настройка защитника запуска Intel.

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

Эксплуатация FIT

При помощи UEFITool, который мы представили в Главе 15 (и который мы обсудим дополнительно в Главе 19), вы можете исследовать некоторые записи FIT в своём образе встроенного ПО и выделить для последующего анализа сам ACM из этого образа, причём совместно с установленной политикой запуска и манифестами ключей. Это может оказаться полезным, так как сам ACM может применяться для сокрытия вредоносного кода. В своём следующем примере воспользуемся неким образом встроенного ПО, полученного из некой системы с включённой технологией Защитника запуска Intel. (Главе 19 предоставляет сведения о том, как выделить некое встроенное ПО из конкретной платформы.)

Прежде всего загрузим сам образ встроенного ПО в UEFITool, выбрав File4 Open > Image File. После определения конкретного файла образа встроенного ПО для загрузки вы обнаружите некое окно, подобное отображённому на Рисунке 17-14.

 

Рисунок 17-14


Просмотр FIT в UEFITool

В нижней половине полученного окна вы можете наблюдать имеющуюся таблицу FIT, которая перечисляет свои записи. Колонка Type из этой таблицы FIT отображает значения типа записей FIT. Мы ищем записи FIT для конкретных типов ACM BIOS, манифеста ключа Защитника запуска и политики запуска Защитника запуска. Применяя эти сведения, мы имеем возможность определить местоположение этих компонентов Защитника запуска Intel в своём образе встроенного ПО и выделить их для последующего анализа. В данном конкретном примере, запись FIT #6 указывает значение местоположения искомого ACM BIOS; он начинается с адреса 0xfffc0000. Записи #7 и #8 FIT указывают местоположение искомых манифестов ключа и политики запуска; они начинаются со значений адресов 0xfffc9180 и 0xfffc8100, соответственно.

Настройка защитника запуска Intel

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

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

Соответствующий BPMсам по себе содержит собственный номер версии безопасности, местоположение и хэш своего IBB; надлежащий открытый ключ BPM; а также цифровые подписи для только что перечисленных полей самого BPM - и снова за исключением установленного открытого ключа корня, который может быть подтверждён при помощи имеющегося открытого ключа BPM. Значение местоположения IBB предоставляет необходимую схему этого IBB в памяти. Она может не быть непрерывным блоком памяти; она вместо этого может состоять из нескольких не находящихся рядом областей. Хэш этого IBB содержит кумулятивное хэш значение всех областей памяти, занимаемых этим IBB. Таким образом, полный процесс проверки подписи обсуждаемого IBB состоит в следующем:

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

  2. Ы случае успеха проверки, Защитник запуска определяет местоположение надлежащего BPM при помощи FIT, вычисляет значение хэша этого BPM и сравнивает его с хэшем BPM в своём KM. Когда эти значения не равны, Защитник запуска сообщает о некой ошибке и включает действия исправления; в противном случае он получает из BPM значение хэша и местоположение IBB.

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

  4. В противном случае Защитник запуска сообщает что его проверка успешна. Если включена Поверка записи, Защитник записи также измеряет полученный IBB вычисляя его хэш и сохраняя полученное измерение в своём TPM. Далее Защитник запуска передаёт управление в проверенный IBB.

Обсуждавшийся KM является существенно важной структурой, ибо он содержит необходимый открытый ключ OEM корня для проверки наличия целостности получаемого IBB. Вы можете спросит, "Раз KM Защитника запуска хранится в незащищённом флеше SPI совместно с образом встроенного ПО, не означает ли это что злоумышленник способен изменить его в флеше для предоставления Защитнику запуска поддельного ключа проверки?" Для предотвращения подобных этой атак, значение хэша открытого ключа OEM корня вместо этого хранится в программируемом при эксплуатации плавком предохранителе (feld-programmable fuses) самого набора микросхем. Такие предохранители могут программироваться только один раз, в тот момент, когда предоставляется необходимая политика запуска Защитника запуска. После того как такие плавкие предохранители записаны, невозможно переписать их. Именно таким образом ключ проверки нашего Защитника запуска цепляется якорем в аппаратных средствах, превращая это оборудование в не изменяемый корень доверительных отношений. (Политики запуска Защитника запуска также хранятся в плавких предохранителях набора микросхем, что делает невозможным изменения такой политики после данного обстоятельства.)

Если некий злоумышленник изменяет манифест ключа установленного Защитника запуска, процесс ACM отметит такое изменение ключа вычислив его хэш и сравнив его со своим "золотым" значением, впаянным в его набор микросхем. Несоответствие хэшей включат некое сообщение об ошибке и поведение исправления. Рисунок 17-15 демонстрирует устанавливаемую цепь доверительных отношений, к которой принуждает Защитник запуска.

 

Рисунок 17-15


Цепочка доверительных отношений Защитника запуска Intel

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

Рисунок 17-16 завершает данный раздел представляя установленные границы зон ответственности для реализаций Безопасного запуска.

 

Рисунок 17-16


Границы ответственности для реализации Безопасного запуска

Доверенная плата запуска ARM

ARM обладает своей собственной реализацией технологии Подтверждённого и выверенного запуска, носящей название TBB (Trusted Boot Board, Доверенной платы запуска) или просто Trusted Boot (Доверенного запуска). В этом разделе мы рассмотрим строение Доверенного запуска. ARM обладает очень особенной настройкой, именуемой как технология безопасности Trust Zone (Зоны доверия), которая разделяет общую среду выполнения на две части. Прежде чем мы перейдём к своему процессу Подтверждённого и выверенного запуска при помощи ARM, нам следует описать как работают Зоны доверия.

Зона доверия ARM

Технология безопасностиЗоны доверия является аппаратно реализуемой функциональной возможностью, которая разделяет общую среду выполнения ARM на два мира: безопасный свет и обычный (или не безопасный) мир, которые совместно представлены в одном и том же физическом ядре, как это представлено на Рисунке 17-17 . Та логика, которая реализована в самом оборудовании процессора и встроенном ПО гарантирует, что ресурсы установленного безопасного света надлежащим образом изолированы и защищены от программного обеспечения, исполняемого в другом, не безопасном мире.

 

Рисунок 17-17


Зона доверия ARM

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

Внутри самого процессор, запускаемое в обычном мире программное обеспечение не имеет прямого доступа к коду и данным из безопасного света. Именно такая логика препятствия контроля доступа реализуется в самом оборудовании, обычно в аппаратных средствах Системы в микросхеме (System on Chip). Тем не менее, исполняемое в обычном мире программное обеспечение способно передавать управление в то программное обеспечение, которое располагается в безопасном свете (например, для выполнения какой- то доверенной службы в этом безопасном мире) при помощи особого программного обеспечения, носящего название Монитора Безопасности (Secure Monitor, в ARM Cortex-A) или в логике ядра (для ARM Cortex-M). Ткой механизм выступает гарантей того, что переключение между мирами не нарушает имеющуюся безопасность всей системы.

Соединённые в единое целое, технология Доверенного запуска и Зоны доверия создают свою Среду доверительного исполнения (Trusted Execution Environment), которая применяется для исполнения программного обеспечения с высокими привилегиями и предоставляющую некое окружение для безопасных технологий, таких как управление цифровыми правами, примитивы криптографии и аутентификации, а также прочие чувствительные к безопасноти приложения. Таким образом, некая изолированная, защищённая среда способна размещать у себя наиболее чувствительное программное обеспечение.

Загрузчики запуска ARM

Поскольку имеющиеся безопасный и обычный миры удерживаются по- отдельности, каждый из миров нуждается в своём собственном наборе загрузчиков запуска. Кроме того, такой процесс запуска для каждого из миров составлен из множества этапов, что некое число загрузчиков запуска должно исполняться в различные моменты в соответствующем процессе запуска. Здесь мы опишем такой поток Доверенного запуска для процессоров приложения ARM в общих терминах, начиная с приводимого ниже списка вовлечённых в Доверенный запуск. Мы показали это на своём предыдущем Рисунке 17-17:

BL1

Загрузчик запуска первого этапа, располагающийся в ПЗУ запуска и выполняется в своём безопасном мире.

BL2

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

BL31

Встроенное ПО времени выполнения безопасного мира, загружаемого и запускаемого BL2.

BL32

Не обязательный загрузчик запуска третьего этапа безопасного мира, загружается BL2.

BL33

Встроенное ПО времени выполнения обычного мира, загружается и запускается BL2.

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

Для проверки имеющейся целостности таких компонентов запуска, Доверенный запуск полагается на сертификаты открытого (общедоступного) ключа X.509 (помните, что все файлы в базе данных db Безопасного запуска UEFI были кодированы при помощи X.509). Будет нелишним заметить, что все сертификаты являются подписанными самостоятельно. Нет необходимости в какой бы то ни было авторизации сертификата, так как данная цепочка доверительных отношений не устанавливается процессом удостоверения эмитента сертификата, а вместо этого содержимым имеющихся расширений сертификатов.

Доверенный запуск пользуется двумя типами сертификатов: сертификатами key (ключа) и content (содержимого). Вначале он применяет сертификаты ключа для проверки значений открытых ключей, которые применяются для подписи сертификатов содержимого. Затем они применяют полученные сертификаты содержимого для хранения значений хэшей образов загрузчиков запуска. Это взаимоотношение иллюстрируется на Рисунке 17-18.

 

Рисунок 17-18


Ключ Доверенного запуска и сертификаты содержимого

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

Поток Доверенного запуска

Теперь, когда вы уже знакомы с основополагающими понятиями Доверенного запуска, давайте взглянем на сам поток Доверенного запуска для некого прикладного процессора, показанного на Рисунке 17-19. Это снабдит вас полной картиной того как в процессорах ARM реализуется Подтверждённый запуск и как он защищает платформы от выполнения кода без установленного доверия, включая руткиты встроенного ПО.

На Рисунке 17-19 сплошные стрелки обозначают передачу потока исполнения, а пунктирные стрелки обозначают доверительные взаимоотношения; иначе говоря, каждый элемент доверяет всякому элементу, на который он указывает пунктирной стрелкой.

 

Рисунок 17-19


Поток Доверенного запуска

Как только данный ЦПУ высвобождается из перезапуска, самым первым фрагментом исполняемого кода является загрузчик запуска 1 (BL11). BL1 загружается из доступного только для чтения ПЗУ, что означает что он не может быть испорчен при его хранении там. BL1 считывает сертификат содержимого9 загрузчика запуска 2 (BL2) из флеш памяти и проверяет ключ его эмитента. BL1 затем вычисляет значение хэша сертификата содержимого эмитента самого BL2 и сравнивает его с имеющимися "золотыми" значениями, хранимыми в своём безопасном ROTPK (root of trust public key register, регистре корневого открытого ключа доверия)10 в своём оборудовании. Такой регистр ROTPK и ПЗУ запуска являются основными корнями доверительных отношений, зацепленных якорно в аппаратных средствах для Доверенного запуска.Если хэши не совпадают или отказывает проверка значения подписи сертификата содержимого BL2, эта система объявляет тревогу.

Когда значение сертификата содержимого BL2 проверена в ROTPK, BL1 загружает соответствующий образ BL2 из флеша2, вычисляет его криптографический хэш и сравнивает это значения хэша с полученным из сертификата содержимого BL25.

После аутентификации, BL1 передаёт управление в BL2, который, в свою очередь, считывает его сертификат ключа доверия6 из памяти флеша. Этот сертификат ключа доверия содержит открытыйе ключи для необходимой проверки самого встроенного ПО как безопасного7, так и обычного8 миров. Тот ключ, который эмитировал сертификат ключа доверия проверяется по значению регистра ROTPK10.

Затем BL2 выполняет аутентификацию BL313, который является строенным ПО времени исполнения для безопасного мира. Чтобы осуществить аутентификацию самого образа BL31, BL2 пользуется своим сертификатом ключа и сертификатом содержимого для BL314. BL2 проверяет эти сертификаты ключей применяя открытый ключ своего безопасного мира, полученный из сертификата ключа доверия. Полученный сертификат ключа BL31 содержит сертификат открытого ключа, применяемого для проверки значения подписи сертификата содержимого соответствующего BL32.

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

Аналогично, BL2 проверяет наличие целостности своего необязательного образа BL32 безопасного мира при помощи надлежащего ключа BL32 и сертификатов содержимого.

Наличие целостности образа встроенного ПО BL33 (выполняемого в обычном мире) проверяется при помощи ключа BL33 и сертификатов содержимого BL33. Сам сертификат ключа BL33 проверяется своим открытым ключом обычного мира, получаемым из общего сертификата ключа доверия.

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

 
[Замечание]Аппаратно подтверждаемый запуск AMD

Хотяэто и не обсуждалось в данной главе, AMD обладает своей собственной реализацией Подтверждённого и выверенного запуска с названием HVB (Hardware Validated Boot, Аппаратно подтверждённого запуска). Данная технология реализует функциональность аналогично Защитнику запуска Intel. Основываясь на технологии Процессора безопасности платформы (Platform Security Processor) AMD, она обладает неким микроконтроллером, посвящённым связанными с безопасностью вычислениями, который исполняется независимо от основного ядра своей системы.

Подтверждённый запуска против руткитов встроенного ПО

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

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

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

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

Заключение

В этой главе мы изучили три технологии Безопасного запуска: Безопасный запуск UEFI, Защитник запуска Intel и Доверенный запуск ARM. Эти технологии полагаются на цепочку доверительных отношений - к которой имеется принуждение с самого начала всего процесса запуска вплоть да выполнения приложений пользователя - и которая вовлекает в себя огромное число модулей запуска. При правильной настройке и реализации они предоставляют защиту от всё растущего числа руткитов встроенного ПО UEFI. Именно по этой причине многие продаваемые системы включают по умолчанию Безопасный запуск. В своей следующей главе мы сосредоточимся на криминалистическом подходе при анализе руткитов встроенного ПО.