From 14a26af3bdadd3975ad8044c3b1c6f7bbf990dba Mon Sep 17 00:00:00 2001 From: Translator Date: Wed, 1 Oct 2025 01:54:27 +0000 Subject: [PATCH] Translated ['src/macos-hardening/macos-security-and-privilege-escalation --- src/SUMMARY.md | 1 + .../README.md | 7 +- .../mach-o-entitlements-and-ipsw-indexing.md | 213 ++++++++++++++ .../universal-binaries-and-mach-o-format.md | 271 +++++++++--------- .../macos-code-signing.md | 133 ++++----- 5 files changed, 427 insertions(+), 198 deletions(-) create mode 100644 src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 27f33cff3..2062b6f9d 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -61,6 +61,7 @@ - [Deofuscation vbs (cscript.exe)](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md) - [Discord Cache Forensics](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/discord-cache-forensics.md) - [Local Cloud Storage](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md) + - [Mach O Entitlements And Ipsw Indexing](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md) - [Office file analysis](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md) - [PDF File analysis](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md) - [PNG tricks](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/png-tricks.md) diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/README.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/README.md index b73ca3a8c..3b3c0e316 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/README.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/README.md @@ -1,4 +1,4 @@ -# Специфічні трюки для програмного забезпечення та типів файлів +# Специфічні трюки для програмного забезпечення/типів файлів {{#include ../../../banners/hacktricks-training.md}} @@ -54,4 +54,9 @@ video-and-audio-file-analysis.md zips-tricks.md {{#endref}} + +{{#ref}} +mach-o-entitlements-and-ipsw-indexing.md +{{#endref}} + {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md new file mode 100644 index 000000000..774637d8d --- /dev/null +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md @@ -0,0 +1,213 @@ +# Mach-O Entitlements Extraction & IPSW Indexing + +{{#include ../../../banners/hacktricks-training.md}} + +## Огляд + +Ця сторінка описує, як програмно витягувати entitlements з Mach-O бінарів, обходячи LC_CODE_SIGNATURE та розбираючи підпис SuperBlob, а також як масштабувати це для Apple IPSW прошивок шляхом маунтування та індексації їх вмісту для судової пошукової/дифової аналізу. + +Якщо потрібне оновлення знань про формат Mach-O та підписування коду, див. також: macOS code signing та внутрішні структури SuperBlob. +- Check macOS code signing details (SuperBlob, Code Directory, special slots): [macOS Code Signing](../../../macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md) +- Check general Mach-O structures/load commands: [Universal binaries & Mach-O Format](../../../macos-hardening/macos-security-and-privilege-escalation/macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md) + + +## Entitlements in Mach-O: where they live + +Entitlements зберігаються всередині даних підпису коду, на які посилається load command LC_CODE_SIGNATURE, і розташовані в сегменті __LINKEDIT. Підпис — це CS_SuperBlob, що містить кілька blob’ів (code directory, requirements, entitlements, CMS тощо). Entitlements blob — це CS_GenericBlob, дані якого є Apple Binary Property List (bplist00), що відображає ключі entitlements у значення. + +Ключові структури (з xnu): +```c +/* mach-o/loader.h */ +struct mach_header_64 { +uint32_t magic; +cpu_type_t cputype; +cpu_subtype_t cpusubtype; +uint32_t filetype; +uint32_t ncmds; +uint32_t sizeofcmds; +uint32_t flags; +uint32_t reserved; +}; + +struct load_command { +uint32_t cmd; +uint32_t cmdsize; +}; + +/* Entitlements live behind LC_CODE_SIGNATURE (cmd=0x1d) */ +struct linkedit_data_command { +uint32_t cmd; /* LC_CODE_SIGNATURE */ +uint32_t cmdsize; /* sizeof(struct linkedit_data_command) */ +uint32_t dataoff; /* file offset of data in __LINKEDIT */ +uint32_t datasize; /* file size of data in __LINKEDIT */ +}; + +/* osfmk/kern/cs_blobs.h */ +typedef struct __SC_SuperBlob { +uint32_t magic; /* CSMAGIC_EMBEDDED_SIGNATURE = 0xfade0cc0 */ +uint32_t length; +uint32_t count; +CS_BlobIndex index[]; +} CS_SuperBlob; + +typedef struct __BlobIndex { +uint32_t type; /* e.g., CSMAGIC_EMBEDDED_ENTITLEMENTS = 0xfade7171 */ +uint32_t offset; /* offset of entry */ +} CS_BlobIndex; + +typedef struct __SC_GenericBlob { +uint32_t magic; /* same as type when standalone */ +uint32_t length; +char data[]; /* Apple Binary Plist containing entitlements */ +} CS_GenericBlob; +``` +Важливі константи: +- LC_CODE_SIGNATURE cmd = 0x1d +- CS SuperBlob magic = 0xfade0cc0 +- Entitlements blob type (CSMAGIC_EMBEDDED_ENTITLEMENTS) = 0xfade7171 +- DER entitlements may be present via special slot (e.g., -7), see the macOS Code Signing page for special slots and DER entitlements notes + +Note: Multi-arch (fat) binaries contain multiple Mach-O slices. You must pick the slice for the architecture you want to inspect and then walk its load commands. + + +## Extraction steps (generic, lossless-enough) + +1) Parse Mach-O header; iterate ncmds worth of load_command records. +2) Locate LC_CODE_SIGNATURE; read linkedit_data_command.dataoff/datasize to map the Code Signing SuperBlob placed in __LINKEDIT. +3) Validate CS_SuperBlob.magic == 0xfade0cc0; iterate count entries of CS_BlobIndex. +4) Locate index.type == 0xfade7171 (embedded entitlements). Read the pointed CS_GenericBlob and parse its data as an Apple binary plist (bplist00) to key/value entitlements. + +Implementation notes: +- Code signature structures use big-endian fields; swap byte order when parsing on little-endian hosts. +- The entitlements GenericBlob data itself is a binary plist (handled by standard plist libraries). +- Some iOS binaries may carry DER entitlements; also some stores/slots differ across platforms/versions. Cross-check both standard and DER entitlements as needed. +- For fat binaries, use the fat headers (FAT_MAGIC/FAT_MAGIC_64) to locate the correct slice and offset before walking Mach-O load commands. + + +## Minimal parsing outline (Python) + +The following is a compact outline showing the control flow to find and decode entitlements. It intentionally omits robust bounds checks and full fat binary support for brevity. +```python +import plistlib, struct + +LC_CODE_SIGNATURE = 0x1d +CSMAGIC_EMBEDDED_SIGNATURE = 0xfade0cc0 +CSMAGIC_EMBEDDED_ENTITLEMENTS = 0xfade7171 + +# all code-signing integers are big-endian per cs_blobs.h +be32 = lambda b, off: struct.unpack_from(">I", b, off)[0] + +def parse_entitlements(macho_bytes): +# assume already positioned at a single-arch Mach-O slice +magic, = struct.unpack_from(" +``` +- Переглядайте змонтовані томи, щоб знайти Mach-O файли (перевіряючи magic та/або використовуючи file/otool), а потім проаналізуйте entitlements та імпортовані frameworks. +- Зберігайте нормалізований вигляд у реляційній базі даних, щоб уникнути лінійного росту при тисячах IPSWs: +- executables, operating_system_versions, entitlements, frameworks +- many-to-many: executable↔OS version, executable↔entitlement, executable↔framework + +Приклад запиту, щоб перерахувати всі версії ОС, які містять задане ім'я executable: +```sql +SELECT osv.version AS "Versions" +FROM device d +LEFT JOIN operating_system_version osv ON osv.device_id = d.id +LEFT JOIN executable_operating_system_version eosv ON eosv.operating_system_version_id = osv.id +LEFT JOIN executable e ON e.id = eosv.executable_id +WHERE e.name = "launchd"; +``` +Примітки щодо портативності БД (якщо ви реалізуєте власний індексер): +- Використовуйте ORM/абстракцію (наприклад, SeaORM), щоб зробити код незалежним від БД (SQLite/PostgreSQL). +- SQLite вимагає AUTOINCREMENT лише для INTEGER PRIMARY KEY; якщо ви хочете i64 PK у Rust, генеруйте сутності як i32 і конвертуйте типи — SQLite внутрішньо зберігає INTEGER як 8-байтове знакове значення. + + +## Open-source tooling and references for entitlement hunting + +- Firmware mount/download: https://github.com/blacktop/ipsw +- Entitlement databases and references: +- Jonathan Levin’s entitlement DB: https://newosxbook.com/ent.php +- entdb: https://github.com/ChiChou/entdb +- Large-scale indexer (Rust, self-hosted Web UI + OpenAPI): https://github.com/synacktiv/appledb_rs +- Apple headers for structures and constants: +- loader.h (Mach-O headers, load commands) +- cs_blobs.h (SuperBlob, GenericBlob, CodeDirectory) + +For more on code signing internals (Code Directory, special slots, DER entitlements), see: [macOS Code Signing](../../../macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md) + + +## References + +- [appledb_rs: a research support tool for Apple platforms](https://www.synacktiv.com/publications/appledbrs-un-outil-daide-a-la-recherche-sur-plateformes-apple.html) +- [synacktiv/appledb_rs](https://github.com/synacktiv/appledb_rs) +- [blacktop/ipsw](https://github.com/blacktop/ipsw) +- [Jonathan Levin’s entitlement DB](https://newosxbook.com/ent.php) +- [ChiChou/entdb](https://github.com/ChiChou/entdb) +- [XNU cs_blobs.h](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/kern/cs_blobs.h) +- [XNU mach-o/loader.h](https://github.com/apple-oss-distributions/xnu/blob/main/EXTERNAL_HEADERS/mach-o/loader.h) +- [SQLite Datatypes](https://sqlite.org/datatype3.html) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md index 42ed557ac..8dcbda89d 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md @@ -1,61 +1,61 @@ -# macOS Universal binaries & Mach-O Format +# macOS Універсальні бінарні файли та формат Mach-O {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## Основна інформація -Mac OS бінарники зазвичай компілюються як **універсальні бінарники**. **Універсальний бінарник** може **підтримувати кілька архітектур в одному файлі**. +Бінарні файли Mac OS зазвичай компілюються як **універсальні бінарні файли**. **Універсальний бінарний файл** може **підтримувати кілька архітектур в одному файлі**. -Ці бінарники слідують **Mach-O структурі**, яка в основному складається з: +Ці бінарні файли слідують структурі **Mach-O**, яка в основному складається з: -- Заголовка -- Команд завантаження -- Даних +- Заголовок +- Команди завантаження +- Дані ![https://alexdremov.me/content/images/2022/10/6XLCD.gif](<../../../images/image (470).png>) ## Fat Header -Шукайте файл за допомогою: `mdfind fat.h | grep -i mach-o | grep -E "fat.h$"` +Search for the file with: `mdfind fat.h | grep -i mach-o | grep -E "fat.h$"`
#define FAT_MAGIC	0xcafebabe
 #define FAT_CIGAM	0xbebafeca	/* NXSwapLong(FAT_MAGIC) */
 
 struct fat_header {
-	uint32_t	magic;		/* FAT_MAGIC або FAT_MAGIC_64 */
-	uint32_t	nfat_arch;	/* кількість структур, що слідують */
+	uint32_t	magic;		/* FAT_MAGIC or FAT_MAGIC_64 */
+	uint32_t	nfat_arch;	/* number of structs that follow */
 };
 
 struct fat_arch {
-cpu_type_t	cputype;	/* специфікатор процесора (int) */
-cpu_subtype_t	cpusubtype;	/* специфікатор машини (int) */
-uint32_t	offset;		/* зсув файлу до цього об'єктного файлу */
-uint32_t	size;		/* розмір цього об'єктного файлу */
-uint32_t	align;		/* вирівнювання як ступінь 2 */
+cpu_type_t	cputype;	/* cpu specifier (int) */
+cpu_subtype_t	cpusubtype;	/* machine specifier (int) */
+uint32_t	offset;		/* file offset to this object file */
+uint32_t	size;		/* size of this object file */
+uint32_t	align;		/* alignment as a power of 2 */
 };
 
-Заголовок має **магічні** байти, за якими слідує **число** **архітектур**, які файл **містить** (`nfat_arch`), і кожна архітектура матиме структуру `fat_arch`. +Заголовок містить **magic**-байти, за якими йде **кількість** **архітектур**, які **містить** файл (`nfat_arch`), і для кожної архітектури існує структура `fat_arch`. -Перевірте це за допомогою: +Перевірити це можна за допомогою:
% file /bin/ls
 /bin/ls: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
-/bin/ls (для архітектури x86_64):	Mach-O 64-bit executable x86_64
-/bin/ls (для архітектури arm64e):	Mach-O 64-bit executable arm64e
+/bin/ls (for architecture x86_64):	Mach-O 64-bit executable x86_64
+/bin/ls (for architecture arm64e):	Mach-O 64-bit executable arm64e
 
 % otool -f -v /bin/ls
 Fat headers
 fat_magic FAT_MAGIC
 nfat_arch 2
-архітектура x86_64
+architecture x86_64
     cputype CPU_TYPE_X86_64
 cpusubtype CPU_SUBTYPE_X86_64_ALL
 capabilities 0x0
     offset 16384
     size 72896
     align 2^14 (16384)
-архітектура arm64e
+architecture arm64e
     cputype CPU_TYPE_ARM64
 cpusubtype CPU_SUBTYPE_ARM64E
 capabilities PTR_AUTH_VERSION USERSPACE 0
@@ -64,15 +64,15 @@ capabilities PTR_AUTH_VERSION USERSPACE 0
     align 2^14 (16384)
 
-або за допомогою інструменту [Mach-O View](https://sourceforge.net/projects/machoview/): +or using the [Mach-O View](https://sourceforge.net/projects/machoview/) tool:
-Як ви, напевно, думаєте, зазвичай універсальний бінарник, скомпільований для 2 архітектур, **подвоює розмір** одного, скомпільованого лише для 1 архітектури. +Як ви, мабуть, здогадуєтеся, зазвичай універсальний бінарний файл, скомпільований для 2 архітектур, **подвоює розмір** порівняно з тим, що скомпільований лише для однієї архітектури. ## **Mach-O Header** -Заголовок містить основну інформацію про файл, таку як магічні байти для його ідентифікації як Mach-O файл та інформацію про цільову архітектуру. Ви можете знайти його за допомогою: `mdfind loader.h | grep -i mach-o | grep -E "loader.h$"` +Заголовок містить базову інформацію про файл, таку як magic-байти для ідентифікації його як Mach-O файлу та інформацію про цільову архітектуру. Ви можете знайти його в: `mdfind loader.h | grep -i mach-o | grep -E "loader.h$"` ```c #define MH_MAGIC 0xfeedface /* the mach magic number */ #define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */ @@ -99,19 +99,19 @@ uint32_t flags; /* flags */ uint32_t reserved; /* reserved */ }; ``` -### Mach-O File Types +### Типи файлів Mach-O -Є різні типи файлів, ви можете знайти їх визначення в [**джерельному коді, наприклад, тут**](https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h). Найважливіші з них: +Існують різні типи файлів, їх можна знайти визначеними в [**source code for example here**](https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h). Найважливіші з них: -- `MH_OBJECT`: Переміщуваний об'єктний файл (проміжні продукти компіляції, ще не виконувані). +- `MH_OBJECT`: Relocatable object file (intermediate products of compilation, not executables yet). - `MH_EXECUTE`: Виконувані файли. -- `MH_FVMLIB`: Фіксований файл бібліотеки VM. -- `MH_CORE`: Знімки коду +- `MH_FVMLIB`: Файл бібліотеки Fixed VM. +- `MH_CORE`: Дампи коду - `MH_PRELOAD`: Попередньо завантажений виконуваний файл (більше не підтримується в XNU) - `MH_DYLIB`: Динамічні бібліотеки -- `MH_DYLINKER`: Динамічний зв'язувач -- `MH_BUNDLE`: "Файли плагінів". Генеруються за допомогою -bundle в gcc і явно завантажуються за допомогою `NSBundle` або `dlopen`. -- `MH_DYSM`: Супутній файл `.dSym` (файл з символами для налагодження). +- `MH_DYLINKER`: Динамічний лінкер +- `MH_BUNDLE`: "Plugin files". Генеруються за допомогою -bundle в gcc і явно завантажуються через `NSBundle` або `dlopen`. +- `MH_DYSM`: Супутній `.dSym` файл (файл із символами для налагодження). - `MH_KEXT_BUNDLE`: Розширення ядра. ```bash # Checking the mac header of a binary @@ -124,71 +124,71 @@ MH_MAGIC_64 ARM64 E USR00 EXECUTE 19 1728 NOUNDEFS DY
-## **Mach-O Прапори** +## **Mach-O прапори** -Джерельний код також визначає кілька прапорів, корисних для завантаження бібліотек: +Исходний код також визначає кілька прапорів, корисних для завантаження бібліотек: -- `MH_NOUNDEFS`: Немає невизначених посилань (повністю зв'язано) -- `MH_DYLDLINK`: Зв'язування Dyld +- `MH_NOUNDEFS`: Немає невизначених посилань (повністю зв'язаний) +- `MH_DYLDLINK`: Dyld лінкування - `MH_PREBOUND`: Динамічні посилання попередньо зв'язані. -- `MH_SPLIT_SEGS`: Файл розділяє сегменти r/o та r/w. -- `MH_WEAK_DEFINES`: Бінарний файл має слабко визначені символи -- `MH_BINDS_TO_WEAK`: Бінарний файл використовує слабкі символи -- `MH_ALLOW_STACK_EXECUTION`: Зробити стек виконуваним -- `MH_NO_REEXPORTED_DYLIBS`: Бібліотека не має команд LC_REEXPORT -- `MH_PIE`: Виконуваний файл, незалежний від позиції -- `MH_HAS_TLV_DESCRIPTORS`: Є секція з локальними змінними потоку -- `MH_NO_HEAP_EXECUTION`: Немає виконання для сторінок купи/даних -- `MH_HAS_OBJC`: Бінарний файл має секції oBject-C -- `MH_SIM_SUPPORT`: Підтримка емулятора +- `MH_SPLIT_SEGS`: Файл розділяє r/o та r/w сегменти. +- `MH_WEAK_DEFINES`: Бінарний файл має слабо визначені символи +- `MH_BINDS_TO_WEAK`: Бінарний файл використовує weak символи +- `MH_ALLOW_STACK_EXECUTION`: Дозволяє виконання коду на стеку +- `MH_NO_REEXPORTED_DYLIBS`: Бібліотека без команд LC_REEXPORT +- `MH_PIE`: Position Independent Executable +- `MH_HAS_TLV_DESCRIPTORS`: Є секція з thread-local змінними +- `MH_NO_HEAP_EXECUTION`: Заборонено виконання на сторінках heap/даних +- `MH_HAS_OBJC`: Бінарний файл містить секції Objective-C +- `MH_SIM_SUPPORT`: Підтримка симулятора - `MH_DYLIB_IN_CACHE`: Використовується для dylibs/frameworks у кеші спільних бібліотек. ## **Команди завантаження Mach-O** -**Розташування файлу в пам'яті** вказується тут, детально описуючи **місцезнаходження таблиці символів**, контекст основного потоку на початку виконання та необхідні **спільні бібліотеки**. Інструкції надаються динамічному завантажувачу **(dyld)** щодо процесу завантаження бінарного файлу в пам'ять. +Тут визначається розташування файлу в пам'яті, з детальним описом розташування таблиці символів, контексту головного потоку на початку виконання та необхідних спільних бібліотек. Надаються інструкції динамічному завантажувачу (dyld) щодо процесу завантаження бінарного файлу в пам'ять. -Використовується структура **load_command**, визначена в згаданому **`loader.h`**: +Використовується структура `load_command`, визначена у згаданому `loader.h`: ```objectivec struct load_command { uint32_t cmd; /* type of load command */ uint32_t cmdsize; /* total size of command in bytes */ }; ``` -Є близько **50 різних типів команд завантаження**, які система обробляє по-різному. Найпоширеніші з них: `LC_SEGMENT_64`, `LC_LOAD_DYLINKER`, `LC_MAIN`, `LC_LOAD_DYLIB` та `LC_CODE_SIGNATURE`. +There are about **50 different types of load commands** that the system handles differently. The most common ones are: `LC_SEGMENT_64`, `LC_LOAD_DYLINKER`, `LC_MAIN`, `LC_LOAD_DYLIB`, and `LC_CODE_SIGNATURE`. ### **LC_SEGMENT/LC_SEGMENT_64** > [!TIP] -> В основному, цей тип команди завантаження визначає **як завантажити \_\_TEXT** (виконуваний код) **та \_\_DATA** (дані для процесу) **сегменти** відповідно до **зсувів, вказаних у секції даних** під час виконання бінарного файлу. +> По суті, цей тип Load Command визначає, **як завантажувати сегменти \_\_TEXT** (виконуваний код) **та \_\_DATA** (дані процесу) **відповідно до зсувів, вказаних у секції даних**, коли бінарник виконується. -Ці команди **визначають сегменти**, які **відображаються** у **віртуальному адресному просторі** процесу під час його виконання. +Ці команди **визначають сегменти**, які **відображаються** в **віртуальній пам'яті процесу** під час його виконання. -Існують **різні типи** сегментів, такі як сегмент **\_\_TEXT**, який містить виконуваний код програми, та сегмент **\_\_DATA**, який містить дані, що використовуються процесом. Ці **сегменти розташовані в секції даних** файлу Mach-O. +Існують **різні типи** сегментів, наприклад сегмент **\_\_TEXT**, який містить виконуваний код програми, та сегмент **\_\_DATA**, який містить дані, що використовуються процесом. Ці **сегменти знаходяться в секції даних** файлу Mach-O. -**Кожен сегмент** може бути додатково **поділений** на кілька **секцій**. **Структура команди завантаження** містить **інформацію** про **ці секції** в межах відповідного сегмента. +**Кожен сегмент** може бути додатково **поділений** на кілька **секцій**. **Структура load command** містить **інформацію** про **ці секції** в межах відповідного сегменту. -У заголовку спочатку ви знайдете **заголовок сегмента**: +У заголовку спочатку знаходиться **segment header**: -
struct segment_command_64 { /* для 64-бітних архітектур */
+
struct segment_command_64 { /* for 64-bit architectures */
 uint32_t	cmd;		/* LC_SEGMENT_64 */
-uint32_t	cmdsize;	/* включає sizeof section_64 structs */
-char		segname[16];	/* ім'я сегмента */
-uint64_t	vmaddr;		/* адреса пам'яті цього сегмента */
-uint64_t	vmsize;		/* розмір пам'яті цього сегмента */
-uint64_t	fileoff;	/* зсув файлу цього сегмента */
-uint64_t	filesize;	/* кількість для відображення з файлу */
-int32_t		maxprot;	/* максимальний захист VM */
-int32_t		initprot;	/* початковий захист VM */
-	uint32_t	nsects;		/* кількість секцій у сегменті */
-	uint32_t	flags;		/* прапори */
+uint32_t	cmdsize;	/* includes sizeof section_64 structs */
+char		segname[16];	/* segment name */
+uint64_t	vmaddr;		/* memory address of this segment */
+uint64_t	vmsize;		/* memory size of this segment */
+uint64_t	fileoff;	/* file offset of this segment */
+uint64_t	filesize;	/* amount to map from the file */
+int32_t		maxprot;	/* maximum VM protection */
+int32_t		initprot;	/* initial VM protection */
+	uint32_t	nsects;		/* number of sections in segment */
+	uint32_t	flags;		/* flags */
 };
 
-Приклад заголовка сегмента: +Example of segment header:
-Цей заголовок визначає **кількість секцій, заголовки яких з'являються після** нього: +Цей заголовок визначає **кількість секцій**, заголовки яких з'являються після нього: ```c struct section_64 { /* for 64-bit architectures */ char sectname[16]; /* name of this section */ @@ -205,62 +205,62 @@ uint32_t reserved2; /* reserved (for count or sizeof) */ uint32_t reserved3; /* reserved */ }; ``` -Приклад **заголовка секції**: +Приклад **section header**:
-Якщо ви **додасте** **зсув секції** (0x37DC) + **зсув**, де **архітектура починається**, в цьому випадку `0x18000` --> `0x37DC + 0x18000 = 0x1B7DC` +Якщо ви **додасте** **section offset** (0x37DC) до **offset**, де **arch starts** (у цьому випадку `0x18000`) --> `0x37DC + 0x18000 = 0x1B7DC`
-Також можливо отримати **інформацію про заголовки** з **командного рядка** за допомогою: +Також можна отримати **headers information** з **command line** за допомогою: ```bash otool -lv /bin/ls ``` -Загальні сегменти, завантажені цим cmd: +Common segments loaded by this cmd: -- **`__PAGEZERO`:** Він інструктує ядро **відобразити** **адресу нуль** так, щоб вона **не могла бути прочитана, записана або виконана**. Змінні maxprot і minprot у структурі встановлені в нуль, щоб вказати, що **немає прав на читання-запис-виконання на цій сторінці**. -- Це виділення важливе для **зменшення вразливостей, пов'язаних з розіменуванням нульових вказівників**. Це пов'язано з тим, що XNU забезпечує жорстку нульову сторінку, яка гарантує, що перша сторінка (тільки перша) пам'яті недоступна (за винятком i386). Бінарний файл може виконати ці вимоги, створивши невелику \_\_PAGEZERO (використовуючи `-pagezero_size`), щоб покрити перші 4k, а решта 32-бітної пам'яті була доступна як в режимі користувача, так і в режимі ядра. -- **`__TEXT`**: Містить **виконуваний** **код** з **правами на читання** та **виконання** (без запису)**.** Загальні секції цього сегмента: +- **`__PAGEZERO`:** Він інструктує ядро **відобразити** адресу нуль так, щоб її **не можна було читати, записувати або виконувати**. Змінні maxprot і minprot у структурі встановлені в нуль, щоб вказати, що на цій сторінці **немає прав на читання-запис-виконання**. +- Це виділення важливе для **пом’якшення вразливостей через dereference NULL pointer**. Це тому, що XNU накладає жорстку сторінку нуля, яка забезпечує, що перша сторінка (тільки перша) пам’яті недоступна (за винятком i386). Бінарник може виконати цю вимогу, створивши невеликий \_\_PAGEZERO (використовуючи `-pagezero_size`) щоб покрити перші 4k і зробивши решту 32-бітної пам’яті доступною як у користувацькому, так і в ядровому режимі. +- **`__TEXT`**: Містить **виконуваний** **код** з правами **читання** та **виконання** (без запису)**.** Звичайні секції цього сегмента: - `__text`: Скомпільований бінарний код - `__const`: Константні дані (тільки для читання) -- `__[c/u/os_log]string`: Константи рядків C, Unicode або os logs -- `__stubs` та `__stubs_helper`: Бере участь у процесі завантаження динамічної бібліотеки -- `__unwind_info`: Дані про розгортання стеку. -- Зверніть увагу, що весь цей вміст підписаний, але також позначений як виконуваний (створюючи більше можливостей для експлуатації секцій, які не обов'язково потребують цього привілею, як секції, присвячені рядкам). -- **`__DATA`**: Містить дані, які є **читабельними** та **записуваними** (без виконуваних)**.** -- `__got:` Глобальна таблиця зсувів -- `__nl_symbol_ptr`: Неледачний (прив'язка при завантаженні) вказівник символу -- `__la_symbol_ptr`: Ледачий (прив'язка при використанні) вказівник символу -- `__const`: Має бути даними тільки для читання (насправді не так) -- `__cfstring`: Рядки CoreFoundation +- `__[c/u/os_log]string`: C, Unicode або os log рядкові константи +- `__stubs` і `__stubs_helper`: Залучені під час динамічного завантаження бібліотек +- `__unwind_info`: Дані для розгортання стеку (stack unwind) +- Зауважте, що весь цей вміст підписаний, але також позначений як виконуваний (що створює більше опцій для експлуатації секцій, які фактично не потребують цього привілею, наприклад секції, присвячені рядкам). +- **`__DATA`**: Містить дані, які **можна читати** і **записувати** (без виконання)**.** +- `__got:` Global Offset Table +- `__nl_symbol_ptr`: Non lazy (bind at load) symbol pointer +- `__la_symbol_ptr`: Lazy (bind on use) symbol pointer +- `__const`: Повинні бути даними лише для читання (насправді ні) +- `__cfstring`: CoreFoundation рядки - `__data`: Глобальні змінні (які були ініціалізовані) - `__bss`: Статичні змінні (які не були ініціалізовані) -- `__objc_*` (\_\_objc_classlist, \_\_objc_protolist тощо): Інформація, що використовується середовищем виконання Objective-C -- **`__DATA_CONST`**: \_\_DATA.\_\_const не гарантує, що є константним (права на запис), так само як і інші вказівники та GOT. Цей розділ робить `__const`, деякі ініціалізатори та таблицю GOT (після розв'язання) **тільки для читання** за допомогою `mprotect`. -- **`__LINKEDIT`**: Містить інформацію для компоновщика (dyld), таку як символи, рядки та записи таблиці переміщення. Це загальний контейнер для вмісту, який не знаходиться в `__TEXT` або `__DATA`, а його вміст описується в інших командах завантаження. -- Інформація dyld: Переміщення, неледачні/ледачі/слабкі коди прив'язки та інформація про експорт -- Початок функцій: Таблиця початкових адрес функцій -- Дані в коді: Острівці даних у \_\_text -- Таблиця символів: Символи в бінарному файлі -- Таблиця непрямих символів: Вказівники/стаб символів -- Таблиця рядків -- Код підпису -- **`__OBJC`**: Містить інформацію, що використовується середовищем виконання Objective-C. Хоча ця інформація також може бути знайдена в сегменті \_\_DATA, в різних секціях \_\_objc\_\*. -- **`__RESTRICT`**: Сегмент без вмісту з єдиною секцією, що називається **`__restrict`** (також порожня), яка забезпечує, що при виконанні бінарного файлу він ігноруватиме змінні середовища DYLD. +- `__objc_*` (\_\_objc_classlist, \_\_objc_protolist, etc): Інформація, що використовується рантаймом Objective-C +- **`__DATA_CONST`**: \_\_DATA.\_\_const не гарантується як константа (має права на запис), так само як і інші покажчики та GOT. Цей сегмент робить `__const`, деякі ініціалізатори та таблицю GOT (після її розв’язання) **тільки для читання** за допомогою `mprotect`. +- **`__LINKEDIT`**: Містить інформацію для лінкера (dyld), таку як таблиці символів, рядків та записів релокацій. Це загальний контейнер для вмісту, який не входить до `__TEXT` або `__DATA`, і його вміст описується в інших load командах. +- dyld information: Rebase, опкоди non-lazy/lazy/weak binding та інформація про export +- Початки функцій: Таблиця адрес початку функцій +- Data In Code: Острови даних у \_\_text +- Таблиця символів: Символи у бінарному файлі +- Indirect Symbol Table: Показникові/заглушкові символи +- String Table +- Code Signature +- **`__OBJC`**: Містить інформацію, яку використовує рантайм Objective-C. Хоча ця інформація також може бути знайдена в сегменті \_\_DATA, у різних секціях \_\_objc\_\*. +- **`__RESTRICT`**: Сегмент без вмісту з єдиною секцією під назвою **`__restrict`** (також порожньою), який гарантує, що при виконанні бінарника він ігноруватиме DYLD змінні середовища. -Як було видно в коді, **сегменти також підтримують прапорці** (хоча вони не використовуються дуже часто): +As it was possible to see in the code, **segments also support flags** (although they aren't used very much): - `SG_HIGHVM`: Тільки ядро (не використовується) - `SG_FVMLIB`: Не використовується -- `SG_NORELOC`: Сегмент не має переміщення -- `SG_PROTECTED_VERSION_1`: Шифрування. Використовується, наприклад, Finder для шифрування тексту сегмента `__TEXT`. +- `SG_NORELOC`: Сегмент не має релокацій +- `SG_PROTECTED_VERSION_1`: Шифрування. Використовується, наприклад, Finder для шифрування текстового сегмента `__TEXT`. ### **`LC_UNIXTHREAD/LC_MAIN`** -**`LC_MAIN`** містить точку входу в **атрибуті entryoff.** Під час завантаження **dyld** просто **додає** це значення до (в пам'яті) **бази бінарного файлу**, а потім **переходить** до цієї інструкції, щоб почати виконання коду бінарного файлу. +**`LC_MAIN`** містить точку входу в атрибуті **entryoff.** Під час завантаження **`dyld`** просто **додає** це значення до (в пам’яті) **бази бінарника**, після чого **переходить** до цієї інструкції, щоб розпочати виконання коду бінарника. -**`LC_UNIXTHREAD`** містить значення, які повинні мати регістри при запуску основного потоку. Це вже застаріло, але **`dyld`** все ще використовує це. Можна побачити значення регістрів, встановлені цим: +**`LC_UNIXTHREAD`** містить значення, які повинні бути встановлені у регістрах при запуску головного потоку. Воно вже застаріле, але **`dyld`** все ще його використовує. Можна побачити значення регістрів, встановлені цим, за допомогою: ```bash otool -l /usr/lib/dyld [...] @@ -286,34 +286,39 @@ cpsr 0x00000000 ``` ### **`LC_CODE_SIGNATURE`** -Містить інформацію про **код підпису файлу Macho-O**. Він містить лише **зсув**, який **вказує** на **блоб підпису**. Це зазвичай знаходиться в самому кінці файлу.\ -Однак ви можете знайти деяку інформацію про цей розділ у [**цьому блозі**](https://davedelong.com/blog/2018/01/10/reading-your-own-entitlements/) та у [**цих гістах**](https://gist.github.com/carlospolop/ef26f8eb9fafd4bc22e69e1a32b81da4). +{{#ref}} +../../../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md +{{#endref}} + + +Містить інформацію про **code signature файлу Mach-O**. Воно містить лише **offset**, який **вказує** на **signature blob**. Зазвичай це розташовано в самому кінці файлу.\ +However, you can find some information about this section in [**this blog post**](https://davedelong.com/blog/2018/01/10/reading-your-own-entitlements/) and this [**gists**](https://gist.github.com/carlospolop/ef26f8eb9fafd4bc22e69e1a32b81da4). ### **`LC_ENCRYPTION_INFO[_64]`** -Підтримка шифрування бінарних файлів. Однак, звичайно, якщо зловмисник зможе скомпрометувати процес, він зможе скинути пам'ять у незашифрованому вигляді. +Підтримка шифрування бінарників. Проте, якщо зловмисникові вдасться скомпрометувати процес, він зможе дампнути пам'ять у незашифрованому вигляді. ### **`LC_LOAD_DYLINKER`** -Містить **шлях до виконуваного файлу динамічного зв'язувача**, який відображає спільні бібліотеки в адресному просторі процесу. **Значення завжди встановлюється на `/usr/lib/dyld`**. Важливо зазначити, що в macOS, відображення dylib відбувається в **режимі користувача**, а не в режимі ядра. +Містить **шлях до виконуваного файлу dynamic linker**, який відображає shared libraries в адресний простір процесу. The **value is always set to `/usr/lib/dyld`**. Важливо зазначити, що в macOS відображення dylib відбувається в **user mode**, а не в kernel mode. ### **`LC_IDENT`** -Застарілий, але коли налаштований для генерації дампів при паніці, створюється дамп ядра Mach-O, і версія ядра встановлюється в команді `LC_IDENT`. +Застарілий, але коли налаштовано генерацію дампів при panic, створюється Mach-O core dump і версія ядра встановлюється в команді `LC_IDENT`. ### **`LC_UUID`** -Випадковий UUID. Він корисний для чого завгодно, але XNU кешує його разом з рештою інформації про процес. Його можна використовувати в звітах про збої. +Випадковий UUID. Прямого широкого застосування немає, але XNU кешує його разом з рештою інформації про процес. Може використовуватись у crash reports. ### **`LC_DYLD_ENVIRONMENT`** -Дозволяє вказати змінні середовища для dyld перед виконанням процесу. Це може бути дуже небезпечно, оскільки може дозволити виконувати довільний код всередині процесу, тому ця команда завантаження використовується лише в dyld, зібраному з `#define SUPPORT_LC_DYLD_ENVIRONMENT`, і додатково обмежує обробку лише змінними у формі `DYLD_..._PATH`, що вказують шляхи завантаження. +Дозволяє вказати змінні оточення для dyld перед запуском процесу. Це може бути досить небезпечно, оскільки дозволяє виконати довільний код всередині процесу, тому ця load command використовується лише в збірках dyld з `#define SUPPORT_LC_DYLD_ENVIRONMENT` і додатково обмежує обробку лише змінними у формі `DYLD_..._PATH`, які задають шляхи завантаження. ### **`LC_LOAD_DYLIB`** -Ця команда завантаження описує залежність **динамічної** **бібліотеки**, яка **інструктує** **завантажувач** (dyld) **завантажити та зв'язати цю бібліотеку**. Існує команда завантаження `LC_LOAD_DYLIB` **для кожної бібліотеки**, яка потрібна бінарному файлу Mach-O. +Ця load command описує залежність від **dynamic** **library**, яка **наказує** **loader** (dyld) **завантажити та зв'язати цю бібліотеку**. Існує команда `LC_LOAD_DYLIB` **для кожної бібліотеки**, яку вимагає Mach-O бінар. -- Ця команда завантаження є структурою типу **`dylib_command`** (яка містить структуру dylib, що описує фактичну залежну динамічну бібліотеку): +- Ця load command — структура типу **`dylib_command`** (яка містить struct dylib, що описує власне залежну dynamic library): ```objectivec struct dylib_command { uint32_t cmd; /* LC_LOAD_{,WEAK_}DYLIB */ @@ -330,7 +335,7 @@ uint32_t compatibility_version; /* library's compatibility vers number*/ ``` ![](<../../../images/image (486).png>) -Ви також можете отримати цю інформацію з командного рядка за допомогою: +Ви також можете отримати цю інформацію з cli за допомогою: ```bash otool -L /bin/ls /bin/ls: @@ -338,32 +343,32 @@ otool -L /bin/ls /usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0) ``` -Деякі потенційні бібліотеки, пов'язані з шкідливим ПЗ: +Деякі потенційні бібліотеки, пов'язані з malware: - **DiskArbitration**: Моніторинг USB-накопичувачів - **AVFoundation:** Захоплення аудіо та відео -- **CoreWLAN**: Сканування Wifi. - -> [!NOTE] -> Mach-O бінарний файл може містити один або **більше** **конструкторів**, які будуть **виконані** **перед** адресою, вказаною в **LC_MAIN**.\ -> Зсуви будь-яких конструкторів зберігаються в секції **\_\_mod_init_func** сегмента **\_\_DATA_CONST**. - -## **Дані Mach-O** - -В основі файлу лежить регіон даних, який складається з кількох сегментів, як визначено в регіоні команд завантаження. **Різноманітні секції даних можуть бути розміщені в кожному сегменті**, при цьому кожна секція **містить код або дані**, специфічні для певного типу. +- **CoreWLAN**: Сканування Wi‑Fi > [!TIP] -> Дані в основному є частиною, що містить всю **інформацію**, яка завантажується командами завантаження **LC_SEGMENTS_64** +> A Mach-O binary can contain one or **more** **constructors**, that will be **executed** **before** the address specified in **LC_MAIN**.\ +> The offsets of any constructors are held in the **\_\_mod_init_func** section of the **\_\_DATA_CONST** segment. + +## **Mach-O Дані** + +У центрі файлу знаходиться область даних, яка складається з кількох сегментів, як визначено в області load-commands. **У кожному сегменті може міститися різноманіття секцій даних**, причому кожна секція **містить код або дані**, специфічні для певного типу. + +> [!TIP] +> The data is basically the part containing all the **information** that is loaded by the load commands **LC_SEGMENTS_64** ![https://www.oreilly.com/api/v2/epubs/9781785883378/files/graphics/B05055_02_38.jpg](<../../../images/image (507) (3).png>) Це включає: -- **Таблиця функцій:** Яка містить інформацію про функції програми. -- **Таблиця символів**: Яка містить інформацію про зовнішні функції, що використовуються бінарним файлом -- Вона також може містити внутрішні функції, імена змінних та інше. +- **Function table:** Яка містить інформацію про функції програми. +- **Symbol table**: Яка містить інформацію про зовнішні функції, що використовуються бінарним файлом +- Також може містити імена внутрішніх функцій, змінних та інше. -Щоб перевірити це, ви можете використовувати інструмент [**Mach-O View**](https://sourceforge.net/projects/machoview/): +Щоб перевірити це, ви можете використати інструмент [**Mach-O View**](https://sourceforge.net/projects/machoview/):
@@ -371,20 +376,20 @@ otool -L /bin/ls ```bash size -m /bin/ls ``` -## Objetive-C Загальні Розділи +## Objetive-C Common Sections -В `__TEXT` сегменті (r-x): +У `__TEXT` сегменті (r-x): - `__objc_classname`: Імена класів (рядки) - `__objc_methname`: Імена методів (рядки) - `__objc_methtype`: Типи методів (рядки) -В `__DATA` сегменті (rw-): +У `__DATA` сегменті (rw-): -- `__objc_classlist`: Вказівники на всі класи Objective-C -- `__objc_nlclslist`: Вказівники на не-ліниві класи Objective-C -- `__objc_catlist`: Вказівник на категорії -- `__objc_nlcatlist`: Вказівник на не-ліниві категорії +- `__objc_classlist`: Вказівники на всі Objetive-C класи +- `__objc_nlclslist`: Вказівники на Non-Lazy Objective-C класи +- `__objc_catlist`: Вказівник на Categories +- `__objc_nlcatlist`: Вказівник на Non-Lazy Categories - `__objc_protolist`: Список протоколів - `__objc_const`: Константні дані - `__objc_imageinfo`, `__objc_selrefs`, `objc__protorefs`... diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md index 4278e0516..f69131e0c 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md @@ -2,14 +2,19 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## Базова інформація -Mach-o бінарники містять команду завантаження під назвою **`LC_CODE_SIGNATURE`**, яка вказує на **зсув** та **розмір** підписів всередині бінарника. Насправді, використовуючи графічний інструмент MachOView, можна знайти в кінці бінарника розділ під назвою **Code Signature** з цією інформацією: +{{#ref}} +../../../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md +{{#endref}} + + +Mach-o бінарні файли містять load command під назвою **`LC_CODE_SIGNATURE`**, який вказує **offset** і **size** підписів всередині бінарного файлу. Насправді, використовуючи GUI-інструмент MachOView, можна знайти в кінці бінарного файлу розділ під назвою **Code Signature** з цією інформацією:
-Магічний заголовок підпису коду - **`0xFADE0CC0`**. Потім ви отримуєте інформацію, таку як довжина та кількість блобів суперBlob, які їх містять.\ -Цю інформацію можна знайти в [джерельному коді тут](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L276): +Магічний заголовок Code Signature — **`0xFADE0CC0`**. Далі міститься інформація, така як довжина та кількість blobs суперBlob, який їх містить.\ +It's possible to find this information in the [source code here](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L276): ```c /* * Structure of an embedded-signature SuperBlob @@ -38,14 +43,14 @@ char data[]; } CS_GenericBlob __attribute__ ((aligned(1))); ``` -Звичайні об'єкти, що містяться, це Директорія Коду, Вимоги та Права, а також Синтаксис Криптографічного Повідомлення (CMS).\ -Крім того, зверніть увагу, як дані, закодовані в об'єктах, закодовані в **Big Endian.** +Типові blobs включають Code Directory, Requirements та Entitlements, а також Cryptographic Message Syntax (CMS).\ +Зверніть увагу, що дані, закодовані в blobs, записані у **Big Endian.** -Крім того, підписи можуть бути відокремлені від бінарних файлів і зберігатися в `/var/db/DetachedSignatures` (використовується iOS). +Крім того, підписи можуть бути відокремлені від бінарних файлів і збережені в `/var/db/DetachedSignatures` (використовується iOS). -## Об'єкт Директорії Коду +## Code Directory Blob -Можна знайти декларацію [Об'єкта Директорії Коду в коді](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L104): +It's possible to find the declaration of the [Code Directory Blob in the code](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L104): ```c typedef struct __CodeDirectory { uint32_t magic; /* magic number (CSMAGIC_CODEDIRECTORY) */ @@ -101,12 +106,12 @@ char end_withLinkage[0]; } CS_CodeDirectory __attribute__ ((aligned(1))); ``` -Зверніть увагу, що існують різні версії цієї структури, де старі можуть містити менше інформації. +Note that there are different versions of this struct where old ones might contain less information. -## Сторінки підпису коду +## Signing Code Pages -Хешування повного бінарного файлу було б неефективним і навіть марним, якщо він завантажений в пам'ять лише частково. Тому підпис коду насправді є хешем хешів, де кожна бінарна сторінка хешується окремо.\ -Насправді, у попередньому коді **Code Directory** ви можете побачити, що **розмір сторінки вказано** в одному з його полів. Більше того, якщо розмір бінарного файлу не є кратним розміру сторінки, поле **CodeLimit** вказує, де закінчується підпис. +Хешування всього binary було б неефективним і навіть марним, якщо він завантажується в memory лише частково. Тому code signature фактично є hash of hashes, де кожна binary page хешується окремо.\ +Насправді, у попередньому **Code Directory** коді видно, що **page size is specified** в одному з його полів. Більше того, якщо розмір binary не є кратним розміру сторінки, поле **CodeLimit** вказує, де знаходиться кінець signature. ```bash # Get all hashes of /bin/ps codesign -d -vvvvvv /bin/ps @@ -144,25 +149,25 @@ openssl sha256 /tmp/*.page.* ``` ## Entitlements Blob -Зверніть увагу, що програми можуть також містити **entitlement blob**, де визначені всі права. Більше того, деякі бінарні файли iOS можуть мати свої права, специфічні для спеціального слота -7 (замість спеціального слота -5 для прав). +Note that applications might also contain an **entitlement blob** where all the entitlements are defined. Moreover, some iOS binaries might have their entitlements specific in the special slot -7 (instead of in the -5 entitlements special slot). -## Special Slots +## Спеціальні слоти -MacOS програми не мають всього необхідного для виконання всередині бінарного файлу, але також використовують **зовнішні ресурси** (зазвичай всередині **bundle** програми). Тому в бінарному файлі є кілька слотів, які міститимуть хеші деяких цікавих зовнішніх ресурсів, щоб перевірити, чи не були вони змінені. +MacOS applications doesn't have everything they need to execute inside the binary but they also use **external resources** (usually inside the applications **bundle**). Therefore, there are some slots inside the binary who will be containing the hashes of some interesting external resources to check they weren't modified. -Насправді, в структурах Code Directory можна побачити параметр **`nSpecialSlots`**, який вказує на кількість спеціальних слотів. Спеціального слота 0 немає, а найпоширеніші (від -1 до -6) це: +Actually, it's possible to see in the Code Directory structs a parameter called **`nSpecialSlots`** indicating the number of the special slots. The there isn't a special slot 0 and the most common ones (from -1 to -6 are): -- Хеш `info.plist` (або той, що всередині `__TEXT.__info__plist`). -- Хеш вимог -- Хеш каталогу ресурсів (хеш файлу `_CodeSignature/CodeResources` всередині bundle). -- Специфічний для програми (не використовується) -- Хеш прав -- Тільки DMG підписи коду +- Хеш `info.plist` (or the one inside `__TEXT.__info__plist`). +- Хеш Requirements +- Хеш Resource Directory (хеш файлу `_CodeSignature/CodeResources` inside the bundle). +- Application specific (unused) +- Хеш entitlements +- DMG code signatures only - DER Entitlements ## Code Signing Flags -Кожен процес має пов'язану бітову маску, відому як `status`, яка ініціюється ядром, і деякі з них можуть бути переозначені **підписом коду**. Ці прапори, які можуть бути включені в підпис коду, [визначені в коді](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L36): +Every process has related a bitmask known as the `status` which is started by the kernel and some of them can be overridden by the **code signature**. These flags that can be included in the code signing are [defined in the code](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L36): ```c /* code signing attributes of a process */ #define CS_VALID 0x00000001 /* dynamically valid */ @@ -207,15 +212,15 @@ CS_RESTRICT | CS_ENFORCEMENT | CS_REQUIRE_LV | CS_RUNTIME | CS_LINKER_SIGNED) #define CS_ENTITLEMENT_FLAGS (CS_GET_TASK_ALLOW | CS_INSTALLER | CS_DATAVAULT_CONTROLLER | CS_NVRAM_UNRESTRICTED) ``` -Зверніть увагу, що функція [**exec_mach_imgact**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_exec.c#L1420) також може динамічно додавати прапори `CS_EXEC_*` під час запуску виконання. +Зауважте, що функція [**exec_mach_imgact**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_exec.c#L1420) також може динамічно додавати прапори `CS_EXEC_*` під час початку виконання. -## Вимоги до підпису коду +## Вимоги підпису коду -Кожен додаток зберігає деякі **вимоги**, які він повинен **виконати**, щоб мати можливість виконуватися. Якщо **вимоги додатка не виконуються**, він не буде виконаний (оскільки, ймовірно, був змінений). +Кожен додаток зберігає деякі **вимоги**, які він повинен **задовольнити**, щоб його можна було виконати. Якщо **вимоги**, що містяться в додатку, не виконуються додатком, він не буде виконаний (оскільки, ймовірно, був змінений). -Вимоги бінарного файлу використовують **спеціальну граматику**, яка є потоком **виразів** і кодуються як блоби, використовуючи `0xfade0c00` як магічне число, чий **хеш зберігається в спеціальному кодовому слоті**. +Вимоги бінарного файлу використовують **спеціальну граматику**, яка є потоком **виразів**, і кодуються як blobs з використанням `0xfade0c00` як магічного числа, хеш якого **зберігається в спеціальному слоті коду**. -Вимоги бінарного файлу можна побачити, запустивши: +Вимоги бінарного файлу можна переглянути, виконавши: ```bash codesign -d -r- /bin/ls Executable=/bin/ls @@ -225,10 +230,10 @@ codesign -d -r- /Applications/Signal.app/ Executable=/Applications/Signal.app/Contents/MacOS/Signal designated => identifier "org.whispersystems.signal-desktop" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = U68MSDN6DR ``` -> [!NOTE] -> Зверніть увагу, як ці підписи можуть перевіряти такі речі, як інформація про сертифікацію, TeamID, ID, права доступу та багато інших даних. +> [!TIP] +> Зверніть увагу, що ці підписи можуть перевіряти такі речі, як інформація про сертифікацію, TeamID, IDs, entitlements та багато інших даних. -Більше того, можливо згенерувати деякі скомпільовані вимоги, використовуючи інструмент `csreq`: +Крім того, можна згенерувати деякі скомпільовані вимоги за допомогою інструменту `csreq`: ```bash # Generate compiled requirements csreq -b /tmp/output.csreq -r='identifier "org.whispersystems.signal-desktop" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = U68MSDN6DR' @@ -240,57 +245,57 @@ od -A x -t x1 /tmp/output.csreq 0000020 00 00 00 21 6f 72 67 2e 77 68 69 73 70 65 72 73 [...] ``` -Можливо отримати цю інформацію та створити або змінити вимоги за допомогою деяких API з `Security.framework`, таких як: +Можна отримати доступ до цієї інформації та створювати або змінювати вимоги за допомогою деяких API з `Security.framework`, наприклад: -#### **Перевірка дійсності** +#### **Checking Validity** -- **`Sec[Static]CodeCheckValidity`**: Перевіряє дійсність SecCodeRef відповідно до вимоги. -- **`SecRequirementEvaluate`**: Валідовує вимогу в контексті сертифіката. -- **`SecTaskValidateForRequirement`**: Валідовує запущений SecTask відповідно до вимоги `CFString`. +- **`Sec[Static]CodeCheckValidity`**: Перевіряє дійсність `SecCodeRef` відповідно до Requirement. +- **`SecRequirementEvaluate`**: Валідовує Requirement у контексті сертифікату. +- **`SecTaskValidateForRequirement`**: Валідовує запущений `SecTask` відповідно до вимоги у вигляді `CFString`. -#### **Створення та управління вимогами коду** +#### **Creating and Managing Code Requirements** -- **`SecRequirementCreateWithData`:** Створює `SecRequirementRef` з двійкових даних, що представляють вимогу. -- **`SecRequirementCreateWithString`:** Створює `SecRequirementRef` з рядкової виразу вимоги. -- **`SecRequirementCopy[Data/String]`**: Отримує двійкове представлення даних `SecRequirementRef`. -- **`SecRequirementCreateGroup`**: Створює вимогу для членства в групі додатків. +- **`SecRequirementCreateWithData`:** Створює `SecRequirementRef` з бінарних даних, що представляють вимогу. +- **`SecRequirementCreateWithString`:** Створює `SecRequirementRef` з рядкового виразу вимоги. +- **`SecRequirementCopy[Data/String]`**: Отримує бінарне подання `SecRequirementRef`. +- **`SecRequirementCreateGroup`**: Створює вимогу для членства в app-group -#### **Доступ до інформації про підпис коду** +#### **Accessing Code Signing Information** -- **`SecStaticCodeCreateWithPath`**: Ініціалізує об'єкт `SecStaticCodeRef` з шляху файлової системи для перевірки підписів коду. -- **`SecCodeCopySigningInformation`**: Отримує інформацію про підпис з `SecCodeRef` або `SecStaticCodeRef`. +- **`SecStaticCodeCreateWithPath`**: Ініціалізує об'єкт `SecStaticCodeRef` з файлового шляху для інспекції підписів коду. +- **`SecCodeCopySigningInformation`**: Отримує інформацію про підпис із `SecCodeRef` або `SecStaticCodeRef`. -#### **Модифікація вимог коду** +#### **Modifying Code Requirements** -- **`SecCodeSignerCreate`**: Створює об'єкт `SecCodeSignerRef` для виконання операцій підпису коду. -- **`SecCodeSignerSetRequirement`**: Встановлює нову вимогу для підписувача коду, яку потрібно застосувати під час підпису. -- **`SecCodeSignerAddSignature`**: Додає підпис до коду, що підписується, з вказаним підписувачем. +- **`SecCodeSignerCreate`**: Створює `SecCodeSignerRef` для виконання операцій підписування коду. +- **`SecCodeSignerSetRequirement`**: Встановлює нову вимогу для `code signer`, яка застосовується під час підписування. +- **`SecCodeSignerAddSignature`**: Додає підпис до коду, що підписується вказаним підписувачем. -#### **Валідування коду з вимогами** +#### **Validating Code with Requirements** -- **`SecStaticCodeCheckValidity`**: Валідовує статичний об'єкт коду відповідно до вказаних вимог. +- **`SecStaticCodeCheckValidity`**: Валідовує статичний об'єкт коду відповідно до зазначених вимог. -#### **Додаткові корисні API** +#### **Additional Useful APIs** -- **`SecCodeCopy[Internal/Designated]Requirement`: Отримати SecRequirementRef з SecCodeRef** -- **`SecCodeCopyGuestWithAttributes`**: Створює `SecCodeRef`, що представляє об'єкт коду на основі специфічних атрибутів, корисно для пісочниці. -- **`SecCodeCopyPath`**: Отримує шлях файлової системи, пов'язаний з `SecCodeRef`. -- **`SecCodeCopySigningIdentifier`**: Отримує ідентифікатор підпису (наприклад, Team ID) з `SecCodeRef`. -- **`SecCodeGetTypeID`**: Повертає ідентифікатор типу для об'єктів `SecCodeRef`. -- **`SecRequirementGetTypeID`**: Отримує CFTypeID `SecRequirementRef`. +- **`SecCodeCopy[Internal/Designated]Requirement`: Get SecRequirementRef from SecCodeRef** +- **`SecCodeCopyGuestWithAttributes`**: Створює `SecCodeRef`, що представляє об’єкт коду на основі певних атрибутів, корисно для sandboxing. +- **`SecCodeCopyPath`**: Отримує файловий шлях, пов’язаний із `SecCodeRef`. +- **`SecCodeCopySigningIdentifier`**: Отримує signing identifier (наприклад, Team ID) з `SecCodeRef`. +- **`SecCodeGetTypeID`**: Повертає ідентифікатор типу для об’єктів `SecCodeRef`. +- **`SecRequirementGetTypeID`**: Отримує CFTypeID для `SecRequirementRef` -#### **Прапори та константи підпису коду** +#### **Code Signing Flags and Constants** -- **`kSecCSDefaultFlags`**: Значення за замовчуванням, що використовуються в багатьох функціях Security.framework для операцій підпису коду. -- **`kSecCSSigningInformation`**: Прапор, що використовується для вказівки на те, що інформацію про підпис слід отримати. +- **`kSecCSDefaultFlags`**: Прапори за замовчуванням, що використовуються у багатьох функціях `Security.framework` для операцій підписування коду. +- **`kSecCSSigningInformation`**: Прапор, що вказує на необхідність отримати інформацію про підпис. -## Примус підпису коду +## Code Signature Enforcement -**Ядро** є тим, хто **перевіряє підпис коду** перед тим, як дозволити виконання коду додатка. Більше того, один зі способів мати можливість записувати та виконувати новий код в пам'яті - це зловживання JIT, якщо `mprotect` викликано з прапором `MAP_JIT`. Зверніть увагу, що додаток потребує спеціального права для того, щоб мати можливість це робити. +Саме **ядро** перевіряє **підпис коду** перед тим, як дозволити виконання коду додатка. Крім того, одним із способів записати й виконати в пам'яті новий код є зловживання JIT, якщо `mprotect` викликається з прапором `MAP_JIT`. Зверніть увагу, що додаток потребує спеціального entitlement, щоб мати можливість це зробити. ## `cs_blobs` & `cs_blob` -[**cs_blob**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/ubc_internal.h#L106) структура містить інформацію про права, що має запущений процес. `csb_platform_binary` також інформує, чи є додаток платформним бінарним (що перевіряється в різні моменти операційною системою для застосування механізмів безпеки, таких як захист прав SEND до портів завдань цих процесів). +[**cs_blob**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/ubc_internal.h#L106) структура містить інформацію про дозволи (entitlements) запущеного процесу. `csb_platform_binary` також вказує, чи є додаток platform binary (що перевіряється ОС у різні моменти для застосування механізмів безпеки, наприклад щоб захищати SEND права до task портів цих процесів). ```c struct cs_blob { struct cs_blob *csb_next;