• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Змей и Яблоко. Часть 2. Подпись кода.

Norbert Beaver

CD-диск
Пользователь
Регистрация
29.02.2024
Сообщения
15
Реакции
22
Автор перевода: Norbert Beaver
Переведено специально для форума xss.pro
Источник:
github.com/Karmaz95/Snake_Apple/blob/main/README.md

В данной статье описывается принцип работы подписания кода, а также способы чтения подписи кода на системе macOS.

0.png


ВВЕДЕНИЕ

Добро пожаловать в очередную статью из серии о внутренней безопасности macOS!

Эта статья предоставляет подробную информацию о формате подписи кода и объясняет, как происходит процесс подписи. Здесь вы узнаете:
  • Как определить, имеет ли файл действительную подпись
  • Где хранятся разрешения и требования
  • Низкоуровневый формат всех элементов подписи кода
  • Концепция временной (ad hoc) подписи и криптографии с открытым ключом
  • Формат ASN.1 и многое другое…
Кроме того, в статье будет объяснено, как извлекать важную информацию из подписи кода в удобочитаемой форме с помощью Python и других инструментов.

Подписание кода

Подписание кода гарантирует целостность программного обеспечения и идентификацию его автора.

Также, обеспечивает аутентичность и целостность файлов Mach-O. Это является обязательным требованием в современных версиях macOS. Пример ниже упрощает понимание:
1.png


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

Упрощенный процесс подписи:
  • Разделение данных. Все данные делятся на страницы размером 0x1000 (4096 байт).
  • Хеширование. Каждая страница хешируется с использованием алгоритма sha256, а хеши сохраняются в структуре CS_CodeDirectory.
  • Хэш-сообщение. CS_CodeDirectory хешируется для генерации CDHash, который сохраняется в структуре SignedAttr внутри подписи CMS. Затем вся структура снова хешируется для генерации хэш-сообщения.
  • Шифрование. Хэш-сообщение шифруется с использованием закрытого ключа, соответствующего сертификату подписи, и сохраняется как подпись в CMS.
  • Подпись CMS. Формируется окончательное криптографическое доказательство (подпись CMS), которое содержит подпись SignedAttr (CDHash), зашифрованное хэш-сообщение и цепочку доверия сертификатов вместе с сертификатом подписи.
Сертификат подписи включает в себя открытый ключ, используемый для расшифровки подписи.

Временная подпись

Современная macOS на процессорах ARM64 требует, чтобы весь код был как минимум временно подписан. Компоновщик автоматически подпишет бинарный файл после компиляции. Это делает подпись кода постоянной частью формата файла Mach-O.
2.png

Пример бинарного файла с временной подписью от компоновщика

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

Пример подписи с нарушенной целостностью из-за модификации байткода

Чтобы повторно подписать бинарный файл с использованием подписи без сертификата, используйте - .

codesign --force --sign - YOUR_BINARY

Обратите внимание, что флаг, поставленный компоновщиком, отсутствует, и идентификатор изменился:
4.png

Временная подпись означает подписание бинарного файла без криптографического доказательства.

Временно подписанные бинарные файлы Apple проверяются путем сравнения хэша CDHash (sha256) с списком известных действительных CDHash, хранящихся в кэшах доверия AMFI.

Код:
/System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/BaseSystemTrustCache.img4
/System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/StaticTrustCache.img4
/System/Library/Security/OSLaunchPolicyData
5.png

Примеры хешей (исходная структура)

Я создал TrustCacheParser для разбора кэшей доверия. Он основан на PyIMG4 и trustcache. Прежде чем использовать его, необходимо установить эти библиотеки:

Код:
python3 -m pip install pyimg4
wget https://github.com/CRKatri/trustcache/releases/download/v2.0/trustcache_macos_arm64 -O /usr/local/bin/trustcache
chmod +x /usr/local/bin/trustcache
xattr -d com.apple.quarantine /usr/local/bin/trustcache

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

Сертификация и нотаризация

Подписанные временно бинарные файлы будут работать только локально и не пройдут проверку Gatekeeper в других местах. Они подходят только для локального тестирования:
6.png

Пример временно подписанного бинарного файла, распространенного на другую macOS, который заблокирован Gatekeeper-ом

Для распространения вашего кода среди других пользователей подпишите его с использованием сертификата Developer ID от учетной записи разработчика Apple и пройдите процедуру нотаризации.
Для руководства по нотаризации проверьте документ Notarizing macOS software before distribution.​

Подпись кода

Я уже рассмотрел формат Mach-O и его компонентов в предыдущей статье: karol-mazurek.medium.com/snake-apple-i-mach-o-a8eda4b87263

Однако я не описал подпись кода, добавленную в конце файла и загруженную через LC_CODE_SIGNATURE:
7.png

Изображение ниже показывает один и тот же бинарный файл, открытый дважды в MachOView, чтобы показать, как загружается подпись кода и её место в файле Mach-O:
8.png

Обзор структуры

На изображении ниже показана упрощенная структура подписи кода:
9.png

10.png

Подпись кода может быть разделена на:
  • Super Blobсписок других блоков (блок каталога кода, блок требований, блок полномочий, блок подписи).
  • Каталог кодасодержит криптографические хеши, которые фиксируют исполняемые страницы кода, ресурсы и метаданные.
  • Требованиекритерии, которым должна соответствовать кодовая подпись, прежде чем исполняемый файл будет разрешено запускать.
  • Полномочия (XML и DER) — пары ключ-значение, которые дают исполняемому файлу разрешение на использование различных системных ресурсов, таких как сеть, файловая система и т.д.
  • Подпись CMSсама криптографическая подпись в формате Cryptographic Message Syntax (CMS), определённом в RFC565, используемая для валидации.

Что такое Blob?

Большой бинарный объект
(Binary Large Object) — это коллекция бинарных данных, хранящихся как единое целое.

Самодостаточный, структурированный объект данных используется для хранения и управления различными типами информации без фиксированной схемы.

Ключевая идея здесь в том, что SuperBlob действует как контейнер для различных блоков (blob), каждый из которых выполняет свою собственную задачу, что упрощает их разбор и проверку целостности и подлинности кода. Вы можете увидеть его структуру ниже:
11.png

Как видно выше, SuperBlob начинается с magic, [URL='https://github.com/Karmaz95/Snake_Apple/blob/main/II.%20Code%20Signing/mac/cs_blobs.h#L278']length[/URL] и count всех блоков внутри. Затем идет type и offset для каждого блока.

Каждый блок имеет 4-байтовое значение magic, 4-байтовую length (включая размер поля магического числа и длины), и данные, определенные соответствующим типом блока.
12.png

Структура блока это Type-Length-Value

Пример структуры блоков (нулевые байты были удалены для видимости):
13.png

Блок каталога кода

Наиболее важным является то, что он хранит хеши всего бинарного файла в слотах кода.

Каталог кода включает в себя такие детали, как версия каталога кода, флаги, информация о хешах для слотов кода, платформа и размер страницы.

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

Текущая структура каталога кода показана ниже:
14.png

15.png

Пример блока каталога кода (версия 0x20400)

Каталог кода — слоты кода

Хеши хранятся в слотах кода — один хеш на каждую страницу (4096 байт).

Хеш первой страницы хранится в слоте 0. Однако есть нюанс. Последний слот кода может быть меньше и заканчивается там, где начинается кодовая подпись.
16.png

Изображение показывает пример смещения последнего байта страницы памяти на 0xC520.

Для примера, посмотрите на бинарный файл ниже в MachOView:
17.png

Изображение показывает начальное смещение кодовой подписи на 0xC520.
  • Кодовая подпись начинается со смещения 0xC520.
  • Последняя страница памяти должна быть кратна 0x1000 без остатка.
  • В данном случае это будет 0xC000:
18.png

Python:
def roundToLastPage(hex_number):
    rounded_number = (hex_number + 0xFFF) & 0xFFFFE000
    return hex(rounded_number)

Чтобы подтвердить это предположение, вычислите последний хеш и сравните его с выводом команды codesign:
19.png

Сравнение хеша последней страницы памяти.

Каталог кода — специальные слоты

Они представлены отрицательными числами в выводе команды codesign.
20.png

Ниже приведён пример каталога кода версии 20400 без каких-либо флагов времени выполнения, содержащий 15 слотов хешей sha256, из которых 2 являются специальными.

Вы можете заметить, что слот -1 содержит только нули. Это связано с тем, что для нашего примерного бинарного файла нет списка свойств информации (Info.plist). Слот -2 хранит хеш поля требований, которое присутствует в нашем бинарном файле:
21.png

Хеши соответствуют страницам памяти бинарного файла (начиная с первого байта бинарного файла) и хранятся в слотах кода, начиная с слота 0.
Чтобы вручную вычислить тот же хеш, который хранится в блоге каталога кода, выведите первые 0x1000 байт бинарного файла:

Python:
dd bs=1 skip=0 count=0x1000 if=signed_ad_hoc_example 2>/dev/null | sha256sum

Как видно, вывод первого хеша в слоте кода совпадает:
22.png

Каталог кода — Флаги

Каталог кода — Флаги


Они являются необязательными и регулируют использование подписи.
23.png


Для справки: SecCodeSignatureFlags.​

Каталог кода — CDHash

Это финальный хеш, созданный путём хеширования всего блога каталога кода.
Ниже изображены магические байты каталога кода 0xFADE0C02 вместе с его длиной 0x259, хранящимися в кодовой подписи:
24.png

Чтобы показать пример, вы можете сгенерировать CDHash вручную, извлекая 0x259 байт, начиная с смещения 0xC544, и передав их в sha256sum:

Python:
dd bs=1 skip=0xc544 count=0x259 if=signed_ad_hoc_example 2>/dev/null | sha256sum

Хеш, рассчитанный таким образом, совпадает с выводом команды codesign.
25.png

Один и тот же CDHash из вывода команды codesign и при ручном разборе.

Этот хеш вычисляется перед выполнением основного кода бинарного файла, а затем сравнивается с CDHash в подписи CMS.

Блок требований

Указывает дополнительные условия, необходимые для действительности подписи.
Блок требований начинается с магических байтов 0xFADE0C01 и оборачивает другие отдельные блоки требований, начинающиеся с магических байтов 0xFADE0C00.
26.png

Пример блока требований

Для разбора используйте команду codesign с флагом -r:
Код:
codesign -d -r - YOUR_APP
27.png

Пример стандартных требований

Основываясь на приведённом примере, требования следующие:
  • Идентификатор: signed_ad_hoc_example
  • Цепочка сертификатов должна вести к корневому сертификату Apple: anchor apple generic
  • Листовой (подписывающий) сертификат должен быть: Apple Development:(XXXXXXXXXX)
  • Сертификат, выдающий листовой сертификат, должен иметь поле 1.2.840.113635.100.6.2.1, что означает, что он должен быть выдан Apple Worldwide Developer Relations Certification Authority.
Требования заданы на языке требований к кодовой подписи, закодированном с помощью опкодов, определённых в requirement.h. Хеш требований хранится в специальном слоте. Для справки посетите: TN3127: Inside Code Signing: Requirements.​

Ресурсы

Подпись кода защищает его и ресурсы, если ваш код упакован.
Хеши ресурсов хранятся в файле CodeResources PLIST:
28.png

Ключ files хранит хеш в формате sha1 для обратной совместимости, в то время как files2 хранит sha256. Они представлены в виде закодированных в base64 необработанных байтов.
29.png

Пример sha1 хеша из ключа files в файле CodeResources.

Финальный хеш вычисляется на основе содержимого CodeResources и хранится в слоте -3 в каталоге кода. Чтобы вычислить этот хеш вручную, используйте:

Код:
openssl sha256 "$YOUR_APP/Contents/_CodeSignature/CodeResources"

Как видно, хеш в слоте -3 совпадает с вычисленным нами:
30.png

Хеш ресурсов

Блоки полномочий

Предоставляют исполняемому файлу разрешение на использование сервиса или технологии.

Существует два блока полномочий:
Первый, хранящийся в формате XML, начинается с магических байтов 0xFADE7171, а его хеш хранится в слоте -5.
Второй, хранящийся в формате DER, начинается с магических байтов 0xFADE7172, а его хеш хранится в слоте -7. Оба блока полномочий содержат одни и те же данные.
31.png

Пример обоих блоков полномочий

Пример блока полномочий в формате XML:
32.png

Мне кажется, что Apple медленно отказывается от формата XML, и в будущем может остаться только формат DER:
Чтобы разобрать блок полномочий, используйте команду codesign с флагом --entitlements:

Код:
codesign -d --entitlements - --xml YOUR_APP | plutil -convert xml1 -o - -
codesign -d --entitlements - --der YOUR_APP
codesign -d --entitlements - YOUR_APP

Для справки: Полномочия и Полномочия на macOS.

Blob подписи CMS (BLOBWRAPPER)

Это сердце кодовой подписи. Он используется для подписания кода и его валидации.

Наиболее важно, что он хранит зашифрованный хеш каталога кода в качестве подписи и сертификата подписи, а также открытый ключ, используемый для расшифровки.
Ниже показана структура одного сертификата:
33.png


Подпись CMS хранит все сертификаты для проверки цепочки доверия. Вы можете извлечь их с помощью команды codesign и разобрать с помощью openssl:

Код:
codesign -d --extract-certificates=cert_ YOUR_APP
openssl x509 -text -noout -in cert_0

При использовании выше представленной команды, вы получите 3 файла, содержащие сертификаты:
34.png

Они используются для проверки целостности сертификата подписи (cert_0). Вы можете вручную проверить цепочку доверия сертификатов с помощью openssl:

Код:
for i in 0 1 2; do openssl x509 -in "cert_$i" -out "cert_$i.pem"; done
openssl verify -CAfile cert_2.pem cert_1.pem
openssl verify -CAfile cert_1.pem cert_0.pem

Больше о цепочке доверия сертификатов: Руководство по криптографическим сервисам.​

Однако подпись CMS — это не просто эти три сертификата. Прежде всего, она представлена в формате Distinguished Encoding Rules (DER), который является основным форматом сериализации ASN.1 и начинается с байта 0x30.


CMS Signature Blob начинается с магических байтов 0xFADE0B01 и в формате ASN.1 оборачивает эти три сертификата вместе с другой информацией:
35.png

Источник: Собственное исследование — пример CMS Signature Blob.

Я не нашел способа извлечь весь blob с помощью codesign. Я создал опцию --extract_cms для CrimsonUroboros для извлечения:
3_6.png

Вы также можете использовать приведенный ниже bash-скрипт:
Код:
# Путь к файлу
binary_path="YOUR_APP"
# Извлечение сдвига магических байтов
binary_in_hex=$(xxd -p -u -c0 "$binary_path")
# Это будет работать с multiarch-приложением - учитываться будет только первый сдвиг (NR==1)
offset=$(echo -n "$binary_in_hex" | grep -ob 'FADE0B01' | awk -F: 'NR==1{print $1}')
# Данные CMS появляются после магических байтов и длины, поэтому вы должны добавить 8 байтов к значению сдвига
CMS_offset_in_dec=$(( ($offset / 2) + 8))
# Извлечение длины blob
CMS_length=$(echo -n "$binary_in_hex" | awk 'match($0, /FADE0B01/) { print substr($0, RSTART + RLENGTH, 8) }')
# Извлечение подписи CMS из файла
dd bs=1 skip="$CMS_offset_in_dec" count="0x$CMS_length" if="$binary_path" of=cms_sign 2>/dev/null
Затем вы можете проверить подпись CMS с помощью openssl:
Код:
openssl cms -cmsout -print -inform DER -in cms_sign
Я также создал SignatureReader для разбора в человекочитаемом формате:
Код:
SignatureReader --load_cms cms_sign --human
Вывод из команды выше находится в формате Cryptographic Message Syntax, описанном в RFC 5652. Я [...УДАЛИЛ...] некоторые части для улучшения читаемости:
36.png

Как вы можете видеть, помимо сертификатов существует много других данных, но наиболее важными являются зашифрованные signedAttrs, хранящиеся в виде подписи.
37.png

Упрощенный процесс подписи

signedAttrs содержит CDHash и другую информацию, которая должна быть включена для обеспечения целостности подписи в соответствии с:


signedAttrs сначала хэшируется с использованием алгоритма, указанного в:
38.png

39.png

Декодирование ASN.1 с помощью онлайн-декодера для отображения алгоритма

Чтобы точно увидеть, что здесь происходит, выведите все signedAttrs. Чтобы получить точное смещение, вы можете навести курсор на поле SignedAttributes:
40.png

Пример смещения SignedAttributes

Имея эту информацию, используйте openssl для извлечения signedAttrs:
Код:
openssl asn1parse -in cms_sign -inform DER -strparse 4035 -noout -out signedAttrs
Чтобы получить дайджест сообщения, который нужно зашифровать, вы должны хешировать его с использованием указанного алгоритма, но есть одна загвоздка. Если вы посмотрите на первый байт выгруженных signedAttrs, вы увидите байт 0x0A:
41.png

Выгруженные signedAttrs

Тег SET OF (0x31) должен использоваться вместо тега IMPLICIT[0] (закодированного как 0xA0) для первого байта, как указано в RFC 5652#5.4:
42.png


Поэтому первый байт нужно восстановить в значение 0x31:
Код:
printf "\x31" | dd of=signedAttrs bs=1 seek=0 count=1 conv=notrunc
В конце файл signedAttrs должен содержать массив cdhashes, который включает CDHash в исходной байтовой форме sha256 в кодировке base64:
43.png

Извлечённые и изменённые signedAttrs

Обратите внимание, что эти хеши совпадают с хешами в выводе codesign:
44.png

Декодированный CDHash

Теперь signedAttrs готов для хеширования, чтобы создать дайджест сообщения:
45.png

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

Пример зашифрованного дайджеста сообщения, хранящегося в подписи

Вы можете извлечь эту подпись с помощью SignatureReader:
47.png

Пример извлечённой подписи

Проверка подписи

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

1. Начните с извлечения SignatureValue из CMS-подписи:
Код:
openssl asn1parse -in cms_sign -inform DER -strparse 4522 -noout -out signature
2. Извлеките открытый ключ из ранее извлечённого сертификата подписи:
Код:
openssl x509 -inform DER -in cert_0 -pubkey -noout > pubkey.pem
3. Расшифруйте подпись с использованием открытого ключа и разберите данные в формате ASN.1:
Код:
openssl rsautl -in signature -verify -asn1parse -inkey pubkey.pem –pubin

Как видно ниже, дайджест сообщения signedAttrs, рассчитанный ранее, совпадает с дайджестом из расшифрованной подписи.
48.png

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

Упрощённая подпись CMS

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

Сводка проверки подписи кода

Шаги, которые система выполняет для проверки, что код подписан и не был изменён:

Цепочка сертификатов:
  • Проверка цепочки сертификатов, включённой в CMS Signature.
  • Проверка, не истёк ли срок действия или не отозван ли сертификат подписи.
Этот шаг устанавливает надёжность сертификата подписи.

Подпись кода:
  • Система использует открытый ключ из сертификата подписи для расшифровки подписи, которая содержит дайджест сообщения, вычисленный во время подписи кода.
  • Система вычисляет дайджест сообщения из структуры SignedAttributes, которая хранит CDHash, вычисленный во время подписи кода.
  • Эти два дайджеста сообщения сравниваются.
Этот шаг устанавливает целостность подписи кода.

Целостность кода:
  • Система вычисляет CDHash бинарного файла приложения и связанных файлов, так же, как и в процессе подписи кода.
  • Система сравнивает вычисленный CDHash с тем, который хранится в структуре SignedAttributes внутри CMS Signature.
Этот шаг устанавливает целостность приложения.

Оценка требований:
  • Система оценивает условия для запуска приложения, которые указаны в Requirements Blob.
Например, они могут указывать минимальную версию ОС или необходимые полномочия.
Если все проверки проходят успешно, система утверждает подпись кода.

Разбор подписи кода

В этом разделе вы найдете Python-код, который будет полезен для работы с подписью кода и процессом подписи кода.
50.png


Я решил не писать пользовательский парсер на Python из-за возможных изменений в структуре подписи кода. Вместо этого я напишу оболочку вокруг инструментов codesign.

Проверка подписи кода

Используйте команду codesign для проверки подписи:
Код:
codesign --verify YOUR_APP
  • В случае, если подпись целостна, вывод будет отсутствовать.
51.png

  • Команда codesign выводит информацию через канал stderr:
52.png

  • Функция-обёртка:
Код:
result = subprocess.run(["codesign", "-v", file_path], capture_output=True)
if result.stderr == b'':
    return True
else:
    return False
53.png


Информация подписи кода
Код:
codesign -d -vvvvvv YOUR_APP
  • Функция-обёртка:
Код:
result = subprocess.run(["codesign", "-d", "-vvvvvv", file_path], capture_output=True)
print(result.stderr.decode('utf-8'))
54.png


Требования

Код:
codesign -d -r - signed_ad_hoc_example
  • Функция-обёртка:
Код:
result = subprocess.run(["codesign", "-d", "-r", "-", file_path], capture_output=True)
print(result.stdout)
55.png


Полномочия

Код:
codesign -d --entitlements - YOUR_APP
codesign -d --entitlements - --xml YOUR_APP
codesign -d --entitlements - --der YOUR_APP
  • Функция-обёртка:
Код:
result = subprocess.run(["codesign", "-d", "--entitlements", "-", file_path], capture_output=True)
print(result.stdout.decode('utf-8'))
56.png


Подпись CMS

Для ясности, бинарный объект, используемый ниже, — это бинарный файл arm64, полученный после разбора универсального бинарного файла с помощью lief.MachO.parse(path).

  • Извлечение сырых байтов подписи CMS:
Код:
def extract_CMS(binary, magic_bytes):
    cs = binary.code_signature
    cs_content = bytes(cs.content)
    offset = cs_content.find(magic_bytes)
    cms_len_in_bytes = cs_content[offset+4:offset+8]
    cms_len_in_int = int.from_bytes(cms_len_in_bytes, byteorder='big')
    cms_signature = cs_content[offset+8:offset+8+cms_len_in_int]
    return cms_signature
   
# Blob магических байтов подписи CMS
magic_bytes = (0xFADE0B01).to_bytes(4, byteorder='big')
cms_signature = extract_CMS(binary, magic_bytes)
57.png


  • Вывод полноценной CMS-подписи:
Код:
from asn1crypto.cms import ContentInfo

# Загрузка CMS подписи с помощью asn1crypto
content_info = ContentInfo.load(cms_signature)
# Доступ к стурктуре SignedData
cms = content_info['content']
print(cms.debug())
58.png


  • Извлечение зашифрованной подписи:
Код:
content_info = ContentInfo.load(cms_signature)
# Доступ к структуре SignedData
signed_data = content_info['content']
# Доступ к струкутуре SignerInfo
signer_info = signed_data['signer_infos'][0]
# Извлечение подписи
signature = signer_info['signature']
print(f"0x{signature.contents.hex()}")
59.png


Сертификаты

Код:
codesign -d --extract-certificates=cert_ YOUR_APP
  • Функция-обёртка:
Код:
subprocess.run(["codesign", "-d", f"--extract-certificates={cert_name}", file_path], capture_output=True)
60.png


Извлечение публичного ключа из сертификата:
61.png


Удаление подписи

Код:
binary.remove_signature()
binary.write(new_name)
62.png


Подпись

Код:
subprocess.run(["codesign", "-s", security_identity, "-f", file_path], capture_output=True)
63.png


ЗАКЛЮЧЕНИЕ

Программы, описанные в этой статье (CrimsonUroboros, extract_cms, TrustCacheParser и SignatureReader), можно найти в репозитории Snake_Apple II. Code Signing (Змей и Яблоко. Часть 2. Подпись кода).
64.png

Модуль подписи кода в CrimsonUroboros

Следующая статья будет посвящена механизмам безопасности бинарных файлов за пределами подписей кода и обновлению CrimsonUroboros с добавлением проверки безопасности (checksec).
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх