Доклады, выступления, видео и электронные публикации

О технических аспектах ограничения на запуск исполняемого кода на этапе до загрузки ОС

Московский физико-технический институт (национальный исследовательский университет), г. Долгопрудный, 141701, Российская Федерация

Защита от вредоносных программ требует разработки формальной модели [1], которая в том числе определяет, какие программы запускать можно, а какие — нет. С технической точки зрения, за реализацию запрета на запуск постороннего кода отвечает монитор безопасности субъектов [2]. В общем случае, монитор безопасности (МБ) — постоянно работающая и не изменяемая система контроля доступа, которую нельзя обойти и для которой полное выполнение политики безопасности доказано [3]. При этом МБ является полноценным субъектом, то есть остаётся элементом среды, которую защищает. Следовательно, он должен обладать более высоким индексом защищённости, чем остальные элементы среды. Наибольшим потенциалом защиты обладал бы резидентный компонент безопасности, реализованный аппаратно, однако платой за этот потенциал будет низкая гибкость и адаптируемость полученного средства защиты [4], из-за чего программная реализация МБ может быть более удобной с точки зрения интеграции в существующие ЭВМ.

На данный момент задачу ограничения на запуск постороннего кода принято решать в операционных системах (ОС). Тем не менее, ОС — не единственная среда исполнения программ. До загрузки ОС ЭВМ загружает базовую систему ввода-вывода (BIOS), которая отвечает за инициализацию оборудования и выбор загрузчика ОС. Загрузчик ОС является программой, которая работает в рамках BIOS. BIOS может предоставлять и другие средства, которые можно использовать в качестве альтернативы средствам ОС. Однако долгое время в силу отсутствия стандартизации реализации BIOS могли отличаться вплоть до отдельной ревизии материнской платы, что делало разработку программ BIOS крайне затратной [5]. Поэтому вопрос организации замкнутой программной среды на этапе до загрузки ОС не стоял так остро.

В современных же ЭВМ интерфейс BIOS стандартизирован спецификацией Unified Extensible Firmware Interface (UEFI) [6]. Следовательно, значительно уменьшилась разница в сложности разработки для ОС и BIOS. Известно, что атаки на уровне BIOS и раньше были более привлекательными для нарушителя [7], а для UEFI было показано, что благодаря стандартизации стало возможно автоматизировать процесс заражения [8]. Появилась задача реализации МБ для организации замкнутой программной среды на этапе до загрузки ОС. Доверенный UEFI явно требуется средствам доверенной загрузки (СДЗ) уровня BIOS, чтобы гарантировать невозможность обхода СДЗ в процессе загрузки системы.

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

Согласно спецификации, задача UEFI — предоставить стандартизированные интерфейсы для использования в образах, загружаемых UEFI: драйверах, приложениях и загрузчиках ОС. Эти образы могут использовать сервисы UEFI, которые делятся на 2 вида: Boot Services и Runtime Services. Причина разделения сервисов UEFI на Boot и Runtime в том, что, согласно спецификации, Runtime Services должны быть доступны после перехвата управления ОС, в то время как Boot Services окажутся недоступны [9]. Эти сервисы доступны как структуры, содержащиеся в глобальной структуре EFI_SYSTEM_TABLE, которая передаётся каждому загружаемому UEFI-образу.

Таблица Boot Services включает в себя протоколы работы с устройствами, загрузку других образов UEFI, выделение памяти, работу с событиями и прочие служебные функции, всего их более 40. Среди определённых в стандарте протоколов можно выделить работу с файлами в файловой системе FAT32, получение информации о разделах, работу с USB-устройствами, сжатие данных, работу с Unicode-строками и регулярными выражениями, работу с сетью, консольный ввод-вывод, вывод графики, работу с PCI, SCSI. Большое число стандартизированных интерфейсов придаёт UEFI черты самостоятельной операционной системы [7]. Среди Boot-сервисов к нашей задаче относятся LoadImage(), который отвечает за загрузку образов, а также StartImage() и UnloadImage(), которые отвечают за запуск и выгрузку соответственно.

Рассмотрим подробнее образы UEFI:

  1. UEFI Applications — приложения, которые могут быть загружен прошивкой для исполнения. После завершения работы приложение выгружается из памяти.
  2. UEFI OS Loaders — загрузчики ОС, которые отличаются от приложений тем, что при корректной работе не возвращают управление прошивке UEFI. Если загрузка ОС произведена успешно, загрузчик должен вызвать ExitBootServices(), что завершит все Boot Services, а также управление памятью, после чего ответственность за управление системой перейдёт ОС.
  3. UEFI Drivers — подобны приложениям, однако в случае завершения с кодом EFI_SUCCESS не выгружаются из памяти. Бывают двух видов: Boot Service Drivers и Runtime Drivers. Последние не выгружаются из памяти даже после вызова ExitBootServices().

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

Адаптеры для LoadImage(), StartImage() и UnloadImage() будут необходимыми компонентами МБ: StartImage() будет блокировать загрузку вредоносного кода, LoadImage() не допустит загрузки недоверенного образа в память, UnloadImage() не позволит прекратить работу образа, реализующего МБ. Строго говоря, возможность выделять память и прямой доступ к ней позволяют загружать исполняемый образ в память в обход LoadImage(). Тем не менее, реализация механизма, дублирующего LoadImage() потребует усилий злоумышленника при том, что защита LoadImage() не отличается существенно от StartImage() (используется один и тот же белый список), поэтому контроль за запуском LoadImage() увеличит разницу между построением защиты и тратами на её преодоление, что поможет лучше выполнить условие достаточности защиты [10].

Не менее важным является контроль над средствами файлового ввода-вывода, поскольку менять настройки МБ недопустимо, вне зависимости от того, хранятся ли они в файле с исполняемым кодом программы или в отдельном файле. Для этого можно с помощью ReinstallProtocolInterface() установить адаптер для методов Write() и WriteEx() UEFI-протокола работы с файлами — EFI_FILE_PROTOCOL. Отличие WriteEx() от Write() лишь в том, что WriteEx() при успешном выполнении создаёт событие. Может показаться, что из-за схожести функций WriteEx() должен вызывать Write(), однако спецификация не гарантирует этого, поэтому адаптер нужен как для Write(), так и для WriteEx(). Методы с префиксом Write спецификация определяет и для других протоколов: для работы с блочными устройствами в блокирующем и неблокирующем виде (последний используется для продолжения работы программы, не дожидаясь завершения функции), работы с дисками, лентами, и не только. Поэтому выбор методов для переопределения зависит от того, где хранятся настройки МБ. Почти все они не предусматривают метода с префиксом Open, поэтому в случае, если недопустимо даже читать настройки монитора, придётся переопределять методы с префиксами Read и Write, а не только Open. Разумеется, для того, чтобы эти настройки нельзя было изменить, нужно определять адаптеры для Boot-сервисов работы с протоколами. Эти адаптеры должны оставлять доверенным образам возможность определять свои реализации протоколов в рамках своей задачи — предоставления реализации для интерфейсов, определённых в стандарте UEFI.

Полученную схему реализации ограничения на запуск исполняемого кода иллюстрирует Рисунок 1. Штриховые стрелки указывают на объекты доступа, сплошные — изображают поток исполнения. Попытка запрещённого доступа прерывается на уровне адаптера.

Рисунок 1 – Схема реализации ограничения на запуск исполняемого кода

Очевидно, что аппаратными ресурсами может владеть только одна программа: несоблюдение порядка операций, которое происходит при попытке обработать неатомарные запросы нескольких программ одновременно, может привести устройство в неработоспособное состояние. UEFI не претендует на исполнение роли ОС и предоставляет абстракции только для этапа BIOS. Это достигается путём предоставления UEFI Boot-сервиса ExitBootServices(). Этот сервис должен завершить все Boot-сервисы, после чего пометить память EfiBootServicesCode и EfiBootServicesData как свободную. Несмотря на то, что у Runtime Services останется доступ к указателям на Boot Services в EFI_SYSTEM_TABLE, обращаться по ним будет нельзя, так как эти указатели уже не будут указывать на Boot Services [9]. Следовательно, в случае переопределения Runtime-сервисов, для нормальной загрузки ОС нужно перед завершением этапа Boot вернуть все указатели на Runtime-сервисы в исходное состояние. Тогда система будет загружена в штатном режиме, а все ресурсы, которые использовал монитор безопасности на стадии UEFI, будут автоматически освобождены после загрузки ОС.

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

Список литературы

  1. Конявский, В.А. «Доверенная гарвардская» архитектура – компьютер с динамически изменяемой архитектурой. (Комплексная защита информации. Материалы XX научно-практической конференции. Минск, 19-21 мая 2015 г. – Минск: РИВШ, 2015. С. 32-37.)
  2. Зайцев А.П. Программно-аппаратные средства обеспечения информационной безопасности: Учебное пособие (М.: Машиностроение-1, 2006.)
  3. Рудина C. Модели безопасности и архитектурные подходы к их реализации в системах критической инфраструктуры [Электронный ресурс] URL: http://comsec.spb.ru/imctcpa15/01.05.RudinaEA.pdf (дата обращения: 11.04.2019)
  4. Конявский В.А. Основы понимания феномена электронного обмена информацией (Минск: Серия "Библиотека журнала "УЗИ", 2004 — 327c.)
  5. UEFI и универсальный механизм заражения. [Электронный ресурс] URL: http://www.computerra.ru/118961/uefi-trojan-n-bootkit-light-eater/ (дата обращения: 11.04.2019)
  6. Черчесов А.Э. Фазы загрузки UEFI и способы контроля исполняемых образов // Вопросы защиты информации. М., 2018. № 2 (121). С. 51-53.
  7. Лыдин С.С. О средствах доверенной загрузки для аппаратных платформ с UEFI BIOS (Вопросы защиты информации: Научно-практический журнал/ФГУП «ВИМИ», М.,2016г., Вып.3, №114, с. 45-50.)
  8. Xeno Kovah, Corey Kallenberg. How Many Million BIOSes Would you Like to Infect? [Электронный ресурс] URL: http://legbacore.com/Research_files/HowManyMillionBIOSesWouldYouLikeToInfect_Whitepaper_v1.pdf (дата обращения: 10.04.2019)
  9. UEFI Specification Version 2.8 [Электронный ресурс]. URL: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf (дата обращения: 26.04.2019)
  10. Управление защитой информации на базе СЗИ НСД "Аккорд" (Москва: "Радио и связь", 1999 - 325c.)

Автор: Максимов А. А.

Дата публикации: 18.01.2019

Библиографическая ссылка: Максимов А. А. О технических аспектах ограничения на запуск исполняемого кода на этапе до загрузки ОС // Комплексная защита информации: материалы ХХIV научно-практической конференции. Витебск. 21–23 мая 2019 г.: УО ВГТУ. Витебск, 2019. С. 343–347.


Scientia potestas est
Кнопка связи