mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/macos-hardening/macos-security-and-privilege-escalation
This commit is contained in:
parent
2c62c15400
commit
14a26af3bd
@ -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)
|
||||
|
@ -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}}
|
||||
|
@ -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("<I", macho_bytes, 0)
|
||||
is64 = magic in (0xfeedfacf,)
|
||||
if is64:
|
||||
ncmds = struct.unpack_from("<I", macho_bytes, 0x10)[0]
|
||||
sizeofcmds = struct.unpack_from("<I", macho_bytes, 0x14)[0]
|
||||
off = 0x20
|
||||
else:
|
||||
# 32-bit not shown
|
||||
return None
|
||||
|
||||
code_sig_off = code_sig_size = None
|
||||
for _ in range(ncmds):
|
||||
cmd, cmdsize = struct.unpack_from("<II", macho_bytes, off)
|
||||
if cmd == LC_CODE_SIGNATURE:
|
||||
# struct linkedit_data_command is little-endian in file
|
||||
_, _, dataoff, datasize = struct.unpack_from("<IIII", macho_bytes, off)
|
||||
code_sig_off, code_sig_size = dataoff, datasize
|
||||
off += cmdsize
|
||||
|
||||
if code_sig_off is None:
|
||||
return None
|
||||
|
||||
blob = macho_bytes[code_sig_off: code_sig_off + code_sig_size]
|
||||
if be32(blob, 0x0) != CSMAGIC_EMBEDDED_SIGNATURE:
|
||||
return None
|
||||
|
||||
count = be32(blob, 0x8)
|
||||
# iterate BlobIndex entries (8 bytes each after 12-byte header)
|
||||
for i in range(count):
|
||||
idx_off = 12 + i*8
|
||||
btype = be32(blob, idx_off)
|
||||
boff = be32(blob, idx_off+4)
|
||||
if btype == CSMAGIC_EMBEDDED_ENTITLEMENTS:
|
||||
# GenericBlob is big-endian header followed by bplist
|
||||
glen = be32(blob, boff+4)
|
||||
data = blob[boff+8: boff+glen]
|
||||
return plistlib.loads(data)
|
||||
return None
|
||||
```
|
||||
Usage tips:
|
||||
- Щоб працювати з fat binaries, спочатку прочитайте struct fat_header/fat_arch, виберіть потрібний архітектурний зріз, потім передайте піддіапазон у parse_entitlements.
|
||||
- На macOS ви можете перевірити результати за допомогою: codesign -d --entitlements :- /path/to/binary
|
||||
|
||||
|
||||
## Example findings
|
||||
|
||||
Привілейовані platform binaries часто запитують чутливі entitlements, такі як:
|
||||
- com.apple.security.network.server = true
|
||||
- com.apple.rootless.storage.early_boot_mount = true
|
||||
- com.apple.private.kernel.system-override = true
|
||||
- com.apple.private.pmap.load-trust-cache = ["cryptex1.boot.os", "cryptex1.boot.app", "cryptex1.safari-downlevel"]
|
||||
|
||||
Пошук їх у великому масштабі по firmware images надзвичайно цінний для attack surface mapping і diffing між релізами/пристроями.
|
||||
|
||||
|
||||
## Scaling across IPSWs (mounting and indexing)
|
||||
|
||||
Щоб перерахувати виконувані файли та витягнути entitlements у масштабі без зберігання повних образів:
|
||||
|
||||
- Використовуйте ipsw tool від @blacktop для завантаження і монтування файлових систем прошивки. Монтування використовує apfs-fuse, тож ви можете обходити APFS томи без повного витягання.
|
||||
```bash
|
||||
# Download latest IPSW for iPhone11,2 (iPhone XS)
|
||||
ipsw download ipsw -y --device iPhone11,2 --latest
|
||||
|
||||
# Mount IPSW filesystem (uses underlying apfs-fuse)
|
||||
ipsw mount fs <IPSW_FILE>
|
||||
```
|
||||
- Переглядайте змонтовані томи, щоб знайти 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}}
|
@ -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**, яка в основному складається з:
|
||||
|
||||
- Заголовка
|
||||
- Команд завантаження
|
||||
- Даних
|
||||
- Заголовок
|
||||
- Команди завантаження
|
||||
- Дані
|
||||
|
||||
.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$"`
|
||||
|
||||
<pre class="language-c"><code class="lang-c"><strong>#define FAT_MAGIC 0xcafebabe
|
||||
</strong><strong>#define FAT_CIGAM 0xbebafeca /* NXSwapLong(FAT_MAGIC) */
|
||||
</strong>
|
||||
struct fat_header {
|
||||
<strong> uint32_t magic; /* FAT_MAGIC або FAT_MAGIC_64 */
|
||||
</strong><strong> uint32_t nfat_arch; /* кількість структур, що слідують */
|
||||
<strong> uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */
|
||||
</strong><strong> uint32_t nfat_arch; /* number of structs that follow */
|
||||
</strong>};
|
||||
|
||||
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 */
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
Заголовок має **магічні** байти, за якими слідує **число** **архітектур**, які файл **містить** (`nfat_arch`), і кожна архітектура матиме структуру `fat_arch`.
|
||||
Заголовок містить **magic**-байти, за якими йде **кількість** **архітектур**, які **містить** файл (`nfat_arch`), і для кожної архітектури існує структура `fat_arch`.
|
||||
|
||||
Перевірте це за допомогою:
|
||||
Перевірити це можна за допомогою:
|
||||
|
||||
<pre class="language-shell-session"><code class="lang-shell-session">% 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
|
||||
<strong>nfat_arch 2
|
||||
</strong><strong>архітектура x86_64
|
||||
</strong><strong>architecture x86_64
|
||||
</strong> cputype CPU_TYPE_X86_64
|
||||
cpusubtype CPU_SUBTYPE_X86_64_ALL
|
||||
capabilities 0x0
|
||||
<strong> offset 16384
|
||||
</strong><strong> size 72896
|
||||
</strong> align 2^14 (16384)
|
||||
<strong>архітектура arm64e
|
||||
<strong>architecture arm64e
|
||||
</strong> cputype CPU_TYPE_ARM64
|
||||
cpusubtype CPU_SUBTYPE_ARM64E
|
||||
capabilities PTR_AUTH_VERSION USERSPACE 0
|
||||
@ -64,15 +64,15 @@ capabilities PTR_AUTH_VERSION USERSPACE 0
|
||||
</strong> align 2^14 (16384)
|
||||
</code></pre>
|
||||
|
||||
або за допомогою інструменту [Mach-O View](https://sourceforge.net/projects/machoview/):
|
||||
or using the [Mach-O View](https://sourceforge.net/projects/machoview/) tool:
|
||||
|
||||
<figure><img src="../../../images/image (1094).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Як ви, напевно, думаєте, зазвичай універсальний бінарник, скомпільований для 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
|
||||
|
||||
<figure><img src="../../../images/image (1133).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## **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**:
|
||||
|
||||
<pre class="language-c"><code class="lang-c">struct segment_command_64 { /* для 64-бітних архітектур */
|
||||
<pre class="language-c"><code class="lang-c">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 */
|
||||
<strong> uint32_t nsects; /* кількість секцій у сегменті */
|
||||
</strong> 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 */
|
||||
<strong> uint32_t nsects; /* number of sections in segment */
|
||||
</strong> uint32_t flags; /* flags */
|
||||
};
|
||||
</code></pre>
|
||||
|
||||
Приклад заголовка сегмента:
|
||||
Example of segment header:
|
||||
|
||||
<figure><img src="../../../images/image (1126).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Цей заголовок визначає **кількість секцій, заголовки яких з'являються після** нього:
|
||||
Цей заголовок визначає **кількість секцій**, заголовки яких з'являються після нього:
|
||||
```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**:
|
||||
|
||||
<figure><img src="../../../images/image (1108).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Якщо ви **додасте** **зсув секції** (0x37DC) + **зсув**, де **архітектура починається**, в цьому випадку `0x18000` --> `0x37DC + 0x18000 = 0x1B7DC`
|
||||
Якщо ви **додасте** **section offset** (0x37DC) до **offset**, де **arch starts** (у цьому випадку `0x18000`) --> `0x37DC + 0x18000 = 0x1B7DC`
|
||||
|
||||
<figure><img src="../../../images/image (701).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Також можливо отримати **інформацію про заголовки** з **командного рядка** за допомогою:
|
||||
Також можна отримати **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*/
|
||||
```
|
||||
.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**
|
||||
|
||||
 (3).png>)
|
||||
|
||||
Це включає:
|
||||
|
||||
- **Таблиця функцій:** Яка містить інформацію про функції програми.
|
||||
- **Таблиця символів**: Яка містить інформацію про зовнішні функції, що використовуються бінарним файлом
|
||||
- Вона також може містити внутрішні функції, імена змінних та інше.
|
||||
- **Function table:** Яка містить інформацію про функції програми.
|
||||
- **Symbol table**: Яка містить інформацію про зовнішні функції, що використовуються бінарним файлом
|
||||
- Також може містити імена внутрішніх функцій, змінних та інше.
|
||||
|
||||
Щоб перевірити це, ви можете використовувати інструмент [**Mach-O View**](https://sourceforge.net/projects/machoview/):
|
||||
Щоб перевірити це, ви можете використати інструмент [**Mach-O View**](https://sourceforge.net/projects/machoview/):
|
||||
|
||||
<figure><img src="../../../images/image (1120).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
@ -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`...
|
||||
|
@ -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** з цією інформацією:
|
||||
|
||||
<figure><img src="../../../images/image (1) (1) (1) (1).png" alt="" width="431"><figcaption></figcaption></figure>
|
||||
|
||||
Магічний заголовок підпису коду - **`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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user