ci.dll - библиотека проверки цифровых подписей

Метки:  , , , , , , , , ,

И последним этапом в цепочке проверки целостности кода стадии загрузки 32-битной операционной системы Windows 7 является библиотека ci.dll (именуемая разработчиками Модулем Целостности Кода, Code Integrity Module). Данный компонент впервые появился в операционной системе Windows 7 и в своем составе имеет функции, обеспечивающие проверку целостности бинарных образов на этапе отображения/загрузки в адресное пространство ядра. Таким образом, можно сделать вывод, что фактически проверке по задумке разработчиков, подлежат только ключевые образы, являющиеся для системы критичными в плане безопасности. Область действия функционала ci.dll ограничивается только локальной системой, то есть той, на которой непосредственно происходит выполнение кода функций, иначе говоря библиотека является ни чем иным как изолированным идентификатором безопасности локальной системы.
Теперь, собственно, сделаем небольшое отступление для того, что бы дать краткое описание необходимых для понимания происходящего механизмов. С определенного времени в Windows появились так называемые сертификаты подписи кода.

Сертификат подписи кода (Code Signing Certificate) - цифровой "документ" для программного обеспечения (бинарные модули/скрипты), удостоверяющий автора программы и гарантирующий целостность (неизменность) кода.

Получается, что введение подобного типа сертификатов призвано обеспечить:

  • проверка подлинности кода;
  • проверка целостности кода;

Существует несколько видов сертификатов подписи кода, но в контексте данного материала нас интересуют лишь следующие:

  • Цифровая подпись Authenticode (Authenticode Signing) - сертификат, предназначающийся для удостоверения кода (программ/скриптов) пользовательского режима;
  • Цифровая подпись модулей режима ядра (Kernel Mode Signing) - сертификат, позволяющий удостоверять модули, предназначенные для работы в режиме ядра (нативные библиотеки/драйвера);

Цифровая подпись Authenticode используется для подписи 32- и 64-битных исполняемых файлов (.exe, .dll, .cab .msi, и некоторые другие). Помимо этого, позволяет подписывать код для Microsoft Office, Microsoft VBA, Silverlight 4. Цифровая подпись (сертификат разработчика) модулей режима ядра (Kernel Mode) позволяет подписывать приложения, предназначенные для работы в режиме ядра. Для 64-битных версий операционных это имеет особое значение, поскольку для систем данной разрядности (начиная с Windows Vista) необходимо, чтобы все kernel-mode-приложения были подписаны сертификатом, выпущенным доверенным центром сертификации. Как вы уже поняли, перечисленный перечень удостоверяющих процедур призваны осуществить функции, предоставляемые (экспортируемые) библиотекой ci.dll.
Справедливы следующие утверждения:

  • Библиотека ci.dll присутствует в операционных системах Windows 7 и новее.
  • Библиотека ci.dll функционирует в только в ситуации, когда Windows загружается в штатном (нормальном) режиме загрузки, подразумевающем отключенный режим отладки (Debug mode) и включенную проверку целостности драйверов (ENABLE_DRIVER_INTEGRITY).
  • основное назначение библиотеки ci.dll - проверка целостности драйверов и компонентов (подписанных цифровой подписью). Поэтому, логично что функции библиотеки ci.dll могут возвращать запрашивающему коду некий статус, сигнализирующий об успешном/неудачном прохождении вышеуказанных проверок целостности.
  • Библиотека ci.dll обеспечивает поддержку следующих алгоритмов: проверка цифровой подписи RSA PKCS#1 (v1.5), хэш SHA-1, хэш SHA-256, хэш SHA-384, хэш SHA-512.
  • Библиотека ci.dll обеспечивает на этапе инициализации тесты собственной целостности с использованием следующих алгоритмов: SHS (SHA-1) проверка известного ответа, SHS (SHA-256) проверка известного ответа, SHS (SHA-512) проверка известного ответа, RSA проверка на основе теста с использованием известной подписи формата PKCS#1 v1.5.

Теперь для лучшего понимания следующего далее материла дадим пару определений.

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

Экспортируемые и внутренние функции библиотеки:

Функция Описание
CiCheckSignedFile() Для выборки и подписи Authenticode, проверяет можно ли получить выборку из подписи и что сама подпись является подлинной. (Опционально) может возвращать информацию о подписи.
CiFindPageHashesInCatalog() Для выборки и подписи Authenticode первой страницы PE-образа, подтверждает что выборку можно получить из .cat-файла, содержащегося в проверяемом системном каталоге. (Опционально) может возвращать информацию по каталогу.
CiFindPageHashesInSignedFile() Для выборки и подписи Authenticode первой страницы PE-образа, проверяет можно ли получить выборку из подписи и что сама подпись является подлинной. (Опционально) может возвращать информацию о подписи.
CiFreePolicyInfo() Освобождает память, выделенную ранее функциями CiVerifyHashInCatalog, CiCheckSignedFile, CiFindPageHashesInCatalog и CiFindPageHashesInSignedFile. Исключительно внутренняя сервисная функция.
CiGetPEInformation() Функция возвращает системные конфигурационные данные, связанные с подписанным (защищенным) образом.
CiInitialize() Функция проверки кода ядра и начальной (инициализации) настройки адресов функций обратного вызова для последующего обращения.
CiVerifyHashInCatalog() Для Authenticode-выборки файла, проверяет что выборку можно получить из .cat-файла, содержащегося в проверяемом системном каталоге. (Опционально) может возвращать информацию по каталогу.
Функция Описание
CiValidateImageHeader() Проверяет заголовки исполняемого образа.
CiValidateImageData() Проверяет данные секций исполняемого образа.

Из ядра Windows 7, например, на этапе начальной загрузки, вызываются функции CiInitialize(), CiValidateImageHeader(), CiValidateImageData(). Если проверка собственной целостности не проходит, то функция CiInitialize() возвращает статус STATUS_UNSUCCESSFUL, в этом случае загрузка операционной системы прекращается с ошибкой. В случае успешного прохождения тестов, функция CiInitialize() возвращает (инициализированную) структуру с именем _g_CiCallbacks, через которую впоследствии будет осуществляться обратный вызов экспортируемых и некоторых внутренних функций (были описаны выше). Вызывающий код впоследствии может использовать эти функции для проведения проверки любого исполняемого образа на целостность.

Отключение проверки образов

Любые, представленные в данном разделе модификации приведены исключительно для ознакомления и выполнялись исключительно из исследовательских соображений с единственной целью определения причин зависания процедуры загрузки операционной системы на ранних этапах (на этапе выполнения модулей winload.exe/ntoskrnl.exe).

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

Можно было непосредственно изменить его, тем не менее, более корректным вариантом будет изменить код вызываемой "вложенной" функции PEProcessDispatch:

Требуется заменить начальные байты функции так, что бы значение регистра eax (в котором возвращается результат выполнения) равнялось 0 и сразу после этого осуществлялся возврат из функции.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *