Статья Проверка электронной цифровой подписи Authenticode. Часть 1. Теория
Dragokas
Very kind Developer
Привет!
Я как-то довольно давно заинтересовался темой цифровых подписей, какова их защита, как они устроены изнутри, как с ними работать из-под CryptoAPI. По мере изучения возникало много подводных камней. Наконец, я готов рассказать и вам на доступном языке о принципах шифрования и подписания, практике и готовой реализации проверки подписей.
Содержание:
Часть 1. Кусочек теории.
Dragokas
Very kind Developer
1.1. Что такое электронная цифровая подпись (ЭЦП) и зачем она нужна?
ЭЦП – это информация, с помощью которой можно удостовериться, что:
1. Файл подписан конкретным издателем;
2. Файл не повреждён после того, как его подписали.
Это гарантирует, что файл получен от доверенного (на ваш субъективный взгляд) издателя и не был модифицирован (перепакован, пропатчен, повреждён при скачивании случайно или специально).
Если проверка ЭЦП прошла успешно, то при запуске с повышенными привилегиями, в окне UAC вы увидите слова «Проверенный издатель» и его имя:
А если эта программа запускается без повышения привилегий, то после скачивания с сети при запуске вы получите предупреждение:
А вот в случае с легитимной подписью система не будет отображать этого сообщения для файла, у которого при запуске присутствует поток Zone.Identifier:$DATA.
Также из положительных моментов, такую подпись в перспективе можно будет внести в белые списки производителей антивирусов.
Если вы планируете разрабатывать драйвера для распространения, цифровая подпись будет обязательна.
Также, приложениям, подписанным легитимной ЭЦП, разрешается запуск с уровнем целостности UIAccess при указании соответствующего параметра в манифесте и размещении файла программы в одном из безопасных расположений.
1.2. Надёжность ЭЦП и эксплуатация вредоносным ПО.
1.2.1. Человеческий фактор и приватные ключи.
Известно много случаев, когда издатель получил сертификат законно, но использует его для распространения вредоносных или нежелательных программ. Пример: Lenovo – раз, два.
Некоторые компании по расторопности распространяли программу вместе с приватными ключами. Пример: снова Lenovo. И вот результат. Также периодически бывают случаи кражи сертификатов у хорошо известных производителей. Пример: Foxconn и ПО Duqu2. Поэтому не стоит слепо доверять цифровой подписи. Однако, запуская файл, вы сможете убедиться, что его создал, например, Петя, а не злой сосед Вася . Даже если центр сертификации (CA) выпустит сертификат на имя, схожее с уже существующими, существует механизм отзыва сертификатов. Правда, никто Вам не скажет сколько ПК успеет заразиться за это время.
1.2.2. Уязвимости в структуре ЭЦП.
Следует учитывать, что проверяется целостность только кода (исполняемой части файла), а не всего файла целиком. Некоторые недобросовестные программисты (в т.ч. именитые фирмы – в этических целях я не буду их называть) в целях упрощения / экономии используют один и тот же бинарный образ уже готовой подписи для разных файлов (без переподписания), добавляя свои метаданные прямо в структуру подписи, в ту её часть, что не проверяется. Для обеспечения более строгой проверки структуры подписи существует твик реестра, выпущенный в рамках бюллетеня безопасности Microsoft. Однако, такая защита вызывала больше проблем, чем пользы, даже во время запуска служб Майкрософт. Так что фикс был отозван.
С оглядкой на данный фикс, некоторые особо хитрые разработчики нашли и другие лазейки для обхода проверки с другой стороны (заодно открыв новую дыру в своём ПО). Как результат, известны случаи создания дроппера вредоносного ПО способом пропатчивания файла без повреждения ЭЦП у программ данных конкретных разработчиков.
С этических соображений, подробности и ссылки на источники я не буду публиковать.
1.2.3. Стойкость алгоритма хеша.
Наиболее старый из алгоритмов хеша подписи, который вы всё ещё можете встретить, – это MD5. Он использовался для подписания части системных файлов в ОС Windows 2000 и ранее.
В частности, некоторые исполняемые файлы подвержены атаке SHAttered, которая работает
в 100.000 раз быстрее, чем полный перебор. Чтобы проверить подвержен ли файл с SHA1 быстрому подбору коллизии, можно воспользоваться инструментом sha1collisiondetection, разработанным Marc Stevens (CWI) и Dan Shumow (Microsoft) и доступным на GitHub. Если это подтверждается, достаточно перекомпилировать файл и проверить его снова.
В данный момент для подписания файлов используется в основном только алгоритм SHA2, а сертификаты подписываются только SHA2 (детальнее см. раздел 1.6 «Двойная подпись»).
Время, начиная с которого сертификаты с хешем SHA1 признаются не крипто-стойкими, указано в ветке реестра (на Win 8.1 и выше):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CertDllCreateCertificateChainEngine\Config\Default => WeakSha1ThirdPartyAfterTime (FILETIME)
Для SHA1 – это дата 01.01.2016.
Для MD5 – это дата 01.03.2009.
Подписи файлов, поставленные с использованием этих алгоритмов позже указанной даты, будут считаться недействительными.
Детальнее, см. Microsoft TechNet. Protecting Against Weak Cryptographic Algorithms.
1.3. Что означает, легитимна ли подпись?
Эта подпись должна быть выдана центром сертификации (Certification authority (CA)), чей сертификат находится в хранилище доверенных корневых сертификатов (TRCA), либо вшит в системные файлы, являющиеся частью механизма проверки.
Вы можете увидеть TRCA через оснастку certmgr.msc
Соответственно, одного их этих CA можно увидеть в цепочке доверия в свойствах файла => вкладка «Цифровая подпись» => Сведения => Просмотр сертификата => Путь сертификации:
Проверка подписи выполняется передачей идентификатора политики WINTRUST_ACTION_GENERIC_VERIFY_V2 в функцию WinVerifyTrust(). Эта политика выдвигает такие требования:
1) Все сертификаты вверх по цепочке доверия в подписанном файле должны также находиться и в хранилище доверенных корневых сертификатов.
Пример, когда часть сертификатов не являются доверенными:
2) Конечный сертификат должен иметь разрешение на подписание кода. Это отображено в поле «Назначение сертификата» (EKU).
3) Не вышел срок действия сертификата (за одним исключением*).
*Если на файл наложена подпись