Проверка электронной цифровой подписи Authenticode. Часть 3. Набор программ

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
8,030
Решения
13
Реакции
6,805
Это продолжение. См. также другие части этой статьи:

Часть 1. Кусочек теории.
Часть 2. Описание реализации программы проверки подписей

Часть 3. Программа проверки Authenticode ЭЦП

Это программа проверки цифровых подписей (ЭЦП) форматов файлов, содержащих код, таких как Portable Executable и прочих.

С чего начать?
Для программистов VB6/VBA:
- просто добавьте в вашу программу модуль 'modDigiSign.bas' и посмотрите ‘Примеры использования’ ниже.
Для программистов других языков:
- не стесняйтесь, моя программа использует чисто WinAPI, и может послужить вам хорошей подсказкой, если не сможете найти нужной вам реализации в примерах из сети. В частности рекомендую OpenSource проект ‘Process Hacker’.

Назначение
Данный модуль хорошо протестирован и позволяет проверить:
- является ли ЭЦП легитимной (без необходимости в подключении к интернет)
- является ли WHQL подпись драйвера легитимной
- принадлежит ли подпись Microsoft
- является ли подпись встроенной (внутренней) или внешней (подпись через каталог)
- присутствует ли подпись (проверкой в структуре PE)

Утилита также показывает такую информацию о сертификатах:
- срок действия (начало / конец)
- кем выдан
- кому выдан
- электронная почта

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

Демо-проект также содержит код для проверки:
- соответствует ли файл PE формату
- защищён ли файл через SFC / WPF
Создаёт отчёт в формате CSV.

Совместимость
ОС: Windows 10 / 8.1 / 8 / 7 / Vista / XP / 2000, x32 и x64 бит, включая 64-битные исполняемые файлы и 64-битные папки.
Алгоритмы хешей подписи / выборки: MD5, SHA1, SHA256.
Юникодная поддержка.
Без зависимостей от библиотек сторонних производителей (используется CryptoAPI).

Требования
- Если вы используете в программе х64 файловый переадресатор, убедитесь, что он не отключён перед тем, как использовать функции из этого модуля.
Это очень важно! Если вы не можете гарантировать это, чтобы быть уверенным в совместимости, вы можете заменить свои функции на мою обёртку "ToggleWow64FSRedirection (true / false)".
- Не используйте какие-либо виды виртуализации при работе в IDE, вроде 'режима совместимости с XP'. Это может негативно повлиять на результаты проверки.

Примеры использования

Основной синтаксис:
VB.NET / VBA:
Dim SignResult As SignResult_TYPE

SignVerify [Файл для проверки], [Флаги], [out_Структура с результатом проверки]

1.1. Проверка, является ли подпись легитимной с выводом всей доступной информации.

VB.NET / VBA:
Dim SignResult As SignResult_TYPE

Debug.? "Подписан и проверен ? " & SignVerify("c:\путь\Файл_для_теста.exe", 0, SignResult)

1.2. Вывод подробного описания:

VB.NET / VBA:
with SignResult
    debug.? "Легитимна?                       " & .isLegit
    debug.? "Подписан?                        " & .isSigned
    debug.? "Внутренняя подпись?              " & .isEmbedded
    debug.? "Подписан через каталог?          " & .isSignedByCert
    debug.? "Путь к каталогу?                 " & .CatalogPath
    debug.? "Самоподписанный?                 " & .isSelfSigned
    debug.? "Хеш корневого сертификата:       " & .HashRootCert
    debug.? "Authenticode (PE) хеш файла:     " & .HashFileCode
    debug.? "Подпись Microsoft?               " & .isMicrosoftSign
    debug.? "Кто выдал сертификат?            " & .Issuer
    debug.? "Кто подписал (имя)?              " & .SubjectName
    debug.? "Кто подписал (email)?            " & .SubjectEmail
    debug.? "Сертификат действителен, начиная с даты: " & .DateCertBegin
    debug.? "Сертификат действителен до:      " & .DateCertExpired
    debug.? "Время подписания (штамп сервера времени): " & .DateTimeStamp
    debug.? "Результаты проверки – Код:       " & .ReturnCode
    debug.? "Результаты проверки – Краткое описание: " & .ShortMessage
    debug.? "Результаты проверки – Детальное описание: " & .FullMessage
    debug.? "Алгоритм хеша подписи сертификата:        " & .AlgorithmCertHash
    debug.? "Алгоритм хеша выборки:           " & .AlgorithmSignDigest
    debug.? "Не содержит подписи?             " & (.ReturnCode = &H800B0100)
    debug.? "Количество подписей (Win8+):     " .NumberOfSigns
end with

2. Проверить, подписан ли файл Microsoft:
VB.NET / VBA:
debug.? IsMicrosoftFile("c:\windows\explorer.exe")

Описание флагов

VB.NET / VBA:
Public Enum FLAGS_SignVerify
    SV_CheckRevocation = 1         ' – проверить всю цепочку доверия на предмет отзыва сертификата ( потребуется подключение к интернет )
    SV_DisableCatalogVerify = 2    ' – не выполнять проверку через каталог безопасности ( будет проверена только внутренняя подпись )
    SV_isDriver = 4                ' – проверить подпись WHQL драйвера
    SV_CacheDoNotLoad = 8          ' – не считывать последний результат проверки из кеша
    SV_CacheDoNotSave = 16         ' – не сохранять результаты проверки в кеш (бережёт ОЗУ)
    SV_CacheFree = 32                  ' – освободить память, занятую подсистемой кеширования
    SV_AllowSelfSigned = 64        ' – рассматривать само-подписанные сертификаты как легитимные
    SV_AllowExpired = 128           ' – разрешить подписи с просроченным сертификатом (см. далее раздел «Теория: что означает, легитимна ли подпись?»)
    SV_CheckEmbeddedPresence = 256 ' – всегда проверять присутствие внутренней подписи ( даже если проверка была выполнена через каталог безопасности ). Влияет на поле isEmbedded.
    SV_CheckSecondarySignature = 512 ' проверить вторичную внутреннюю подпись (проверка по каталогу безопасности выполняться не будет)
    SV_NoFileSizeLimit = 1024       ' – разрешить проверку файлов с любым размером ( по-умолчанию, установлен лимит в 100 МБ. )
End Enum

Дополнительная информация

1. Цепочка доверия
Модуль перечисляет все сертификаты по цепочке доверия. Из корневого сертификата извлекается SHA256 хеш. Из финального – вся остальная информация. Если Вам нужно извлечь информацию из промежуточных сертификатов, вы можете сделать это самостоятельно. Все указатели на сертификаты хранятся в массиве Signature(0).Certificate() в функции GetSignerInfo().

2. Проверка, отозван ли сертификат (флаг SV_CheckRevocation)
Я специально сделал, чтобы процесс проверки подписи не требовал подключения к сети. Таким образом, проверка выполняется быстро, а программа не будет подвисать.
Проверка на отзыв сертификата выполняться не будет. Если она вам нужна, добавьте флаг SV_CheckRevocation. Будьте осторожны, проверка на отзыв может занять более 5 секунд и даже привести к зависанию программы, если у системы имеются проблемы с подключением к интернет (рекомендуется вынести такую проверку в отдельный поток).
На самом деле, этот вид проверки требуется в очень редких случаях, например, если вам нужно убедиться, что сертификат не был отозван из-за того, что его украли и используют во вредоносных целях.

3. Кеш (флаги SV_CacheDoNotSave, SV_CacheDoNotLoad)
По-умолчанию, результаты проверки сохраняются, используя Scripting.Dictionary. При проверке одинакового пути функция будет возвращаться всегда один и тот же результат. Чтобы запретить кеширование, возведите флаг SV_CacheDoNotSave. Чтобы одноразово запретить чтение результата из кеша, укажите флаг SV_CacheDoNotLoad.

3.1. Условная константа #UseSimpleCatCheck.
Позволяет задействовать дополнительный уровень кеширования. Работает это так: если один из файлов был успешно проверен по каталогу безопасности, то из этого каталога считываются все остальные хеши файлов и заносятся в кеш. Если в следующий раз в функцию проверки попадёт файл, хеш которого совпадёт с занесённым в кеш, то его верификация через WinVerifyTrust не будет проводиться, т.к. подпись каталога безопасности, в котором хранится этот хеш, уже была проверена ранее.

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

Есть и официальный способ для проверки подписи Майкрософт: воспользоваться функцией CertVerifyCertificateChainPolicy(), передав ей флаг CERT_CHAIN_POLICY_MICROSOFT_ROOT.

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

В программе не учитывается распознавание случаев со старыми сертификатами MD2/MD5 (Windows NT и ниже), когда Майкрософт подписывала некоторые файлы через промежуточный CA, сертификат которого выдан VeriSign:

3.1.Verisign_MS.webp


Демо-приложение Digital Signature Checker

3.2.SigVerifyTool_face.webp


Укажите список файлов и/или папок для проверки (по одной на строку) и нажмите кнопку «Go».

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

VB.NET / VBA:
SV c:\file.exe
Проверка самого себя:
H:\_AVZ\Наши разработки\_Dragokas\DigiSignChecker\SignVerify>sv sv.exe
--------------------------------------------------
Verified file: sv.exe
Legitimate? False
Signed? True
Signed by internal signature? True
Signed by catalogue? False
Catalogue location:
Self-signed? True
Root certificate hash: 05F1F2D5BA84CDD6866B37AB342969515E3D912E
Authenticode (PE) file hash: 2A74534CEA1E23385D0D1FC6732EBB634534497A
Is Microsoft signature? False
Who issued cert.? Alex Dragokas
Who signed PE EXE (name)? Alex Dragokas
Who signed PE EXE (email)?
Certificate valid from date: 30.06.2014 23:59:42
Certificate expired date: 01.01.2040 2:59:59
Signature time stamp: 10.05.2017 22:50:14
Verify results - Code: -2146762487
Verify results - Short description: CERT_E_UNTRUSTEDROOT: Verified, but self-signed
Verify results - Extended description: Цепочка сертификатов обработана, но обработка прервана на корневом сертификате, у
которого отсутствует отношение доверия с поставщиком доверия.
Cert. sign. hash algorithm: SHA-1 OIWSEC_RSA
Digest hash algorithm: SHA-256 NIST
Number of signatures (Win8+): 1

Заключение
Выше рассмотрен порядок работы модуля ‘modDigiSign.bas’, даны базовые знания о видах сертификатов, способах подписания, назначения подписи и принципе её проверки. В приложении предоставлено несколько программных реализаций на языках VB6 и C++.

Некоторые технические аспекты остались не охваченными, в частности, проверка подписи через CNG (Cryptography API: Next Generation), которая пришла на замену CryptoAPI, начиная с Windows Vista, а также о том, как ОС проверяет подпись системных файлов, прежде чем разрешить их запуск/загрузку, в особенности – уровни подписи, которые были введены в Windows 8.

Если Вам будет интересно углубиться, вы можете обратиться к дополнительной литературе в конце статьи. Например, по этой ссылке на японском: EternalWindows.jp - Certificate validation (гугло-переводчик в помощь ) неплохо описываются параметры функций для проверки ЭЦП, проверки индивидуальных сертификатов по цепочке доверия, извлечения данных из сертификатов, получения и просмотра списка отзывов (CRL) с соответствующими примерами на C++. А по уровням подписи вы можете почитать:
Alex Ionescu. The Evolution of Protected Processes Part 1: Pass-the-Hash Mitigations in Windows 8.1
Alex Ionescu. The Evolution of Protected Processes Part 2: Exploit/Jailbreak Mitigations, Unkillable Processes and Protected Services
Alex Ionescu. Protected Processes Part 3 : Windows PKI Internals (Signing Levels, Scenarios, Root Keys, EKUs & Runtime Signers)

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

Спасибо за внимание и удачи всем !!!
С наилучшими пожеланиями,
Польшин Станислав.


Приложения:
Программа Batch Digital Signature Verifier (GUI приложение пакетной проверки подписей)
Программа Certificate Enumerator (перечисление имён и хешей сертификатов в корневом хранилище)
Программа RemoveSign (удаление ЭЦП)
Проект SignVerify с модулем modDigiSign.bas (в двух видах – демо для консоли отладки и консольная программа SV с тестовым батником test.cmd)
Doc-файл (эта статья).

Дополнительная литература:

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

Вложения

Последнее редактирование:
Назад
Сверху Снизу