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
4d1fb13574
commit
aff0c64704
@ -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 @@
|
||||
# Trucchi per Software/Tipi di File Specifici
|
||||
# Trucchi per software specifici / tipi di file
|
||||
|
||||
{{#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 Estrazione degli Entitlements & Indicizzazione IPSW
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Panoramica
|
||||
|
||||
Questa pagina spiega come estrarre gli entitlements dai binari Mach-O in modo programmatico percorrendo LC_CODE_SIGNATURE e parsando il SuperBlob della firma del codice, e come scalare questo processo attraverso i firmware Apple IPSW montando e indicizzando i loro contenuti per ricerca/diff forense.
|
||||
|
||||
Se ti serve un ripasso sul formato Mach-O e sul code signing, vedi anche: macOS code signing and SuperBlob internals.
|
||||
- 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
|
||||
|
||||
Gli entitlements sono memorizzati all'interno dei dati della firma del codice referenziati dal load command LC_CODE_SIGNATURE e posizionati nel segmento __LINKEDIT. La signature è una CS_SuperBlob contenente multiple blob (code directory, requirements, entitlements, CMS, ecc.). L'entitlements blob è una CS_GenericBlob il cui dato è un Apple Binary Property List (bplist00) che mappa le chiavi degli entitlements ai valori.
|
||||
|
||||
Key structures (from 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;
|
||||
```
|
||||
Costanti importanti:
|
||||
- LC_CODE_SIGNATURE cmd = 0x1d
|
||||
- CS SuperBlob magic = 0xfade0cc0
|
||||
- Entitlements blob type (CSMAGIC_EMBEDDED_ENTITLEMENTS) = 0xfade7171
|
||||
- DER entitlements possono essere presenti tramite slot speciali (es., -7); vedi la pagina macOS Code Signing per note su slot speciali e DER entitlements
|
||||
|
||||
Nota: Multi-arch (fat) binaries contengono multiple Mach-O slices. Devi selezionare la slice per l'architettura che vuoi ispezionare e poi percorrere i suoi load commands.
|
||||
|
||||
|
||||
## Passaggi di estrazione (generici, sufficientemente senza perdita)
|
||||
|
||||
1) Analizza l'header Mach-O; itera i record load_command per il numero ncmds.
|
||||
2) Individua LC_CODE_SIGNATURE; leggi linkedit_data_command.dataoff/datasize per mappare il Code Signing SuperBlob posizionato in __LINKEDIT.
|
||||
3) Valida CS_SuperBlob.magic == 0xfade0cc0; itera count voci di CS_BlobIndex.
|
||||
4) Individua index.type == 0xfade7171 (embedded entitlements). Leggi il CS_GenericBlob puntato e parsalo come un plist binario Apple (bplist00) per ottenere entitlements chiave/valore.
|
||||
|
||||
Note di implementazione:
|
||||
- Le strutture di Code signature utilizzano campi big-endian; scambia l'ordine dei byte quando esegui il parsing su host little-endian.
|
||||
- I dati del GenericBlob delle entitlements sono un plist binario (gestito dalle librerie plist standard).
|
||||
- Alcuni binari iOS possono includere DER entitlements; inoltre alcuni store/slot variano tra piattaforme/versioni. Verifica sia le entitlements standard sia quelle DER se necessario.
|
||||
- Per i binari fat, usa gli header fat (FAT_MAGIC/FAT_MAGIC_64) per localizzare la slice e l'offset corretti prima di attraversare i load commands Mach-O.
|
||||
|
||||
|
||||
## Schema minimo di parsing (Python)
|
||||
|
||||
Quanto segue è uno schema compatto che mostra il flusso di controllo per trovare e decodificare le entitlements. Omesso intenzionalmente controlli di confine robusti e il supporto completo per binari fat per brevità.
|
||||
```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
|
||||
```
|
||||
Suggerimenti d'uso:
|
||||
- Per gestire fat binaries, prima leggi struct fat_header/fat_arch, scegli la slice di architettura desiderata, poi passa il sottointervallo a parse_entitlements.
|
||||
- Su macOS puoi verificare i risultati con: codesign -d --entitlements :- /path/to/binary
|
||||
|
||||
|
||||
## Esempi di risultati
|
||||
|
||||
I binari di piattaforma privilegiati spesso richiedono entitlements sensibili come:
|
||||
- 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"]
|
||||
|
||||
La ricerca di questi su larga scala attraverso le immagini firmware è estremamente utile per attack surface mapping e per il diffing tra release/dispositivi.
|
||||
|
||||
|
||||
## Scalare attraverso IPSWs (montaggio e indicizzazione)
|
||||
|
||||
Per enumerare gli eseguibili ed estrarre gli entitlements su larga scala senza conservare le immagini complete:
|
||||
|
||||
- Usa lo strumento ipsw di @blacktop per scaricare e montare i filesystem del firmware. Il montaggio sfrutta apfs-fuse, così puoi attraversare i volumi APFS senza estrazione completa.
|
||||
```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>
|
||||
```
|
||||
- Esplora i volumi montati per individuare file Mach-O (controlla magic e/o usa file/otool), poi analizza entitlements e imported frameworks.
|
||||
- Conserva una vista normalizzata in un database relazionale per evitare una crescita lineare attraverso migliaia di IPSWs:
|
||||
- executables, operating_system_versions, entitlements, frameworks
|
||||
- relazione molti-a-molti: executable↔OS version, executable↔entitlement, executable↔framework
|
||||
|
||||
Esempio di query per elencare tutte le OS versions che contengono un dato executable name:
|
||||
```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";
|
||||
```
|
||||
Note sulla portabilità del DB (se implementi il tuo indexer):
|
||||
- Usa un ORM/abstraction (es., SeaORM) per mantenere il codice DB-agnostic (SQLite/PostgreSQL).
|
||||
- SQLite richiede AUTOINCREMENT solo su un INTEGER PRIMARY KEY; se vuoi i64 PKs in Rust, genera le entità come i32 e converti i tipi, SQLite memorizza INTEGER come intero con segno a 8 byte internamente.
|
||||
|
||||
|
||||
## Open-source tooling and references for entitlement hunting
|
||||
|
||||
- Firmware mount/download: https://github.com/blacktop/ipsw
|
||||
- Databases e riferimenti per entitlements:
|
||||
- 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 per strutture e costanti:
|
||||
- loader.h (Mach-O headers, load commands)
|
||||
- cs_blobs.h (SuperBlob, GenericBlob, CodeDirectory)
|
||||
|
||||
Per maggiori dettagli sugli internals del code signing (Code Directory, special slots, DER entitlements), vedi: [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}}
|
@ -4,13 +4,13 @@
|
||||
|
||||
## Informazioni di base
|
||||
|
||||
I binari di Mac OS sono solitamente compilati come **universal binaries**. Un **universal binary** può **supportare più architetture nello stesso file**.
|
||||
I binari di macOS vengono solitamente compilati come **universal binaries**. Un **universal binary** può **supportare più architetture nello stesso file**.
|
||||
|
||||
Questi binari seguono la **struttura Mach-O** che è fondamentalmente composta da:
|
||||
Questi binari seguono la **struttura Mach-O** che è sostanzialmente composta da:
|
||||
|
||||
- Intestazione
|
||||
- Comandi di caricamento
|
||||
- Dati
|
||||
- Header
|
||||
- Load Commands
|
||||
- Data
|
||||
|
||||
.png>)
|
||||
|
||||
@ -22,40 +22,40 @@ Cerca il file con: `mdfind fat.h | grep -i mach-o | grep -E "fat.h$"`
|
||||
</strong><strong>#define FAT_CIGAM 0xbebafeca /* NXSwapLong(FAT_MAGIC) */
|
||||
</strong>
|
||||
struct fat_header {
|
||||
<strong> uint32_t magic; /* FAT_MAGIC o FAT_MAGIC_64 */
|
||||
</strong><strong> uint32_t nfat_arch; /* numero di strutture che seguono */
|
||||
<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; /* specificatore cpu (int) */
|
||||
cpu_subtype_t cpusubtype; /* specificatore macchina (int) */
|
||||
uint32_t offset; /* offset del file a questo file oggetto */
|
||||
uint32_t size; /* dimensione di questo file oggetto */
|
||||
uint32_t align; /* allineamento come potenza di 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>
|
||||
|
||||
L'intestazione ha i byte **magic** seguiti dal **numero** di **architetture** che il file **contiene** (`nfat_arch`) e ogni architettura avrà una struttura `fat_arch`.
|
||||
L'header contiene i byte di **magic** seguiti dal **numero** di **archs** che il file **contiene** (`nfat_arch`) e ogni arch avrà una struttura `fat_arch`.
|
||||
|
||||
Controllalo con:
|
||||
Verificalo con:
|
||||
|
||||
<pre class="language-shell-session"><code class="lang-shell-session">% file /bin/ls
|
||||
/bin/ls: Mach-O universal binary con 2 architetture: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
|
||||
/bin/ls (per architettura x86_64): Mach-O 64-bit executable x86_64
|
||||
/bin/ls (per architettura arm64e): Mach-O 64-bit executable arm64e
|
||||
/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 (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>architettura 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>architettura 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>
|
||||
|
||||
o utilizzando lo strumento [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>
|
||||
|
||||
Come potresti pensare, di solito un universal binary compilato per 2 architetture **raddoppia la dimensione** di uno compilato per solo 1 arch.
|
||||
Come potresti pensare, di solito un universal binary compilato per 2 architetture **raddoppia la dimensione** rispetto a uno compilato per una sola arch.
|
||||
|
||||
## **Mach-O Header**
|
||||
|
||||
L'intestazione contiene informazioni di base sul file, come i byte magic per identificarlo come un file Mach-O e informazioni sull'architettura target. Puoi trovarlo in: `mdfind loader.h | grep -i mach-o | grep -E "loader.h$"`
|
||||
L'header contiene informazioni di base sul file, come i magic bytes per identificarlo come file Mach-O e informazioni sull'architettura target. Puoi trovarlo in: `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) */
|
||||
@ -101,18 +101,18 @@ uint32_t reserved; /* reserved */
|
||||
```
|
||||
### Tipi di file Mach-O
|
||||
|
||||
Ci sono diversi tipi di file, puoi trovarli definiti nel [**codice sorgente per esempio qui**](https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h). I più importanti sono:
|
||||
Ci sono diversi tipi di file, puoi trovarli definiti nel [**source code for example here**](https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h). I più importanti sono:
|
||||
|
||||
- `MH_OBJECT`: File oggetto relocabile (prodotti intermedi della compilazione, non eseguibili ancora).
|
||||
- `MH_EXECUTE`: File eseguibili.
|
||||
- `MH_FVMLIB`: File di libreria VM fissa.
|
||||
- `MH_CORE`: Dump di codice
|
||||
- `MH_PRELOAD`: File eseguibile pre-caricato (non più supportato in XNU)
|
||||
- `MH_DYLIB`: Librerie dinamiche
|
||||
- `MH_OBJECT`: Relocatable object file (prodotti intermedi della compilazione, non ancora eseguibili).
|
||||
- `MH_EXECUTE`: Executable files.
|
||||
- `MH_FVMLIB`: Fixed VM library file.
|
||||
- `MH_CORE`: Code Dumps
|
||||
- `MH_PRELOAD`: Preloaded executable file (no longer supported in XNU)
|
||||
- `MH_DYLIB`: Dynamic Libraries
|
||||
- `MH_DYLINKER`: Linker dinamico
|
||||
- `MH_BUNDLE`: "File plugin". Generati utilizzando -bundle in gcc e caricati esplicitamente da `NSBundle` o `dlopen`.
|
||||
- `MH_DYSM`: File `.dSym` companion (file con simboli per il debug).
|
||||
- `MH_KEXT_BUNDLE`: Estensioni del kernel.
|
||||
- `MH_BUNDLE`: "Plugin files". Generated using -bundle in gcc and explicitly loaded by `NSBundle` or `dlopen`.
|
||||
- `MH_DYSM`: Companion `.dSym` file (file con i simboli per il debugging).
|
||||
- `MH_KEXT_BUNDLE`: Kernel Extensions.
|
||||
```bash
|
||||
# Checking the mac header of a binary
|
||||
otool -arch arm64e -hv /bin/ls
|
||||
@ -120,75 +120,75 @@ Mach header
|
||||
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
|
||||
MH_MAGIC_64 ARM64 E USR00 EXECUTE 19 1728 NOUNDEFS DYLDLINK TWOLEVEL PIE
|
||||
```
|
||||
Oppure usando [Mach-O View](https://sourceforge.net/projects/machoview/):
|
||||
Or using [Mach-O View](https://sourceforge.net/projects/machoview/):
|
||||
|
||||
<figure><img src="../../../images/image (1133).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## **Flag Mach-O**
|
||||
## **Flag di Mach-O**
|
||||
|
||||
Il codice sorgente definisce anche diversi flag utili per il caricamento delle librerie:
|
||||
|
||||
- `MH_NOUNDEFS`: Nessun riferimento non definito (completamente collegato)
|
||||
- `MH_DYLDLINK`: Collegamento Dyld
|
||||
- `MH_PREBOUND`: Riferimenti dinamici precollegati.
|
||||
- `MH_SPLIT_SEGS`: Il file divide i segmenti r/o e r/w.
|
||||
- `MH_WEAK_DEFINES`: Il binario ha simboli debolmente definiti
|
||||
- `MH_BINDS_TO_WEAK`: Il binario utilizza simboli deboli
|
||||
- `MH_ALLOW_STACK_EXECUTION`: Rende lo stack eseguibile
|
||||
- `MH_NO_REEXPORTED_DYLIBS`: Libreria non comandi LC_REEXPORT
|
||||
- `MH_PIE`: Eseguibile indipendente dalla posizione
|
||||
- `MH_HAS_TLV_DESCRIPTORS`: C'è una sezione con variabili locali per thread
|
||||
- `MH_NO_HEAP_EXECUTION`: Nessuna esecuzione per heap/pagine dati
|
||||
- `MH_HAS_OBJC`: Il binario ha sezioni oBject-C
|
||||
- `MH_SIM_SUPPORT`: Supporto per simulatori
|
||||
- `MH_DYLIB_IN_CACHE`: Utilizzato su dylibs/frameworks nella cache delle librerie condivise.
|
||||
- `MH_NOUNDEFS`: Nessun riferimento indefinito (tutti i riferimenti risolti)
|
||||
- `MH_DYLDLINK`: Collegamento dyld
|
||||
- `MH_PREBOUND`: Riferimenti dinamici preassegnati.
|
||||
- `MH_SPLIT_SEGS`: File con segmenti r/o e r/w separati.
|
||||
- `MH_WEAK_DEFINES`: Il binario ha simboli definiti debolmente
|
||||
- `MH_BINDS_TO_WEAK`: Il binario usa simboli deboli
|
||||
- `MH_ALLOW_STACK_EXECUTION`: Rendere lo stack eseguibile
|
||||
- `MH_NO_REEXPORTED_DYLIBS`: La libreria non ha comandi LC_REEXPORT
|
||||
- `MH_PIE`: Eseguibile indipendente dalla posizione (PIE)
|
||||
- `MH_HAS_TLV_DESCRIPTORS`: Presenza di una sezione con variabili locali al thread
|
||||
- `MH_NO_HEAP_EXECUTION`: Nessuna esecuzione per le pagine heap/data
|
||||
- `MH_HAS_OBJC`: Il binario contiene sezioni Objective-C
|
||||
- `MH_SIM_SUPPORT`: Supporto al simulatore
|
||||
- `MH_DYLIB_IN_CACHE`: Usato per dylibs/frameworks nella cache delle librerie condivise.
|
||||
|
||||
## **Comandi di caricamento Mach-O**
|
||||
|
||||
Il **layout del file in memoria** è specificato qui, dettagliando la **posizione della tabella dei simboli**, il contesto del thread principale all'inizio dell'esecuzione e le **librerie condivise** richieste. Vengono fornite istruzioni al caricatore dinamico **(dyld)** sul processo di caricamento del binario in memoria.
|
||||
La **disposizione del file in memoria** viene specificata qui, dettagliando la **posizione della tabella dei simboli**, il contesto del main thread all'avvio dell'esecuzione, e le **librerie condivise** richieste. Vengono fornite istruzioni al dynamic loader **(dyld)** sul processo di caricamento del binario in memoria.
|
||||
|
||||
Utilizza la struttura **load_command**, definita nel menzionato **`loader.h`**:
|
||||
Viene utilizzata la struttura **load_command**, definita nel già citato **`loader.h`**:
|
||||
```objectivec
|
||||
struct load_command {
|
||||
uint32_t cmd; /* type of load command */
|
||||
uint32_t cmdsize; /* total size of command in bytes */
|
||||
};
|
||||
```
|
||||
Ci sono circa **50 diversi tipi di comandi di caricamento** che il sistema gestisce in modo diverso. I più comuni sono: `LC_SEGMENT_64`, `LC_LOAD_DYLINKER`, `LC_MAIN`, `LC_LOAD_DYLIB` e `LC_CODE_SIGNATURE`.
|
||||
Esistono circa **50 diversi tipi di load commands** che il sistema gestisce in modo differente. I più comuni sono: `LC_SEGMENT_64`, `LC_LOAD_DYLINKER`, `LC_MAIN`, `LC_LOAD_DYLIB`, and `LC_CODE_SIGNATURE`.
|
||||
|
||||
### **LC_SEGMENT/LC_SEGMENT_64**
|
||||
|
||||
> [!TIP]
|
||||
> Fondamentalmente, questo tipo di comando di caricamento definisce **come caricare il \_\_TEXT** (codice eseguibile) **e il \_\_DATA** (dati per il processo) **segmenti** secondo gli **offset indicati nella sezione Dati** quando il binario viene eseguito.
|
||||
> In pratica, questo tipo di Load Command definisce **come caricare i \_\_TEXT** (codice eseguibile) **e i \_\_DATA** (dati per il processo) **segments** in base agli **offset indicati nella Data section** quando il binario viene eseguito.
|
||||
|
||||
Questi comandi **definiscono segmenti** che sono **mappati** nello **spazio di memoria virtuale** di un processo quando viene eseguito.
|
||||
Questi comandi **definiscono segmenti** che vengono **mappati** nello **spazio di memoria virtuale** di un processo quando viene eseguito.
|
||||
|
||||
Ci sono **diversi tipi** di segmenti, come il **\_\_TEXT** segmento, che contiene il codice eseguibile di un programma, e il **\_\_DATA** segmento, che contiene dati utilizzati dal processo. Questi **segmenti si trovano nella sezione dati** del file Mach-O.
|
||||
Esistono **diversi tipi** di segmenti, come il segmento **\_\_TEXT**, che contiene il codice eseguibile di un programma, e il segmento **\_\_DATA**, che contiene i dati utilizzati dal processo. Questi **segmenti sono situati nella Data section** del file Mach-O.
|
||||
|
||||
**Ogni segmento** può essere ulteriormente **diviso** in più **sezioni**. La **struttura del comando di caricamento** contiene **informazioni** su **queste sezioni** all'interno del rispettivo segmento.
|
||||
**Ogni segmento** può essere ulteriormente **diviso** in più **sezioni**. La **struttura del load command** contiene **informazioni** su **queste sezioni** all'interno del rispettivo segmento.
|
||||
|
||||
Nell'intestazione prima trovi l'**intestazione del segmento**:
|
||||
In the header first you find the **segment header**:
|
||||
|
||||
<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; /* includes sizeof section_64 structs */
|
||||
char segname[16]; /* nome del segmento */
|
||||
uint64_t vmaddr; /* indirizzo di memoria di questo segmento */
|
||||
uint64_t vmsize; /* dimensione della memoria di questo segmento */
|
||||
uint64_t fileoff; /* offset del file di questo segmento */
|
||||
uint64_t filesize; /* quantità da mappare dal file */
|
||||
int32_t maxprot; /* protezione VM massima */
|
||||
int32_t initprot; /* protezione VM iniziale */
|
||||
<strong> uint32_t nsects; /* numero di sezioni nel segmento */
|
||||
</strong> uint32_t flags; /* flag */
|
||||
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>
|
||||
|
||||
Esempio di intestazione del segmento:
|
||||
Example of segment header:
|
||||
|
||||
<figure><img src="../../../images/image (1126).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Questa intestazione definisce il **numero di sezioni i cui intestazioni appaiono dopo** di essa:
|
||||
Questo header definisce il **numero di sezioni i cui header appaiono dopo** di esso:
|
||||
```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 */
|
||||
};
|
||||
```
|
||||
Esempio di **intestazione di sezione**:
|
||||
Esempio di **section header**:
|
||||
|
||||
<figure><img src="../../../images/image (1108).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Se **aggiungi** l'**offset di sezione** (0x37DC) + l'**offset** dove **inizia l'arch**, in questo caso `0x18000` --> `0x37DC + 0x18000 = 0x1B7DC`
|
||||
Se **sommi** il **section offset** (0x37DC) + l'**offset** in cui inizia l'**arch**, in questo caso `0x18000` --> `0x37DC + 0x18000 = 0x1B7DC`
|
||||
|
||||
<figure><img src="../../../images/image (701).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
È anche possibile ottenere **informazioni sugli header** dalla **linea di comando** con:
|
||||
È inoltre possibile ottenere le **headers information** dalla **command line** con:
|
||||
```bash
|
||||
otool -lv /bin/ls
|
||||
```
|
||||
Segmenti comuni caricati da questo cmd:
|
||||
Common segments loaded by this cmd:
|
||||
|
||||
- **`__PAGEZERO`:** Istruisce il kernel a **mappare** l'**indirizzo zero** in modo che **non possa essere letto, scritto o eseguito**. Le variabili maxprot e minprot nella struttura sono impostate a zero per indicare che non ci sono **diritti di lettura-scrittura-esecuzione su questa pagina**.
|
||||
- Questa allocazione è importante per **mitigare le vulnerabilità di dereferenziazione di puntatori NULL**. Questo perché XNU applica una rigida pagina zero che garantisce che la prima pagina (solo la prima) della memoria sia inaccessibile (eccetto in i386). Un binario potrebbe soddisfare questi requisiti creando un piccolo \_\_PAGEZERO (utilizzando `-pagezero_size`) per coprire i primi 4k e rendendo il resto della memoria a 32 bit accessibile sia in modalità utente che in modalità kernel.
|
||||
- **`__TEXT`**: Contiene **codice** **eseguibile** con permessi di **lettura** e **esecuzione** (non scrivibile)**.** Sezioni comuni di questo segmento:
|
||||
- `__text`: Codice binario compilato
|
||||
- `__const`: Dati costanti (solo lettura)
|
||||
- `__[c/u/os_log]string`: Costanti di stringa C, Unicode o os logs
|
||||
- `__stubs` e `__stubs_helper`: Coinvolti durante il processo di caricamento della libreria dinamica
|
||||
- `__unwind_info`: Dati di unwind dello stack.
|
||||
- Nota che tutto questo contenuto è firmato ma anche contrassegnato come eseguibile (creando più opzioni per lo sfruttamento di sezioni che non necessitano necessariamente di questo privilegio, come le sezioni dedicate alle stringhe).
|
||||
- **`__DATA`**: Contiene dati che sono **leggibili** e **scrivibili** (non eseguibili)**.**
|
||||
- `__got:` Tabella degli offset globali
|
||||
- `__nl_symbol_ptr`: Puntatore simbolo non pigro (binding al caricamento)
|
||||
- `__la_symbol_ptr`: Puntatore simbolo pigro (binding all'uso)
|
||||
- `__const`: Dovrebbe essere dati di sola lettura (non realmente)
|
||||
- `__cfstring`: Stringhe CoreFoundation
|
||||
- `__data`: Variabili globali (che sono state inizializzate)
|
||||
- `__bss`: Variabili statiche (che non sono state inizializzate)
|
||||
- `__objc_*` (\_\_objc_classlist, \_\_objc_protolist, ecc): Informazioni utilizzate dal runtime Objective-C
|
||||
- **`__DATA_CONST`**: \_\_DATA.\_\_const non è garantito essere costante (permessi di scrittura), né lo sono altri puntatori e la GOT. Questa sezione rende `__const`, alcuni inizializzatori e la tabella GOT (una volta risolta) **solo lettura** utilizzando `mprotect`.
|
||||
- **`__LINKEDIT`**: Contiene informazioni per il linker (dyld) come, simboli, stringhe e voci della tabella di rilocazione. È un contenitore generico per contenuti che non sono né in `__TEXT` né in `__DATA` e il suo contenuto è descritto in altri comandi di caricamento.
|
||||
- Informazioni dyld: Rebase, opcodes di binding non pigro/pigro/debole e informazioni di esportazione
|
||||
- Inizio delle funzioni: Tabella degli indirizzi di inizio delle funzioni
|
||||
- Dati nel codice: Isole di dati in \_\_text
|
||||
- Tabella dei simboli: Simboli nel binario
|
||||
- Tabella dei simboli indiretti: Simboli puntatore/stub
|
||||
- Tabella delle stringhe
|
||||
- Firma del codice
|
||||
- **`__OBJC`**: Contiene informazioni utilizzate dal runtime Objective-C. Anche se queste informazioni potrebbero essere trovate anche nel segmento \_\_DATA, all'interno di varie sezioni in \_\_objc\_\*.
|
||||
- **`__RESTRICT`**: Un segmento senza contenuto con una singola sezione chiamata **`__restrict`** (anch'essa vuota) che garantisce che quando si esegue il binario, ignorerà le variabili ambientali DYLD.
|
||||
- **`__PAGEZERO`:** Istruisce il kernel a **mappare** l'**indirizzo zero** così che **non possa essere letto, scritto o eseguito**. Le variabili maxprot e minprot nella struttura sono impostate a zero per indicare che **non ci sono diritti di lettura-scrittura-esecuzione su questa pagina**.
|
||||
- Questa allocazione è importante per **mitigare vulnerabilità di dereferenziazione di puntatore NULL**. Questo perché XNU impone una hard page zero che assicura che la prima pagina (solo la prima) di memoria sia inaccessibile (eccetto in i386). Un binary potrebbe soddisfare questo requisito creando un piccolo \_\_PAGEZERO (usando il `-pagezero_size`) per coprire i primi 4k e rendendo il resto della memoria a 32 bit accessibile sia in user che in kernel mode.
|
||||
- **`__TEXT`**: Contiene **codice** **eseguibile** con permessi di **lettura** e **esecuzione** (non scrivibile).
|
||||
- `__text`: Compiled binary code
|
||||
- `__const`: Constant data (read only)
|
||||
- `__[c/u/os_log]string`: C, Unicode or os logs string constants
|
||||
- `__stubs` and `__stubs_helper`: Involved during the dynamic library loading process
|
||||
- `__unwind_info`: Stack unwind data.
|
||||
- Nota che tutto questo contenuto è firmato ma anche marcato come eseguibile (creando più opzioni per lo sfruttamento di sezioni che non necessitano necessariamente di tale privilegio, come le sezioni dedicate alle stringhe).
|
||||
- **`__DATA`**: Contiene dati che sono **leggibili** e **scrivibili** (non eseguibili).
|
||||
- `__got:` Global Offset Table
|
||||
- `__nl_symbol_ptr`: Non lazy (bind at load) symbol pointer
|
||||
- `__la_symbol_ptr`: Lazy (bind on use) symbol pointer
|
||||
- `__const`: Should be read-only data (not really)
|
||||
- `__cfstring`: CoreFoundation strings
|
||||
- `__data`: Global variables (that have been initialized)
|
||||
- `__bss`: Static variables (that have not been initialized)
|
||||
- `__objc_*` (\_\_objc_classlist, \_\_objc_protolist, etc): Information used by the Objective-C runtime
|
||||
- **`__DATA_CONST`**: \_\_DATA.\_\_const non è garantito come costante (permessi di scrittura), né lo sono altri puntatori e la GOT. Questa sezione rende `__const`, alcuni inizializzatori e la tabella GOT (una volta risolta) **sola lettura** usando `mprotect`.
|
||||
- **`__LINKEDIT`**: Contiene informazioni per il linker (dyld) come tabelle di simboli, stringhe e voci di relocazione. È un contenitore generico per contenuti che non sono né in `__TEXT` né in `__DATA` e il suo contenuto è descritto in altri load commands.
|
||||
- dyld information: Rebase, Non-lazy/lazy/weak binding opcodes and export info
|
||||
- Functions starts: Table of start addresses of functions
|
||||
- Data In Code: Data islands in \_\_text
|
||||
- SYmbol Table: Symbols in binary
|
||||
- Indirect Symbol Table: Pointer/stub symbols
|
||||
- String Table
|
||||
- Code Signature
|
||||
- **`__OBJC`**: Contiene informazioni usate dal runtime Objective-C. Sebbene queste informazioni possano anche trovarsi nel segmento \_\_DATA, all'interno delle varie sezioni \_\_objc\_\*.
|
||||
- **`__RESTRICT`**: Un segmento senza contenuto con una singola sezione chiamata **`__restrict`** (anch'essa vuota) che assicura che, all'esecuzione del binary, verranno ignorate le variabili ambientali DYLD.
|
||||
|
||||
Come è stato possibile vedere nel codice, **i segmenti supportano anche flag** (anche se non sono molto utilizzati):
|
||||
As it was possible to see in the code, **segments also support flags** (although they aren't used very much):
|
||||
|
||||
- `SG_HIGHVM`: Solo core (non utilizzato)
|
||||
- `SG_FVMLIB`: Non utilizzato
|
||||
- `SG_NORELOC`: Il segmento non ha rilocazione
|
||||
- `SG_PROTECTED_VERSION_1`: Crittografia. Utilizzato ad esempio da Finder per crittografare il segmento di testo `__TEXT`.
|
||||
- `SG_HIGHVM`: Core only (not used)
|
||||
- `SG_FVMLIB`: Not used
|
||||
- `SG_NORELOC`: Segment has no relocation
|
||||
- `SG_PROTECTED_VERSION_1`: Encryption. Used for example by Finder to encrypt text `__TEXT` segment.
|
||||
|
||||
### **`LC_UNIXTHREAD/LC_MAIN`**
|
||||
|
||||
**`LC_MAIN`** contiene il punto di ingresso nell'**attributo entryoff.** Al momento del caricamento, **dyld** semplicemente **aggiunge** questo valore alla **base del binario** (in memoria), poi **salta** a questa istruzione per avviare l'esecuzione del codice del binario.
|
||||
**`LC_MAIN`** contiene l'entrypoint nell'attributo **entryoff.** Al momento del load, **dyld** semplicemente **aggiunge** questo valore alla **base del binary** (in memoria), poi **salta** a questa istruzione per avviare l'esecuzione del codice del binary.
|
||||
|
||||
**`LC_UNIXTHREAD`** contiene i valori che il registro deve avere quando si avvia il thread principale. Questo era già deprecato ma **`dyld`** lo utilizza ancora. È possibile vedere i valori dei registri impostati da questo con:
|
||||
**`LC_UNIXTHREAD`** contiene i valori che i registri devono avere all'avvio del thread principale. Questo è già deprecato ma **`dyld`** lo usa ancora. È possibile vedere i valori dei registri impostati da questo con:
|
||||
```bash
|
||||
otool -l /usr/lib/dyld
|
||||
[...]
|
||||
@ -286,34 +286,39 @@ cpsr 0x00000000
|
||||
```
|
||||
### **`LC_CODE_SIGNATURE`**
|
||||
|
||||
Contiene informazioni sulla **firma del codice del file Macho-O**. Contiene solo un **offset** che **punta** al **blob della firma**. Questo si trova tipicamente alla fine del file.\
|
||||
Tuttavia, puoi trovare alcune informazioni su questa sezione in [**questo post del blog**](https://davedelong.com/blog/2018/01/10/reading-your-own-entitlements/) e in questo [**gist**](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}}
|
||||
|
||||
|
||||
Contiene informazioni sulla **code signature del file Macho-O**. Contiene solo un **offset** che **punta** al **signature blob**. Tipicamente si trova alla fine del file.\
|
||||
Tuttavia, puoi trovare alcune informazioni su questa sezione in [**this blog post**](https://davedelong.com/blog/2018/01/10/reading-your-own-entitlements/) e in questo [**gists**](https://gist.github.com/carlospolop/ef26f8eb9fafd4bc22e69e1a32b81da4).
|
||||
|
||||
### **`LC_ENCRYPTION_INFO[_64]`**
|
||||
|
||||
Supporto per la crittografia binaria. Tuttavia, ovviamente, se un attaccante riesce a compromettere il processo, sarà in grado di scaricare la memoria non crittografata.
|
||||
Supporta la cifratura del binario. Tuttavia, ovviamente, se un attacker riesce a compromettere il processo, potrà effettuare il dump della memoria non cifrata.
|
||||
|
||||
### **`LC_LOAD_DYLINKER`**
|
||||
|
||||
Contiene il **percorso all'eseguibile del linker dinamico** che mappa le librerie condivise nello spazio degli indirizzi del processo. Il **valore è sempre impostato su `/usr/lib/dyld`**. È importante notare che in macOS, il mapping delle dylib avviene in **modalità utente**, non in modalità kernel.
|
||||
Contiene il **percorso all'eseguibile del dynamic linker** che mappa le shared libraries nello spazio degli indirizzi del processo. Il **valore è sempre impostato a `/usr/lib/dyld`**. È importante notare che in macOS, il mapping dei dylib avviene in **modalità utente**, non in modalità kernel.
|
||||
|
||||
### **`LC_IDENT`**
|
||||
|
||||
Obsoleto, ma quando configurato per generare dump in caso di panico, viene creato un core dump Mach-O e la versione del kernel è impostata nel comando `LC_IDENT`.
|
||||
Obsoleto, ma quando configurato per generare dump su panic, viene creato un core dump Mach-O e la versione del kernel viene impostata nel comando `LC_IDENT`.
|
||||
|
||||
### **`LC_UUID`**
|
||||
|
||||
UUID casuale. È utile per qualsiasi cosa direttamente, ma XNU lo memorizza nella cache con il resto delle informazioni sul processo. Può essere utilizzato nei rapporti di crash.
|
||||
UUID casuale. Non è utile direttamente, ma XNU lo memorizza nella cache insieme al resto delle informazioni del processo. Può essere usato nei crash report.
|
||||
|
||||
### **`LC_DYLD_ENVIRONMENT`**
|
||||
|
||||
Consente di indicare le variabili di ambiente al dyld prima che il processo venga eseguito. Questo può essere molto pericoloso poiché può consentire di eseguire codice arbitrario all'interno del processo, quindi questo comando di caricamento è utilizzato solo in dyld costruito con `#define SUPPORT_LC_DYLD_ENVIRONMENT` e restringe ulteriormente l'elaborazione solo alle variabili della forma `DYLD_..._PATH` specificando i percorsi di caricamento.
|
||||
Permette di indicare variabili d'ambiente a dyld prima che il processo venga eseguito. Questo può essere molto pericoloso in quanto può permettere di eseguire codice arbitrario all'interno del processo, quindi questo load command è usato solo nelle build di dyld con `#define SUPPORT_LC_DYLD_ENVIRONMENT` e limita ulteriormente l'elaborazione solo a variabili della forma `DYLD_..._PATH` che specificano load paths.
|
||||
|
||||
### **`LC_LOAD_DYLIB`**
|
||||
|
||||
Questo comando di caricamento descrive una dipendenza di **libreria** **dinamica** che **istruisce** il **loader** (dyld) a **caricare e collegare la suddetta libreria**. C'è un comando di caricamento `LC_LOAD_DYLIB` **per ogni libreria** di cui il binario Mach-O ha bisogno.
|
||||
This load command describes a **dynamic** **library** dependency which **instructs** the **loader** (dyld) to **load and link said library**. There is a `LC_LOAD_DYLIB` load command **for each library** that the Mach-O binary requires.
|
||||
|
||||
- Questo comando di caricamento è una struttura di tipo **`dylib_command`** (che contiene una struct dylib, che descrive la libreria dinamica dipendente effettiva):
|
||||
- Questo load command è una struttura di tipo **`dylib_command`** (che contiene una struct dylib, descrivendo la libreria dinamica dipendente reale):
|
||||
```objectivec
|
||||
struct dylib_command {
|
||||
uint32_t cmd; /* LC_LOAD_{,WEAK_}DYLIB */
|
||||
@ -338,53 +343,53 @@ 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)
|
||||
```
|
||||
Alcune librerie potenzialmente correlate al malware sono:
|
||||
Alcune librerie potenzialmente correlate a malware sono:
|
||||
|
||||
- **DiskArbitration**: Monitoraggio delle unità USB
|
||||
- **AVFoundation:** Cattura audio e video
|
||||
- **CoreWLAN**: Scansioni Wifi.
|
||||
|
||||
> [!NOTE]
|
||||
> Un binario Mach-O può contenere uno o **più** **costruttori**, che verranno **eseguiti** **prima** dell'indirizzo specificato in **LC_MAIN**.\
|
||||
> Gli offset di qualsiasi costruttore sono contenuti nella sezione **\_\_mod_init_func** del segmento **\_\_DATA_CONST**.
|
||||
|
||||
## **Dati Mach-O**
|
||||
|
||||
Al centro del file si trova la regione dati, che è composta da diversi segmenti come definiti nella regione dei comandi di caricamento. **Una varietà di sezioni dati può essere ospitata all'interno di ciascun segmento**, con ciascuna sezione **che contiene codice o dati** specifici per un tipo.
|
||||
- **DiskArbitration**: Monitoring USB drives
|
||||
- **AVFoundation:** Capture audio and video
|
||||
- **CoreWLAN**: Wifi scans.
|
||||
|
||||
> [!TIP]
|
||||
> I dati sono fondamentalmente la parte che contiene tutte le **informazioni** caricate dai comandi di caricamento **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 Data**
|
||||
|
||||
Al centro del file si trova la regione dati, che è composta da diversi segmenti come definiti nella regione load-commands. **Una varietà di data sections può essere ospitata all'interno di ogni segmento**, con ogni sezione **contenente code or data** specifici di un tipo.
|
||||
|
||||
> [!TIP]
|
||||
> I dati sono fondamentalmente la parte che contiene tutte le **informazioni** che vengono caricate dai load commands **LC_SEGMENTS_64**
|
||||
|
||||
 (3).png>)
|
||||
|
||||
Questo include:
|
||||
|
||||
- **Tabella delle funzioni:** Che contiene informazioni sulle funzioni del programma.
|
||||
- **Tabella dei simboli**: Che contiene informazioni sulle funzioni esterne utilizzate dal binario
|
||||
- Potrebbe anche contenere nomi di funzioni interne, variabili e altro ancora.
|
||||
- **Function table:** Which holds information about the program functions.
|
||||
- **Symbol table**: Which contains information about the external function used by the binary
|
||||
- It could also contain internal function, variable names as well and more.
|
||||
|
||||
Per controllarlo puoi utilizzare lo strumento [**Mach-O View**](https://sourceforge.net/projects/machoview/):
|
||||
To check it you could use the [**Mach-O View**](https://sourceforge.net/projects/machoview/) tool:
|
||||
|
||||
<figure><img src="../../../images/image (1120).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
O dalla cli:
|
||||
Or from the cli:
|
||||
```bash
|
||||
size -m /bin/ls
|
||||
```
|
||||
## Sezioni Comuni di Objective-C
|
||||
## Objetive-C Sezioni comuni
|
||||
|
||||
In `__TEXT` segment (r-x):
|
||||
Nel segmento `__TEXT` (r-x):
|
||||
|
||||
- `__objc_classname`: Nomi delle classi (stringhe)
|
||||
- `__objc_methname`: Nomi dei metodi (stringhe)
|
||||
- `__objc_methtype`: Tipi di metodi (stringhe)
|
||||
- `__objc_methtype`: Tipi dei metodi (stringhe)
|
||||
|
||||
In `__DATA` segment (rw-):
|
||||
Nel segmento `__DATA` (rw-):
|
||||
|
||||
- `__objc_classlist`: Puntatori a tutte le classi Objective-C
|
||||
- `__objc_nlclslist`: Puntatori a classi Objective-C Non-Lazy
|
||||
- `__objc_catlist`: Puntatore a Categorie
|
||||
- `__objc_nlcatlist`: Puntatore a Categorie Non-Lazy
|
||||
- `__objc_classlist`: Puntatori a tutte le classi Objetive-C
|
||||
- `__objc_nlclslist`: Puntatori alle classi Objective-C Non-Lazy
|
||||
- `__objc_catlist`: Puntatore alle categorie
|
||||
- `__objc_nlcatlist`: Puntatore a categorie Non-Lazy
|
||||
- `__objc_protolist`: Elenco dei protocolli
|
||||
- `__objc_const`: Dati costanti
|
||||
- `__objc_imageinfo`, `__objc_selrefs`, `objc__protorefs`...
|
||||
|
@ -2,14 +2,19 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Informazioni di Base
|
||||
## Basic Information
|
||||
|
||||
I binari Mach-o contengono un comando di caricamento chiamato **`LC_CODE_SIGNATURE`** che indica l'**offset** e la **dimensione** delle firme all'interno del binario. In realtà, utilizzando lo strumento GUI MachOView, è possibile trovare alla fine del binario una sezione chiamata **Code Signature** con queste informazioni:
|
||||
{{#ref}}
|
||||
../../../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
I binari Mach-o contengono un load command chiamato **`LC_CODE_SIGNATURE`** che indica l'**offset** e la **size** delle signature all'interno del binario. In particolare, usando lo strumento GUI MachOView, è possibile trovare, alla fine del binario, una sezione chiamata **Code Signature** con queste informazioni:
|
||||
|
||||
<figure><img src="../../../images/image (1) (1) (1) (1).png" alt="" width="431"><figcaption></figcaption></figure>
|
||||
|
||||
L'intestazione magica della Code Signature è **`0xFADE0CC0`**. Poi hai informazioni come la lunghezza e il numero di blob del superBlob che le contiene.\
|
||||
È possibile trovare queste informazioni nel [codice sorgente qui](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L276):
|
||||
L'header magico della Code Signature è **`0xFADE0CC0`**. Seguono informazioni come la lunghezza e il numero di blob dello superBlob che li contiene.\
|
||||
È possibile trovare queste informazioni nel [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)));
|
||||
```
|
||||
I blob comuni contenuti sono Code Directory, Requirements e Entitlements e un Cryptographic Message Syntax (CMS).\
|
||||
Inoltre, nota come i dati codificati nei blob siano codificati in **Big Endian.**
|
||||
I blob comuni contenuti sono Code Directory, Requirements e Entitlements e una Cryptographic Message Syntax (CMS).\
|
||||
Nota inoltre che i dati codificati nei blob sono in **Big Endian.**
|
||||
|
||||
Inoltre, le firme possono essere staccate dai binari e memorizzate in `/var/db/DetachedSignatures` (utilizzato da iOS).
|
||||
Inoltre, le firme possono essere separate dai binari e memorizzate in `/var/db/DetachedSignatures` (usato da iOS).
|
||||
|
||||
## Code Directory Blob
|
||||
|
||||
È possibile trovare la dichiarazione del [Code Directory Blob nel codice](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L104):
|
||||
È possibile trovare la dichiarazione del [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)));
|
||||
```
|
||||
Nota che ci sono diverse versioni di questa struttura in cui quelle vecchie potrebbero contenere meno informazioni.
|
||||
Nota che esistono diverse versioni di questa struct; quelle più vecchie potrebbero contenere meno informazioni.
|
||||
|
||||
## Pagine di Firma del Codice
|
||||
## Firma delle pagine di codice
|
||||
|
||||
Hashare l'intero binario sarebbe inefficiente e persino inutile se viene caricato in memoria solo parzialmente. Pertanto, la firma del codice è in realtà un hash di hash in cui ogni pagina binaria è hashata individualmente.\
|
||||
In effetti, nel precedente codice **Code Directory** puoi vedere che **la dimensione della pagina è specificata** in uno dei suoi campi. Inoltre, se la dimensione del binario non è un multiplo della dimensione di una pagina, il campo **CodeLimit** specifica dove si trova la fine della firma.
|
||||
Calcolare l'hash dell'intero binario sarebbe inefficiente e persino inutile se viene caricato solo parzialmente in memoria. Pertanto, la firma del codice è in realtà un hash di hash in cui ogni pagina del binario viene hashata individualmente.\
|
||||
In realtà, nel precedente codice **Code Directory** puoi vedere che la **dimensione della pagina è specificata** in uno dei suoi campi. Inoltre, se la dimensione del binario non è un multiplo della dimensione di una pagina, il campo **CodeLimit** specifica dove termina la firma.
|
||||
```bash
|
||||
# Get all hashes of /bin/ps
|
||||
codesign -d -vvvvvv /bin/ps
|
||||
@ -142,27 +147,27 @@ dd if=$BINARY of=/tmp/`basename $BINARY`.page.$i bs=$PAGESIZE skip=$i count=1
|
||||
done
|
||||
openssl sha256 /tmp/*.page.*
|
||||
```
|
||||
## Entitlements Blob
|
||||
## Blob degli entitlements
|
||||
|
||||
Nota che le applicazioni potrebbero contenere anche un **entitlement blob** dove sono definiti tutti i diritti. Inoltre, alcuni binari iOS potrebbero avere i loro diritti specifici nello slot speciale -7 (invece che nello slot speciale -5 dei diritti).
|
||||
Nota che le applicazioni potrebbero anche contenere un **entitlement blob** dove tutti gli entitlements sono definiti. Inoltre, alcuni binari iOS potrebbero avere i loro entitlements specificati nello special slot -7 (invece che nello special slot -5 per gli entitlements).
|
||||
|
||||
## Special Slots
|
||||
## Slot speciali
|
||||
|
||||
Le applicazioni MacOS non hanno tutto ciò di cui hanno bisogno per eseguire all'interno del binario, ma utilizzano anche **risorse esterne** (di solito all'interno del **bundle** delle applicazioni). Pertanto, ci sono alcuni slot all'interno del binario che conterranno gli hash di alcune risorse esterne interessanti per verificare che non siano state modificate.
|
||||
Le applicazioni MacOS non contengono tutto il necessario per l'esecuzione all'interno del binario, ma usano anche **external resources** (di solito all'interno del **bundle** dell'applicazione). Pertanto, ci sono alcuni slot nel binario che conterranno gli hash di alcune risorse esterne interessanti per verificare che non siano state modificate.
|
||||
|
||||
In realtà, è possibile vedere nelle strutture del Code Directory un parametro chiamato **`nSpecialSlots`** che indica il numero degli slot speciali. Non esiste uno slot speciale 0 e i più comuni (da -1 a -6) sono:
|
||||
In effetti, è possibile vedere nelle strutture Code Directory un parametro chiamato **`nSpecialSlots`** che indica il numero di special slots. Non esiste uno special slot 0 e i più comuni (da -1 a -6) sono:
|
||||
|
||||
- Hash di `info.plist` (o quello all'interno di `__TEXT.__info__plist`).
|
||||
- Hash dei Requisiti
|
||||
- Hash di `info.plist` (o di quello dentro `__TEXT.__info__plist`).
|
||||
- Hash dei Requirements
|
||||
- Hash della Resource Directory (hash del file `_CodeSignature/CodeResources` all'interno del bundle).
|
||||
- Specifico per l'applicazione (non utilizzato)
|
||||
- Hash dei diritti
|
||||
- Solo firme di codice DMG
|
||||
- Diritti DER
|
||||
- Specifico dell'applicazione (non usato)
|
||||
- Hash degli entitlements
|
||||
- Solo per le code signatures dei DMG
|
||||
- DER Entitlements
|
||||
|
||||
## Code Signing Flags
|
||||
## Flag di code signing
|
||||
|
||||
Ogni processo ha associato un bitmask noto come `status` che è avviato dal kernel e alcuni di essi possono essere sovrascritti dalla **firma del codice**. Queste bandiere che possono essere incluse nella firma del codice sono [definite nel codice](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L36):
|
||||
Ogni processo ha associata una bitmask nota come `status` che è impostata dal kernel e alcune di esse possono essere sovrascritte dalla **code signature**. Questi flag che possono essere inclusi nella code signing sono [definiti nel codice](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)
|
||||
```
|
||||
Nota che la funzione [**exec_mach_imgact**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_exec.c#L1420) può anche aggiungere dinamicamente i flag `CS_EXEC_*` all'avvio dell'esecuzione.
|
||||
Nota che la funzione [**exec_mach_imgact**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_exec.c#L1420) può anche aggiungere i flag `CS_EXEC_*` dinamicamente quando viene avviata l'esecuzione.
|
||||
|
||||
## Requisiti di Firma del Codice
|
||||
## Requisiti della firma del codice
|
||||
|
||||
Ogni applicazione memorizza alcuni **requisiti** che deve **soddisfare** per poter essere eseguita. Se i **requisiti dell'applicazione non sono soddisfatti dall'applicazione**, non verrà eseguita (poiché è probabilmente stata alterata).
|
||||
Ogni applicazione memorizza alcune **requirements** che deve **soddisfare** per poter essere eseguita. Se le **requirements** contenute nell'applicazione non sono soddisfatte, non verrà eseguita (poiché probabilmente è stata alterata).
|
||||
|
||||
I requisiti di un binario utilizzano una **grammatica speciale** che è un flusso di **espressioni** e sono codificati come blob utilizzando `0xfade0c00` come magic, il cui **hash è memorizzato in uno slot di codice speciale**.
|
||||
Le requirements di un binario usano una grammatica speciale che è uno stream di **expressions** e sono codificate come blob usando `0xfade0c00` come magic il cui **hash è memorizzato in uno special code slot**.
|
||||
|
||||
I requisiti di un binario possono essere visualizzati eseguendo:
|
||||
Le requirements di un binario possono essere visualizzate eseguendo:
|
||||
```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]
|
||||
> Nota come queste firme possano controllare informazioni come certificazione, TeamID, ID, diritti e molti altri dati.
|
||||
> [!TIP]
|
||||
> Nota come queste firme possono controllare elementi come le informazioni sul certificato, TeamID, IDs, entitlements e molti altri dati.
|
||||
|
||||
Inoltre, è possibile generare alcuni requisiti compilati utilizzando lo strumento `csreq`:
|
||||
Inoltre, è possibile generare alcuni requisiti compilati usando lo strumento `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
|
||||
[...]
|
||||
```
|
||||
È possibile accedere a queste informazioni e creare o modificare requisiti con alcune API del `Security.framework` come:
|
||||
È possibile accedere a queste informazioni e creare o modificare i requisiti con alcune API di `Security.framework`, ad esempio:
|
||||
|
||||
#### **Controllo della Validità**
|
||||
#### **Verifica della validità**
|
||||
|
||||
- **`Sec[Static]CodeCheckValidity`**: Controlla la validità di SecCodeRef per Requisito.
|
||||
- **`SecRequirementEvaluate`**: Valida il requisito nel contesto del certificato.
|
||||
- **`SecTaskValidateForRequirement`**: Valida un SecTask in esecuzione contro il requisito `CFString`.
|
||||
- **`Sec[Static]CodeCheckValidity`**: Check the validity of SecCodeRef per Requirement.
|
||||
- **`SecRequirementEvaluate`**: Validate requirement in certificate context
|
||||
- **`SecTaskValidateForRequirement`**: Validate a running SecTask against `CFString` requirement.
|
||||
|
||||
#### **Creazione e Gestione dei Requisiti di Codice**
|
||||
#### **Creazione e gestione dei requirement di codice**
|
||||
|
||||
- **`SecRequirementCreateWithData`:** Crea un `SecRequirementRef` da dati binari che rappresentano il requisito.
|
||||
- **`SecRequirementCreateWithString`:** Crea un `SecRequirementRef` da un'espressione stringa del requisito.
|
||||
- **`SecRequirementCopy[Data/String]`**: Recupera la rappresentazione dei dati binari di un `SecRequirementRef`.
|
||||
- **`SecRequirementCreateGroup`**: Crea un requisito per l'appartenenza al gruppo di app.
|
||||
- **`SecRequirementCreateWithData`:** Creates a `SecRequirementRef` from binary data representing the requirement.
|
||||
- **`SecRequirementCreateWithString`:** Creates a `SecRequirementRef` from a string expression of the requirement.
|
||||
- **`SecRequirementCopy[Data/String]`**: Retrieves the binary data representation of a `SecRequirementRef`.
|
||||
- **`SecRequirementCreateGroup`**: Create a requirement for app-group membership
|
||||
|
||||
#### **Accesso alle Informazioni di Firma del Codice**
|
||||
#### **Accesso alle informazioni sulla firma del codice**
|
||||
|
||||
- **`SecStaticCodeCreateWithPath`**: Inizializza un oggetto `SecStaticCodeRef` da un percorso del file system per ispezionare le firme del codice.
|
||||
- **`SecCodeCopySigningInformation`**: Ottiene informazioni di firma da un `SecCodeRef` o `SecStaticCodeRef`.
|
||||
- **`SecStaticCodeCreateWithPath`**: Initializes a `SecStaticCodeRef` object from a file system path for inspecting code signatures.
|
||||
- **`SecCodeCopySigningInformation`**: Obtains signing information from a `SecCodeRef` or `SecStaticCodeRef`.
|
||||
|
||||
#### **Modifica dei Requisiti di Codice**
|
||||
#### **Modifica dei requirement di codice**
|
||||
|
||||
- **`SecCodeSignerCreate`**: Crea un oggetto `SecCodeSignerRef` per eseguire operazioni di firma del codice.
|
||||
- **`SecCodeSignerSetRequirement`**: Imposta un nuovo requisito per il firmatario del codice da applicare durante la firma.
|
||||
- **`SecCodeSignerAddSignature`**: Aggiunge una firma al codice in fase di firma con il firmatario specificato.
|
||||
- **`SecCodeSignerCreate`**: Creates a `SecCodeSignerRef` object for performing code signing operations.
|
||||
- **`SecCodeSignerSetRequirement`**: Sets a new requirement for the code signer to apply during signing.
|
||||
- **`SecCodeSignerAddSignature`**: Adds a signature to the code being signed with the specified signer.
|
||||
|
||||
#### **Validazione del Codice con Requisiti**
|
||||
#### **Validazione del codice con i requirement**
|
||||
|
||||
- **`SecStaticCodeCheckValidity`**: Valida un oggetto di codice statico contro requisiti specificati.
|
||||
- **`SecStaticCodeCheckValidity`**: Validates a static code object against specified requirements.
|
||||
|
||||
#### **API Utili Aggiuntive**
|
||||
#### **Altre API utili**
|
||||
|
||||
- **`SecCodeCopy[Internal/Designated]Requirement`: Ottieni SecRequirementRef da SecCodeRef**
|
||||
- **`SecCodeCopyGuestWithAttributes`**: Crea un `SecCodeRef` che rappresenta un oggetto di codice basato su attributi specifici, utile per il sandboxing.
|
||||
- **`SecCodeCopyPath`**: Recupera il percorso del file system associato a un `SecCodeRef`.
|
||||
- **`SecCodeCopySigningIdentifier`**: Ottiene l'identificatore di firma (ad es., Team ID) da un `SecCodeRef`.
|
||||
- **`SecCodeGetTypeID`**: Restituisce l'identificatore di tipo per oggetti `SecCodeRef`.
|
||||
- **`SecRequirementGetTypeID`**: Ottiene un CFTypeID di un `SecRequirementRef`.
|
||||
- **`SecCodeCopy[Internal/Designated]Requirement`: Get SecRequirementRef from SecCodeRef**
|
||||
- **`SecCodeCopyGuestWithAttributes`**: Creates a `SecCodeRef` representing a code object based on specific attributes, useful for sandboxing.
|
||||
- **`SecCodeCopyPath`**: Retrieves the file system path associated with a `SecCodeRef`.
|
||||
- **`SecCodeCopySigningIdentifier`**: Obtains the signing identifier (e.g., Team ID) from a `SecCodeRef`.
|
||||
- **`SecCodeGetTypeID`**: Returns the type identifier for `SecCodeRef` objects.
|
||||
- **`SecRequirementGetTypeID`**: Gets a CFTypeID of a `SecRequirementRef`
|
||||
|
||||
#### **Flag e Costanti di Firma del Codice**
|
||||
#### **Flag e costanti per la firma del codice**
|
||||
|
||||
- **`kSecCSDefaultFlags`**: Flag predefiniti utilizzati in molte funzioni del Security.framework per operazioni di firma del codice.
|
||||
- **`kSecCSSigningInformation`**: Flag utilizzato per specificare che le informazioni di firma devono essere recuperate.
|
||||
- **`kSecCSDefaultFlags`**: Default flags used in many Security.framework functions for code signing operations.
|
||||
- **`kSecCSSigningInformation`**: Flag used to specify that signing information should be retrieved.
|
||||
|
||||
## Applicazione della Firma del Codice
|
||||
## Applicazione della firma del codice
|
||||
|
||||
Il **kernel** è quello che **controlla la firma del codice** prima di consentire l'esecuzione del codice dell'app. Inoltre, un modo per poter scrivere ed eseguire in memoria nuovo codice è abusare di JIT se `mprotect` viene chiamato con il flag `MAP_JIT`. Nota che l'applicazione ha bisogno di un diritto speciale per poter fare questo.
|
||||
Il **kernel** è colui che **verifica la firma del codice** prima di permettere l'esecuzione del codice dell'app. Inoltre, un modo per poter scrivere ed eseguire in memoria nuovo codice è abusare del JIT se `mprotect` viene chiamato con il flag `MAP_JIT`. Nota che l'applicazione necessita di un entitlement speciale per poterlo fare.
|
||||
|
||||
## `cs_blobs` & `cs_blob`
|
||||
|
||||
[**cs_blob**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/ubc_internal.h#L106) la struct contiene le informazioni sui diritti dell'entitlement del processo in esecuzione su di esso. `csb_platform_binary` informa anche se l'applicazione è un binario di piattaforma (che viene controllato in momenti diversi dal sistema operativo per applicare meccanismi di sicurezza come proteggere i diritti SEND ai porti di task di questi processi).
|
||||
[**cs_blob**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/ubc_internal.h#L106) struct contiene le informazioni sugli entitlement del processo in esecuzione. `csb_platform_binary` informa inoltre se l'applicazione è una platform binary (che viene verificato in momenti diversi dal sistema operativo per applicare meccanismi di sicurezza, ad esempio per proteggere i diritti SEND sulle task ports di questi processi).
|
||||
```c
|
||||
struct cs_blob {
|
||||
struct cs_blob *csb_next;
|
||||
|
Loading…
x
Reference in New Issue
Block a user