mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/generic-methodologies-and-resources/basic-forensic-meth
This commit is contained in:
parent
08f0721ceb
commit
0ab0b46aee
@ -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 @@
|
||||
# Spezielle Software-/Dateityp-Tricks
|
||||
# Spezielle Tricks für bestimmte Software/Dateitypen
|
||||
|
||||
{{#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}}
|
||||
|
||||
## Overview
|
||||
|
||||
Diese Seite erklärt, wie man Entitlements aus Mach-O-Binaries programmatisch extrahiert, indem man den LC_CODE_SIGNATURE durchläuft und den Code-Signing SuperBlob parst, und wie man das auf Apple IPSW-Firmwares skaliert, indem man deren Inhalte einhängt und für forensische Suche/Unterschiedsanalysen indexiert.
|
||||
|
||||
If you need a refresher on Mach-O format and code signing, see also: 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
|
||||
|
||||
Entitlements werden in den Code-Signatur-Daten gespeichert, auf die der LC_CODE_SIGNATURE load command verweist, und im __LINKEDIT-Segment platziert. Die Signatur ist ein CS_SuperBlob, das mehrere Blobs enthält (code directory, requirements, entitlements, CMS, etc.). Der Entitlements-Blob ist ein CS_GenericBlob, dessen Daten eine Apple Binary Property List (bplist00) sind, die Entitlement-Schlüssel auf Werte abbildet.
|
||||
|
||||
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;
|
||||
```
|
||||
Wichtige Konstanten:
|
||||
- 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
|
||||
|
||||
Hinweis: 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.
|
||||
|
||||
|
||||
## Extraktionsschritte (generisch, hinreichend verlustfrei)
|
||||
|
||||
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.
|
||||
|
||||
Implementierungs-Hinweise:
|
||||
- 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:
|
||||
- Um mit fat binaries umzugehen, lesen Sie zuerst struct fat_header/fat_arch, wählen Sie den gewünschten Architektur-Slice und übergeben Sie dann den Subrange an parse_entitlements.
|
||||
- Unter macOS können Sie die Ergebnisse mit folgendem Befehl validieren: codesign -d --entitlements :- /path/to/binary
|
||||
|
||||
|
||||
## Beispielbefunde
|
||||
|
||||
Privilegierte platform binaries verlangen häufig sensible entitlements wie:
|
||||
- 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"]
|
||||
|
||||
Diese großflächige Suche über Firmware-Images hinweg ist äußerst wertvoll für attack surface mapping und diffing zwischen Releases/Geräten.
|
||||
|
||||
|
||||
## Skalierung über IPSWs (Mounten und Indexierung)
|
||||
|
||||
Um ausführbare Dateien aufzulisten und entitlements großflächig zu extrahieren, ohne vollständige Images zu speichern:
|
||||
|
||||
- Verwenden Sie das ipsw tool von @blacktop, um Firmware-Dateisysteme herunterzuladen und zu mounten. Das Mounten nutzt apfs-fuse, sodass Sie APFS-Volumes durchsuchen können, ohne eine vollständige Extraktion.
|
||||
```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>
|
||||
```
|
||||
- Durchsuche eingehängte Volumes, um Mach-O-Dateien zu finden (prüfe magic und/oder verwende file/otool), parse anschließend entitlements und importierte frameworks.
|
||||
- Speichere eine normalisierte Ansicht in einer relationalen Datenbank, um lineares Wachstum über tausende von IPSWs zu vermeiden:
|
||||
- executables, operating_system_versions, entitlements, frameworks
|
||||
- Viele-zu-viele: executable↔OS version, executable↔entitlement, executable↔framework
|
||||
|
||||
Beispielabfrage, um alle OS-Versionen aufzulisten, die einen bestimmten executable-Namen enthalten:
|
||||
```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";
|
||||
```
|
||||
Hinweise zur DB-Portabilität (falls du deinen eigenen Indexer implementierst):
|
||||
- Verwende ein ORM/Abstraktionslayer (z. B. SeaORM), um den Code DB-agnostisch zu halten (SQLite/PostgreSQL).
|
||||
- SQLite benötigt AUTOINCREMENT nur bei einem INTEGER PRIMARY KEY; wenn du i64 PKs in Rust möchtest, generiere Entitäten als i32 und konvertiere die Typen — SQLite speichert INTEGER intern als 8-Byte signed.
|
||||
|
||||
|
||||
## Open-source tooling and references for entitlement hunting
|
||||
|
||||
- Firmware mount/download: https://github.com/blacktop/ipsw
|
||||
- Entitlement-Datenbanken und Referenzen:
|
||||
- Jonathan Levin’s entitlement DB: https://newosxbook.com/ent.php
|
||||
- entdb: https://github.com/ChiChou/entdb
|
||||
- Großskaliger Indexer (Rust, self-hosted Web UI + OpenAPI): https://github.com/synacktiv/appledb_rs
|
||||
- Apple-Header für Strukturen und Konstanten:
|
||||
- loader.h (Mach-O headers, load commands)
|
||||
- cs_blobs.h (SuperBlob, GenericBlob, CodeDirectory)
|
||||
|
||||
Für mehr zu den Interna des Code-Signings (Code Directory, special slots, DER entitlements), siehe: [macOS Code Signing](../../../macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md)
|
||||
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [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 Universal binaries & Mach-O Format
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Grundinformationen
|
||||
## Grundlegende Informationen
|
||||
|
||||
Mac OS-Binaries werden normalerweise als **universelle Binaries** kompiliert. Ein **universelles Binary** kann **mehrere Architekturen in derselben Datei unterstützen**.
|
||||
Mac OS binaries werden normalerweise als **universal binaries** kompiliert. Eine **universal binary** kann **mehrere Architekturen in derselben Datei unterstützen**.
|
||||
|
||||
Diese Binaries folgen der **Mach-O-Struktur**, die im Wesentlichen aus besteht:
|
||||
Diese binaries folgen der **Mach-O-Struktur**, die im Wesentlichen aus folgenden Teilen besteht:
|
||||
|
||||
- Header
|
||||
- Ladebefehle
|
||||
- Daten
|
||||
- Load Commands
|
||||
- Data
|
||||
|
||||
.png>)
|
||||
|
||||
## Fat Header
|
||||
## Fat-Header
|
||||
|
||||
Suchen Sie die Datei mit: `mdfind fat.h | grep -i mach-o | grep -E "fat.h$"`
|
||||
Nach der Datei suchen mit: `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 oder FAT_MAGIC_64 */
|
||||
</strong><strong> uint32_t nfat_arch; /* Anzahl der folgenden Strukturen */
|
||||
<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; /* CPU-Spezifizierer (int) */
|
||||
cpu_subtype_t cpusubtype; /* Maschinen-Spezifizierer (int) */
|
||||
uint32_t offset; /* Dateiverschiebung zu dieser Objektdatei */
|
||||
uint32_t size; /* Größe dieser Objektdatei */
|
||||
uint32_t align; /* Ausrichtung als Potenz von 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>
|
||||
|
||||
Der Header enthält die **magischen** Bytes, gefolgt von der **Anzahl** der **Architekturen**, die die Datei **enthält** (`nfat_arch`), und jede Architektur hat eine `fat_arch`-Struktur.
|
||||
Der Header enthält die **magic**-Bytes, gefolgt von der **Anzahl** der **archs**, die die Datei **enthält** (`nfat_arch`), und jede arch hat eine `fat_arch`-Struktur.
|
||||
|
||||
Überprüfen Sie es mit:
|
||||
Prüfe das mit:
|
||||
|
||||
<pre class="language-shell-session"><code class="lang-shell-session">% file /bin/ls
|
||||
/bin/ls: Mach-O universelles Binary mit 2 Architekturen: [x86_64:Mach-O 64-Bit ausführbar x86_64] [arm64e:Mach-O 64-Bit ausführbar arm64e]
|
||||
/bin/ls (für Architektur x86_64): Mach-O 64-Bit ausführbar x86_64
|
||||
/bin/ls (für Architektur arm64e): Mach-O 64-Bit ausführbar 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-Header
|
||||
Fat headers
|
||||
fat_magic FAT_MAGIC
|
||||
<strong>nfat_arch 2
|
||||
</strong><strong>architektur 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>architektur 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>
|
||||
|
||||
oder mit dem [Mach-O View](https://sourceforge.net/projects/machoview/) Tool:
|
||||
oder mit dem Tool [Mach-O View](https://sourceforge.net/projects/machoview/):
|
||||
|
||||
<figure><img src="../../../images/image (1094).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Wie Sie vielleicht denken, verdoppelt ein universelles Binary, das für 2 Architekturen kompiliert wurde, normalerweise die Größe eines, das nur für 1 Architektur kompiliert wurde.
|
||||
Wie du dir vielleicht denkst, verdoppelt eine universal binary, die für 2 Architekturen kompiliert wurde, in der Regel die Größe im Vergleich zu einer, die nur für eine Arch kompiliert wurde.
|
||||
|
||||
## **Mach-O Header**
|
||||
## **Mach-O-Header**
|
||||
|
||||
Der Header enthält grundlegende Informationen über die Datei, wie magische Bytes, um sie als Mach-O-Datei zu identifizieren, und Informationen über die Zielarchitektur. Sie finden es unter: `mdfind loader.h | grep -i mach-o | grep -E "loader.h$"`
|
||||
Der Header enthält grundlegende Informationen über die Datei, wie z. B. magic-Bytes zur Identifikation als Mach-O-Datei und Informationen über die Zielarchitektur. Du findest ihn unter: `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,16 +101,16 @@ uint32_t reserved; /* reserved */
|
||||
```
|
||||
### Mach-O-Dateitypen
|
||||
|
||||
Es gibt verschiedene Dateitypen, die in dem [**Quellcode zum Beispiel hier**](https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h) definiert sind. Die wichtigsten sind:
|
||||
Es gibt verschiedene Dateitypen; sie sind im [**source code for example here**](https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h) definiert. Die wichtigsten sind:
|
||||
|
||||
- `MH_OBJECT`: Umsetzbare Objektdatei (Zwischenprodukte der Kompilierung, noch keine ausführbaren Dateien).
|
||||
- `MH_OBJECT`: Relokierbare Objektdatei (Zwischenprodukt der Kompilierung, noch keine ausführbare Datei).
|
||||
- `MH_EXECUTE`: Ausführbare Dateien.
|
||||
- `MH_FVMLIB`: Feste VM-Bibliotheksdatei.
|
||||
- `MH_CORE`: Code-Dumps
|
||||
- `MH_PRELOAD`: Vorgelegte ausführbare Datei (wird in XNU nicht mehr unterstützt)
|
||||
- `MH_FVMLIB`: Fixed-VM-Bibliotheksdatei.
|
||||
- `MH_CORE`: Core-Dumps
|
||||
- `MH_PRELOAD`: Vorausgeladene ausführbare Datei (wird in XNU nicht mehr unterstützt)
|
||||
- `MH_DYLIB`: Dynamische Bibliotheken
|
||||
- `MH_DYLINKER`: Dynamischer Linker
|
||||
- `MH_BUNDLE`: "Plugin-Dateien". Generiert mit -bundle in gcc und explizit geladen von `NSBundle` oder `dlopen`.
|
||||
- `MH_BUNDLE`: "Plugin-Dateien". Erzeugt mit -bundle in gcc und explizit geladen durch `NSBundle` oder `dlopen`.
|
||||
- `MH_DYSM`: Begleitende `.dSym`-Datei (Datei mit Symbolen für das Debugging).
|
||||
- `MH_KEXT_BUNDLE`: Kernel-Erweiterungen.
|
||||
```bash
|
||||
@ -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
|
||||
```
|
||||
Oder verwenden Sie [Mach-O View](https://sourceforge.net/projects/machoview/):
|
||||
Oder mit [Mach-O View](https://sourceforge.net/projects/machoview/):
|
||||
|
||||
<figure><img src="../../../images/image (1133).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## **Mach-O-Flags**
|
||||
|
||||
Der Quellcode definiert auch mehrere Flags, die nützlich sind, um Bibliotheken zu laden:
|
||||
Der Quellcode definiert außerdem mehrere Flags, die beim Laden von Libraries nützlich sind:
|
||||
|
||||
- `MH_NOUNDEFS`: Keine undefinierten Referenzen (vollständig verlinkt)
|
||||
- `MH_DYLDLINK`: Dyld-Verlinkung
|
||||
- `MH_NOUNDEFS`: Keine undefinierten Referenzen (fully linked)
|
||||
- `MH_DYLDLINK`: Dyld-Linking
|
||||
- `MH_PREBOUND`: Dynamische Referenzen vorgebunden.
|
||||
- `MH_SPLIT_SEGS`: Datei teilt r/o und r/w Segmente.
|
||||
- `MH_WEAK_DEFINES`: Binärdatei hat schwach definierte Symbole
|
||||
- `MH_BINDS_TO_WEAK`: Binärdatei verwendet schwache Symbole
|
||||
- `MH_ALLOW_STACK_EXECUTION`: Machen Sie den Stack ausführbar
|
||||
- `MH_NO_REEXPORTED_DYLIBS`: Bibliothek hat keine LC_REEXPORT-Befehle
|
||||
- `MH_PIE`: Positionsunabhängige ausführbare Datei
|
||||
- `MH_HAS_TLV_DESCRIPTORS`: Es gibt einen Abschnitt mit thread-lokalen Variablen
|
||||
- `MH_NO_HEAP_EXECUTION`: Keine Ausführung für Heap/Daten-Seiten
|
||||
- `MH_HAS_OBJC`: Binärdatei hat oBject-C-Abschnitte
|
||||
- `MH_SIM_SUPPORT`: Simulatorunterstützung
|
||||
- `MH_DYLIB_IN_CACHE`: Wird bei dylibs/Frameworks im gemeinsamen Bibliothekscache verwendet.
|
||||
- `MH_SPLIT_SEGS`: Datei teilt r/o- und r/w-Segmente.
|
||||
- `MH_WEAK_DEFINES`: Binary hat schwach definierte Symbole
|
||||
- `MH_BINDS_TO_WEAK`: Binary verwendet schwache Symbole
|
||||
- `MH_ALLOW_STACK_EXECUTION`: Macht den Stack ausführbar
|
||||
- `MH_NO_REEXPORTED_DYLIBS`: Library hat keine LC_REEXPORT-Kommandos
|
||||
- `MH_PIE`: Positionsunabhängiges ausführbares Programm (PIE)
|
||||
- `MH_HAS_TLV_DESCRIPTORS`: Es gibt einen Abschnitt mit thread-localen Variablen
|
||||
- `MH_NO_HEAP_EXECUTION`: Keine Ausführung für Heap-/Daten-Seiten
|
||||
- `MH_HAS_OBJC`: Binary hat Objective-C-Abschnitte
|
||||
- `MH_SIM_SUPPORT`: Simulator-Unterstützung
|
||||
- `MH_DYLIB_IN_CACHE`: Wird für dylibs/frameworks im shared library cache verwendet.
|
||||
|
||||
## **Mach-O-Ladebefehle**
|
||||
## **Mach-O Load commands**
|
||||
|
||||
Das **Layout der Datei im Speicher** wird hier spezifiziert, wobei der **Standort der Symboltabelle**, der Kontext des Hauptthreads beim Start der Ausführung und die erforderlichen **gemeinsamen Bibliotheken** detailliert beschrieben werden. Anweisungen werden dem dynamischen Loader **(dyld)** zum Ladeprozess der Binärdatei in den Speicher bereitgestellt.
|
||||
Hier wird das **Speicherlayout der Datei** festgelegt, mit Angaben zur **Position der Symboltabelle**, zum Kontext des Hauptthreads beim Start der Ausführung und zu den benötigten **shared libraries**. Es enthält Anweisungen an den dynamic loader **(dyld)**, wie das Binary in den Speicher geladen werden soll.
|
||||
|
||||
Es verwendet die **load_command**-Struktur, die in der erwähnten **`loader.h`** definiert ist:
|
||||
Dabei wird die Struktur **load_command** verwendet, definiert in der genannten **`loader.h`**:
|
||||
```objectivec
|
||||
struct load_command {
|
||||
uint32_t cmd; /* type of load command */
|
||||
uint32_t cmdsize; /* total size of command in bytes */
|
||||
};
|
||||
```
|
||||
Es gibt etwa **50 verschiedene Arten von Load Commands**, die das System unterschiedlich behandelt. Die häufigsten sind: `LC_SEGMENT_64`, `LC_LOAD_DYLINKER`, `LC_MAIN`, `LC_LOAD_DYLIB` und `LC_CODE_SIGNATURE`.
|
||||
Es gibt etwa **50 verschiedene Typen von Load Commands**, die das System unterschiedlich behandelt. Die gebräuchlichsten sind: `LC_SEGMENT_64`, `LC_LOAD_DYLINKER`, `LC_MAIN`, `LC_LOAD_DYLIB` und `LC_CODE_SIGNATURE`.
|
||||
|
||||
### **LC_SEGMENT/LC_SEGMENT_64**
|
||||
|
||||
> [!TIP]
|
||||
> Grundsätzlich definiert dieser Typ von Load Command **wie man die \_\_TEXT** (ausführbarer Code) **und \_\_DATA** (Daten für den Prozess) **Segmente** gemäß den **Offsets, die im Datenbereich angegeben sind**, wenn die Binärdatei ausgeführt wird.
|
||||
> Im Grunde definiert dieser Typ von Load Command, **wie die __TEXT** (ausführbarer Code) **und die __DATA** (Daten für den Prozess) **Segmente** entsprechend den **Offsets, die im Datenabschnitt angegeben sind**, beim Ausführen des Binaries geladen werden.
|
||||
|
||||
Diese Befehle **definieren Segmente**, die in den **virtuellen Adressraum** eines Prozesses gemappt werden, wenn er ausgeführt wird.
|
||||
Diese Befehle **definieren Segmente**, die beim Ausführen in den **virtuellen Adressraum** eines Prozesses **gemappt** werden.
|
||||
|
||||
Es gibt **verschiedene Arten** von Segmenten, wie das **\_\_TEXT**-Segment, das den ausführbaren Code eines Programms enthält, und das **\_\_DATA**-Segment, das Daten enthält, die vom Prozess verwendet werden. Diese **Segmente befinden sich im Datenbereich** der Mach-O-Datei.
|
||||
Es gibt **verschiedene Typen** von Segmenten, wie das **\_\_TEXT**-Segment, das den ausführbaren Code eines Programms enthält, und das **\_\_DATA**-Segment, das die vom Prozess verwendeten Daten enthält. Diese **Segmente befinden sich im Datenabschnitt** der Mach-O-Datei.
|
||||
|
||||
**Jedes Segment** kann weiter in mehrere **Sektionen** **unterteilt** werden. Die **Struktur des Load Commands** enthält **Informationen** über **diese Sektionen** innerhalb des jeweiligen Segments.
|
||||
**Jedes Segment** kann weiter in mehrere **Sections** unterteilt werden. Die **Load Command-Struktur** enthält **Informationen** über **diese Sections** innerhalb des jeweiligen Segments.
|
||||
|
||||
Im Header finden Sie zuerst den **Segment-Header**:
|
||||
Im Header findet man zuerst den **Segment-Header**:
|
||||
|
||||
<pre class="language-c"><code class="lang-c">struct segment_command_64 { /* für 64-Bit-Architekturen */
|
||||
<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; /* umfasst sizeof section_64 Strukturen */
|
||||
char segname[16]; /* Segmentname */
|
||||
uint64_t vmaddr; /* Speicheradresse dieses Segments */
|
||||
uint64_t vmsize; /* Speichergröße dieses Segments */
|
||||
uint64_t fileoff; /* Dateiverschiebung dieses Segments */
|
||||
uint64_t filesize; /* Menge, die aus der Datei gemappt werden soll */
|
||||
int32_t maxprot; /* maximale VM-Schutz */
|
||||
int32_t initprot; /* anfänglicher VM-Schutz */
|
||||
<strong> uint32_t nsects; /* Anzahl der Sektionen im Segment */
|
||||
</strong> uint32_t flags; /* 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>
|
||||
|
||||
Beispiel eines Segment-Headers:
|
||||
Beispiel für einen Segment-Header:
|
||||
|
||||
<figure><img src="../../../images/image (1126).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Dieser Header definiert die **Anzahl der Sektionen, deren Header danach erscheinen**:
|
||||
Dieser Header legt die **Anzahl der Sections fest, deren Header danach erscheinen**:
|
||||
```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 */
|
||||
};
|
||||
```
|
||||
Beispiel für **Abschnittsüberschrift**:
|
||||
Beispiel für **section header**:
|
||||
|
||||
<figure><img src="../../../images/image (1108).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Wenn Sie den **Abschnittsversatz** (0x37DC) + den **Versatz**, wo der **Arch beginnt**, in diesem Fall `0x18000` hinzufügen --> `0x37DC + 0x18000 = 0x1B7DC`
|
||||
Wenn du den **section offset** (0x37DC) + den **offset**, an dem die **arch** beginnt, in diesem Fall `0x18000` --> `0x37DC + 0x18000 = 0x1B7DC`
|
||||
|
||||
<figure><img src="../../../images/image (701).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Es ist auch möglich, **Header-Informationen** über die **Befehlszeile** zu erhalten mit:
|
||||
Man kann **headers information** auch über die **command line** bekommen mit:
|
||||
```bash
|
||||
otool -lv /bin/ls
|
||||
```
|
||||
Häufige Segmente, die von diesem Befehl geladen werden:
|
||||
Common segments loaded by this cmd:
|
||||
|
||||
- **`__PAGEZERO`:** Es weist den Kernel an, die **Adresse null** zu **mappen**, sodass sie **nicht gelesen, beschrieben oder ausgeführt** werden kann. Die Variablen maxprot und minprot in der Struktur sind auf null gesetzt, um anzuzeigen, dass es **keine Lese-, Schreib- oder Ausführungsrechte auf dieser Seite** gibt.
|
||||
- Diese Zuweisung ist wichtig, um **NULL-Zeiger-Dereferenzierungsanfälligkeiten** zu **mildern**. Dies liegt daran, dass XNU eine harte Seite null durchsetzt, die sicherstellt, dass die erste Seite (nur die erste) des Speichers unzugänglich ist (außer in i386). Ein Binärprogramm könnte diese Anforderungen erfüllen, indem es eine kleine \_\_PAGEZERO erstellt (unter Verwendung von `-pagezero_size`), um die ersten 4k abzudecken und den Rest des 32-Bit-Speichers sowohl im Benutzer- als auch im Kernelmodus zugänglich zu machen.
|
||||
- **`__TEXT`**: Enthält **ausführbaren** **Code** mit **Lese-** und **Ausführungsberechtigungen** (kein schreibbarer)**.** Häufige Abschnitte dieses Segments:
|
||||
- **`__PAGEZERO`:** Es veranlasst den Kernel, die Adresse Null abzubilden, sodass von ihr weder gelesen, geschrieben noch ausgeführt werden kann. Die maxprot- und minprot-Variablen in der Struktur sind auf Null gesetzt, um anzuzeigen, dass es auf dieser Seite **keine Lese-/Schreib-/Ausführungsrechte** gibt.
|
||||
- Diese Allokation ist wichtig, um **NULL-Pointer-Dereferenzierungsschwachstellen** zu mindern. Das liegt daran, dass XNU eine feste Page Zero erzwingt, die sicherstellt, dass die erste Seite (nur die erste) des Speichers unzugänglich ist (außer bei i386). Ein Binary kann diese Anforderung erfüllen, indem es ein kleines __PAGEZERO (mit dem `-pagezero_size`) erstellt, das die ersten 4k abdeckt, und den restlichen 32-Bit-Speicher sowohl im User- als auch im Kernel-Modus zugänglich macht.
|
||||
- **`__TEXT`**: Enthält ausführbaren **Code** mit **Lese**- und **Ausführungs**rechten (nicht schreibbar). Übliche Sektionen dieses Segments:
|
||||
- `__text`: Kompilierter Binärcode
|
||||
- `__const`: Konstanten Daten (nur lesbar)
|
||||
- `__const`: Konstante Daten (nur lesbar)
|
||||
- `__[c/u/os_log]string`: C-, Unicode- oder os-Log-String-Konstanten
|
||||
- `__stubs` und `__stubs_helper`: Beteiligt am Prozess des Ladens dynamischer Bibliotheken
|
||||
- `__unwind_info`: Stack-Unwind-Daten.
|
||||
- Beachten Sie, dass all dieser Inhalt signiert, aber auch als ausführbar markiert ist (was mehr Optionen für die Ausnutzung von Abschnitten schafft, die nicht unbedingt dieses Privileg benötigen, wie z.B. stringdedizierte Abschnitte).
|
||||
- **`__DATA`**: Enthält Daten, die **lesbar** und **schreibbar** sind (nicht ausführbar)**.**
|
||||
- `__got:` Globale Offset-Tabelle
|
||||
- `__nl_symbol_ptr`: Nicht faul (Bindung beim Laden) Symbolzeiger
|
||||
- `__la_symbol_ptr`: Faul (Bindung bei Verwendung) Symbolzeiger
|
||||
- `__const`: Soll schreibgeschützte Daten sein (nicht wirklich)
|
||||
- `__stubs` und `__stubs_helper`: Beteiligt am Prozess des dynamischen Ladens von Bibliotheken
|
||||
- `__unwind_info`: Stack-Unwind-Daten
|
||||
- Beachte, dass all dieser Inhalt signiert ist, aber auch als ausführbar markiert wird (was mehr Angriffsflächen für Abschnitte schafft, die diese Berechtigung nicht unbedingt benötigen, wie speziell für Strings vorgesehene Sektionen).
|
||||
- **`__DATA`**: Enthält Daten, die **lesbar** und **beschreibbar** sind (nicht ausführbar).
|
||||
- `__got:` Global Offset Table
|
||||
- `__nl_symbol_ptr`: Nicht-lazy (bind beim Laden) Symbolzeiger
|
||||
- `__la_symbol_ptr`: Lazy (bind bei Verwendung) Symbolzeiger
|
||||
- `__const`: Sollte schreibgeschützte Daten sein (ist es nicht wirklich)
|
||||
- `__cfstring`: CoreFoundation-Strings
|
||||
- `__data`: Globale Variablen (die initialisiert wurden)
|
||||
- `__bss`: Statische Variablen (die nicht initialisiert wurden)
|
||||
- `__objc_*` (\_\_objc_classlist, \_\_objc_protolist usw.): Informationen, die von der Objective-C-Laufzeit verwendet werden
|
||||
- **`__DATA_CONST`**: \_\_DATA.\_\_const ist nicht garantiert konstant (Schreibberechtigungen), noch sind andere Zeiger und die GOT. Dieser Abschnitt macht `__const`, einige Initialisierer und die GOT-Tabelle (einmal aufgelöst) **schreibgeschützt** mit `mprotect`.
|
||||
- **`__LINKEDIT`**: Enthält Informationen für den Linker (dyld), wie z.B. Symbol-, String- und Relocation-Tabelleneinträge. Es ist ein generischer Container für Inhalte, die sich weder in `__TEXT` noch in `__DATA` befinden, und dessen Inhalt in anderen Ladebefehlen beschrieben wird.
|
||||
- dyld-Informationen: Rebase, Nicht-faule/faul/schwache Bindungs-Opcode und Exportinformationen
|
||||
- Funktionsstarts: Tabelle der Startadressen von Funktionen
|
||||
- Daten im Code: Dateninseln in \_\_text
|
||||
- Symboltabelle: Symbole im Binärformat
|
||||
- Indirekte Symboltabelle: Zeiger/stub-Symbole
|
||||
- Zeichenfolgen-Tabelle
|
||||
- Codesignatur
|
||||
- **`__OBJC`**: Enthält Informationen, die von der Objective-C-Laufzeit verwendet werden. Obwohl diese Informationen auch im \_\_DATA-Segment gefunden werden können, innerhalb verschiedener \_\_objc\_\* Abschnitte.
|
||||
- **`__RESTRICT`**: Ein Segment ohne Inhalt mit einem einzigen Abschnitt namens **`__restrict`** (auch leer), das sicherstellt, dass beim Ausführen des Binärprogramms DYLD-Umgebungsvariablen ignoriert werden.
|
||||
- `__objc_*` (\_\_objc_classlist, \_\_objc_protolist, etc): Informationen, die von der Objective-C-Runtime verwendet werden
|
||||
- **`__DATA_CONST`**: __DATA.__const ist nicht garantiert konstant (Schreibrechte), ebenso wenig wie andere Zeiger und die GOT. Dieser Abschnitt macht `__const`, einige Initialisierer und die GOT-Tabelle (sobald aufgelöst) mit `mprotect` **nur lesbar**.
|
||||
- **`__LINKEDIT`**: Enthält Informationen für den Linker (dyld), wie Symbol-, String- und Relocation-Tabelleneinträge. Es ist ein generischer Container für Inhalte, die weder in `__TEXT` noch in `__DATA` liegen, und dessen Inhalt in anderen Load-Commands beschrieben wird.
|
||||
- dyld information: Rebase, Non-lazy/lazy/weak binding opcodes und Export-Informationen
|
||||
- Function starts: Tabelle der Startadressen von Funktionen
|
||||
- Data In Code: Dateninseln in `__text`
|
||||
- Symbol Table: Symbole im Binary
|
||||
- Indirect Symbol Table: Pointer/Stub-Symbole
|
||||
- String Table
|
||||
- Code Signature
|
||||
- **`__OBJC`**: Enthält Informationen, die von der Objective-C-Runtime verwendet werden. Diese Informationen können allerdings auch im `__DATA`-Segment innerhalb der verschiedenen `__objc_*`-Sektionen zu finden sein.
|
||||
- **`__RESTRICT`**: Ein Segment ohne Inhalt mit einer einzelnen Sektion namens **`__restrict`** (ebenfalls leer), das sicherstellt, dass beim Ausführen des Binaries die DYLD-Umgebungsvariablen ignoriert werden.
|
||||
|
||||
Wie im Code zu sehen war, **unterstützen Segmente auch Flags** (obwohl sie nicht sehr häufig verwendet werden):
|
||||
Wie im Code zu sehen ist, unterstützen **Segmente auch Flags** (obwohl sie nicht sehr oft verwendet werden):
|
||||
|
||||
- `SG_HIGHVM`: Nur Kern (nicht verwendet)
|
||||
- `SG_FVMLIB`: Nicht verwendet
|
||||
- `SG_NORELOC`: Segment hat keine Relokation
|
||||
- `SG_PROTECTED_VERSION_1`: Verschlüsselung. Wird beispielsweise vom Finder verwendet, um den Text des `__TEXT`-Segments zu verschlüsseln.
|
||||
- `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`** enthält den Einstiegspunkt im **entryoff-Attribut.** Zur Ladezeit **fügt dyld** einfach **diesen Wert** zur (im Speicher) **Basis des Binärprogramms** hinzu und **springt** dann zu dieser Anweisung, um die Ausführung des Codes des Binärprogramms zu starten.
|
||||
**`LC_MAIN`** enthält den Entrypoint im **entryoff**-Attribut. Zur Ladezeit addiert **dyld** diesen Wert einfach zur (im Speicher befindlichen) Basis des Binaries und springt dann zu dieser Instruktion, um die Ausführung des Binary-Codes zu starten.
|
||||
|
||||
**`LC_UNIXTHREAD`** enthält die Werte, die die Register haben müssen, wenn der Hauptthread gestartet wird. Dies wurde bereits als veraltet markiert, aber **`dyld`** verwendet es immer noch. Es ist möglich, die von diesem gesetzten Registerwerte zu sehen mit:
|
||||
**`LC_UNIXTHREAD`** enthält die Werte, die die Register beim Start des Main-Threads haben müssen. Dies ist bereits veraltet, wird aber von **`dyld`** weiterhin verwendet. Es ist möglich, die durch dieses Kommando gesetzten Registerwerte mit folgendem Befehl zu sehen:
|
||||
```bash
|
||||
otool -l /usr/lib/dyld
|
||||
[...]
|
||||
@ -286,34 +286,39 @@ cpsr 0x00000000
|
||||
```
|
||||
### **`LC_CODE_SIGNATURE`**
|
||||
|
||||
Enthält Informationen über die **Code-Signatur der Macho-O-Datei**. Es enthält nur einen **Offset**, der auf den **Signatur-Blob** zeigt. Dies befindet sich typischerweise am Ende der Datei.\
|
||||
Sie können jedoch einige Informationen zu diesem Abschnitt in [**diesem Blogbeitrag**](https://davedelong.com/blog/2018/01/10/reading-your-own-entitlements/) und diesen [**Gists**](https://gist.github.com/carlospolop/ef26f8eb9fafd4bc22e69e1a32b81da4) finden.
|
||||
{{#ref}}
|
||||
../../../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
Enthält Informationen über die **code signature of the Macho-O file**. Es enthält nur einen **Offset**, der auf den **Signature Blob** zeigt. Dieser befindet sich typischerweise ganz am Ende der Datei.\
|
||||
Allerdings finden Sie einige Informationen zu diesem Abschnitt in [**this blog post**](https://davedelong.com/blog/2018/01/10/reading-your-own-entitlements/) und diesem [**gists**](https://gist.github.com/carlospolop/ef26f8eb9fafd4bc22e69e1a32b81da4).
|
||||
|
||||
### **`LC_ENCRYPTION_INFO[_64]`**
|
||||
|
||||
Unterstützung für die binäre Verschlüsselung. Wenn ein Angreifer jedoch den Prozess kompromittiert, kann er den Speicher unverschlüsselt dumpen.
|
||||
Unterstützt die Verschlüsselung von Binaries. Wenn ein Angreifer jedoch den Prozess kompromittiert, kann er selbstverständlich den Speicher unverschlüsselt dumpen.
|
||||
|
||||
### **`LC_LOAD_DYLINKER`**
|
||||
|
||||
Enthält den **Pfad zur dynamischen Linker-Executable**, die gemeinsam genutzte Bibliotheken in den Adressraum des Prozesses einbindet. Der **Wert ist immer auf `/usr/lib/dyld`** gesetzt. Es ist wichtig zu beachten, dass in macOS das Dylib-Mapping im **Benutzermodus** und nicht im Kernelmodus erfolgt.
|
||||
Enthält den **Pfad zur dynamic linker executable**, die shared libraries in den Adressraum des Prozesses einbindet. Der **Wert ist immer auf `/usr/lib/dyld` gesetzt**. Wichtig ist, dass unter macOS das Mapping von dylibs im **Benutzermodus** (user mode) und nicht im Kernel-Modus erfolgt.
|
||||
|
||||
### **`LC_IDENT`**
|
||||
|
||||
Veraltet, aber wenn konfiguriert, um Dumps bei einem Panic zu erzeugen, wird ein Mach-O-Core-Dump erstellt und die Kernelversion wird im `LC_IDENT`-Befehl gesetzt.
|
||||
Obsolet, aber wenn so konfiguriert, dass bei Panic Dumps erzeugt werden, wird ein Mach-O Core-Dump erstellt und die Kernel-Version im `LC_IDENT`-Befehl gesetzt.
|
||||
|
||||
### **`LC_UUID`**
|
||||
|
||||
Zufällige UUID. Es ist nützlich für alles direkt, aber XNU cached es mit dem Rest der Prozessinformationen. Es kann in Absturzberichten verwendet werden.
|
||||
Zufällige UUID. Sie ist zwar nicht direkt nützlich, aber XNU cached sie zusammen mit den übrigen Prozessinformationen. Sie kann in Crash-Reports verwendet werden.
|
||||
|
||||
### **`LC_DYLD_ENVIRONMENT`**
|
||||
|
||||
Erlaubt es, Umgebungsvariablen an den dyld anzugeben, bevor der Prozess ausgeführt wird. Dies kann sehr gefährlich sein, da es die Ausführung beliebigen Codes innerhalb des Prozesses ermöglichen kann, sodass dieser Ladebefehl nur in dyld-Bauten mit `#define SUPPORT_LC_DYLD_ENVIRONMENT` verwendet wird und die Verarbeitung weiter auf Variablen der Form `DYLD_..._PATH` beschränkt ist, die Ladepfade angeben.
|
||||
Ermöglicht es, dem dyld Umgebungsvariablen anzugeben, bevor der Prozess ausgeführt wird. Das kann sehr gefährlich sein, da es das Ausführen beliebigen Codes im Prozess erlauben kann; deshalb wird dieser Load-Command nur in dyld-Builds mit `#define SUPPORT_LC_DYLD_ENVIRONMENT` verwendet und verarbeitet zusätzlich nur Variablen der Form `DYLD_..._PATH`, die Ladepfade spezifizieren.
|
||||
|
||||
### **`LC_LOAD_DYLIB`**
|
||||
|
||||
Dieser Ladebefehl beschreibt eine **dynamische** **Bibliotheks**-Abhängigkeit, die den **Loader** (dyld) anweist, die **angegebene Bibliothek zu laden und zu verlinken**. Es gibt einen `LC_LOAD_DYLIB`-Ladebefehl **für jede Bibliothek**, die die Mach-O-Binärdatei benötigt.
|
||||
Dieser Load-Command beschreibt eine **dynamische** **Library**-Abhängigkeit, die den **Loader** (dyld) anweist, die betreffende Library zu **laden und zu verlinken**. Es gibt einen `LC_LOAD_DYLIB`-Load-Command **für jede Library**, die das Mach-O-Binary benötigt.
|
||||
|
||||
- Dieser Ladebefehl ist eine Struktur vom Typ **`dylib_command`** (die eine Struktur dylib enthält, die die tatsächliche abhängige dynamische Bibliothek beschreibt):
|
||||
- Dieser Load-Command ist eine Struktur vom Typ **`dylib_command`** (die eine struct dylib enthält, welche die tatsächlich abhängige dynamische Library beschreibt):
|
||||
```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>)
|
||||
|
||||
Sie können diese Informationen auch über die CLI erhalten mit:
|
||||
Du kannst diese Informationen auch mit der cli abrufen:
|
||||
```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)
|
||||
```
|
||||
Einige potenzielle malwarebezogene Bibliotheken sind:
|
||||
Einige potenziell mit Malware verbundene Bibliotheken sind:
|
||||
|
||||
- **DiskArbitration**: Überwachung von USB-Laufwerken
|
||||
- **AVFoundation:** Audio und Video erfassen
|
||||
- **CoreWLAN**: Wifi-Scans.
|
||||
- **AVFoundation:** Aufnahme von Audio und Video
|
||||
- **CoreWLAN**: WLAN-Scans.
|
||||
|
||||
> [!NOTE]
|
||||
> Eine Mach-O-Binärdatei kann einen oder **mehrere** **Konstruktoren** enthalten, die **ausgeführt** werden, **bevor** die Adresse, die in **LC_MAIN** angegeben ist, erreicht wird.\
|
||||
> Die Offsets aller Konstruktoren befinden sich im Abschnitt **\_\_mod_init_func** des Segments **\_\_DATA_CONST**.
|
||||
> [!TIP]
|
||||
> Eine Mach-O-Binärdatei kann einen oder **mehrere** **Konstruktoren** enthalten, die **ausgeführt** werden **bevor** die in **LC_MAIN** angegebene Adresse.\
|
||||
> Die Offsets von Konstruktoren werden im **\_\_mod_init_func** Abschnitt des **\_\_DATA_CONST** Segments gehalten.
|
||||
|
||||
## **Mach-O-Daten**
|
||||
|
||||
Im Kern der Datei liegt der Datenbereich, der aus mehreren Segmenten besteht, wie im Bereich der Ladebefehle definiert. **Eine Vielzahl von Datensektionen kann innerhalb jedes Segments untergebracht werden**, wobei jede Sektion **Code oder Daten** enthält, die spezifisch für einen Typ sind.
|
||||
Im Kern der Datei liegt der Datenbereich, der aus mehreren Segmenten besteht, wie im Bereich load-commands definiert. **Innerhalb jedes Segments können verschiedene Datensektionen untergebracht sein**, wobei jede Sektion **Code oder Daten** enthält, die einem bestimmten Typ entsprechen.
|
||||
|
||||
> [!TIP]
|
||||
> Die Daten sind im Grunde der Teil, der alle **Informationen** enthält, die durch die Ladebefehle **LC_SEGMENTS_64** geladen werden.
|
||||
> Die Daten sind im Grunde der Teil, der alle **Informationen** enthält, die durch die load commands **LC_SEGMENTS_64** geladen werden.
|
||||
|
||||
 (3).png>)
|
||||
|
||||
Dazu gehören:
|
||||
|
||||
- **Funktionstabelle:** Die Informationen über die Programmfunktionen enthält.
|
||||
- **Symboltabelle**: Die Informationen über die externen Funktionen enthält, die von der Binärdatei verwendet werden.
|
||||
- Es könnte auch interne Funktionen, Variablennamen und mehr enthalten.
|
||||
- **Funktionstabelle:** Enthält Informationen über die Funktionen des Programms.
|
||||
- **Symboltabelle**: Enthält Informationen über die externen Funktionen, die von der Binärdatei verwendet werden.
|
||||
- Es kann auch interne Funktions- und Variablennamen sowie weiteres enthalten.
|
||||
|
||||
Um dies zu überprüfen, könnten Sie das [**Mach-O View**](https://sourceforge.net/projects/machoview/) Tool verwenden:
|
||||
Um dies zu prüfen, können Sie das [**Mach-O View**](https://sourceforge.net/projects/machoview/) Tool verwenden:
|
||||
|
||||
<figure><img src="../../../images/image (1120).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
@ -371,22 +376,22 @@ Oder über die CLI:
|
||||
```bash
|
||||
size -m /bin/ls
|
||||
```
|
||||
## Objetive-C Gemeinsame Abschnitte
|
||||
## Objetive-C: Übliche Abschnitte
|
||||
|
||||
Im `__TEXT` Segment (r-x):
|
||||
Im `__TEXT`-Segment (r-x):
|
||||
|
||||
- `__objc_classname`: Klassennamen (Strings)
|
||||
- `__objc_methname`: Methodennamen (Strings)
|
||||
- `__objc_methtype`: Methodentypen (Strings)
|
||||
|
||||
Im `__DATA` Segment (rw-):
|
||||
Im `__DATA`-Segment (rw-):
|
||||
|
||||
- `__objc_classlist`: Zeiger auf alle Objective-C Klassen
|
||||
- `__objc_nlclslist`: Zeiger auf Nicht-Lazy Objective-C Klassen
|
||||
- `__objc_catlist`: Zeiger auf Kategorien
|
||||
- `__objc_nlcatlist`: Zeiger auf Nicht-Lazy Kategorien
|
||||
- `__objc_protolist`: Protokollliste
|
||||
- `__objc_const`: Konstanten Daten
|
||||
- `__objc_classlist`: Zeiger auf alle Objetive-C-Klassen
|
||||
- `__objc_nlclslist`: Zeiger auf Non-Lazy Objetive-C-Klassen
|
||||
- `__objc_catlist`: Zeiger auf Categories
|
||||
- `__objc_nlcatlist`: Zeiger auf Non-Lazy-Categories
|
||||
- `__objc_protolist`: Liste von Protocols
|
||||
- `__objc_const`: Konstante Daten
|
||||
- `__objc_imageinfo`, `__objc_selrefs`, `objc__protorefs`...
|
||||
|
||||
## Swift
|
||||
|
@ -4,12 +4,17 @@
|
||||
|
||||
## Grundlegende Informationen
|
||||
|
||||
Mach-o-Binärdateien enthalten einen Ladebefehl namens **`LC_CODE_SIGNATURE`**, der den **Offset** und die **Größe** der Signaturen innerhalb der Binärdatei angibt. Tatsächlich ist es möglich, mit dem GUI-Tool MachOView am Ende der Binärdatei einen Abschnitt namens **Code Signature** mit diesen Informationen zu finden:
|
||||
{{#ref}}
|
||||
../../../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
Mach-O-Binärdateien enthalten einen Load-Command namens **`LC_CODE_SIGNATURE`**, der den **offset** und die **size** der Signaturen innerhalb der Binärdatei angibt. Mit dem GUI-Tool MachOView kann man am Ende der Binärdatei einen Abschnitt namens **Code Signature** mit diesen Informationen finden:
|
||||
|
||||
<figure><img src="../../../images/image (1) (1) (1) (1).png" alt="" width="431"><figcaption></figcaption></figure>
|
||||
|
||||
Der magische Header der Code-Signatur ist **`0xFADE0CC0`**. Dann haben Sie Informationen wie die Länge und die Anzahl der Blobs des SuperBlobs, die sie enthalten.\
|
||||
Diese Informationen sind im [Quellcode hier](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L276) zu finden:
|
||||
Der Magic-Header der Code Signature ist **`0xFADE0CC0`**. Danach folgen Informationen wie die Länge und die Anzahl der Blobs des superBlob, das sie enthält.\
|
||||
Diese Informationen lassen sich im [source code here](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L276) finden:
|
||||
```c
|
||||
/*
|
||||
* Structure of an embedded-signature SuperBlob
|
||||
@ -38,14 +43,14 @@ char data[];
|
||||
} CS_GenericBlob
|
||||
__attribute__ ((aligned(1)));
|
||||
```
|
||||
Häufig enthaltene Blobs sind Codeverzeichnis, Anforderungen und Berechtigungen sowie eine kryptografische Nachrichten-Syntax (CMS).\
|
||||
Außerdem beachten Sie, dass die in den Blobs codierten Daten in **Big Endian** codiert sind.
|
||||
Übliche enthaltene Blobs sind Code Directory, Requirements und Entitlements sowie eine Cryptographic Message Syntax (CMS).\
|
||||
Beachte außerdem, dass die in den Blobs enthaltenen Daten in **Big Endian** kodiert sind.
|
||||
|
||||
Darüber hinaus können Signaturen von den Binärdateien getrennt und in `/var/db/DetachedSignatures` gespeichert werden (verwendet von iOS).
|
||||
Außerdem können Signaturen von den Binärdateien getrennt und in `/var/db/DetachedSignatures` gespeichert werden (von iOS verwendet).
|
||||
|
||||
## Codeverzeichnis-Blob
|
||||
## Code Directory Blob
|
||||
|
||||
Es ist möglich, die Deklaration des [Codeverzeichnis-Blobs im Code zu finden](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L104):
|
||||
Die Deklaration des [Code Directory Blob in the code](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L104) kann hier gefunden werden:
|
||||
```c
|
||||
typedef struct __CodeDirectory {
|
||||
uint32_t magic; /* magic number (CSMAGIC_CODEDIRECTORY) */
|
||||
@ -101,12 +106,12 @@ char end_withLinkage[0];
|
||||
} CS_CodeDirectory
|
||||
__attribute__ ((aligned(1)));
|
||||
```
|
||||
Beachten Sie, dass es verschiedene Versionen dieser Struktur gibt, bei denen ältere möglicherweise weniger Informationen enthalten.
|
||||
Beachte, dass es verschiedene Versionen dieser struct gibt, bei denen ältere möglicherweise weniger Informationen enthalten.
|
||||
|
||||
## Signing Code Pages
|
||||
## Code-Seiten signieren
|
||||
|
||||
Das Hashing des vollständigen Binaries wäre ineffizient und sogar nutzlos, wenn es nur teilweise im Speicher geladen ist. Daher ist die Codesignatur tatsächlich ein Hash von Hashes, bei dem jede Binärseite einzeln gehasht wird.\
|
||||
Tatsächlich können Sie im vorherigen **Code Directory**-Code sehen, dass die **Seitenhöhe angegeben ist** in einem seiner Felder. Darüber hinaus gibt das Feld **CodeLimit** an, wo das Ende der Signatur liegt, wenn die Größe des Binaries kein Vielfaches der Seitenhöhe ist.
|
||||
Das Hashen des gesamten binary wäre ineffizient und sogar nutzlos, wenn es nur teilweise im Speicher geladen wird. Deshalb ist die Codesignatur tatsächlich ein Hash von Hashes, wobei jede Seite des binary einzeln gehasht wird.\
|
||||
Tatsächlich kannst du im vorherigen **Code Directory**-Code sehen, dass in einem seiner Felder die **Seitengröße angegeben ist**. Außerdem legt, falls die Größe des binary kein Vielfaches der Seitengröße ist, das Feld **CodeLimit** fest, wo das Ende der Signatur liegt.
|
||||
```bash
|
||||
# Get all hashes of /bin/ps
|
||||
codesign -d -vvvvvv /bin/ps
|
||||
@ -144,25 +149,25 @@ openssl sha256 /tmp/*.page.*
|
||||
```
|
||||
## Entitlements Blob
|
||||
|
||||
Beachten Sie, dass Anwendungen auch einen **Entitlement Blob** enthalten können, in dem alle Berechtigungen definiert sind. Darüber hinaus können einige iOS-Binärdateien ihre Berechtigungen spezifisch im speziellen Slot -7 (anstatt im speziellen Slot -5 für Berechtigungen) haben.
|
||||
Beachte, dass Anwendungen möglicherweise auch ein **entitlement blob** enthalten, in dem alle Entitlements definiert sind. Außerdem können einige iOS-Binaries ihre Entitlements im speziellen Slot -7 haben (anstatt im speziellen Entitlements-Slot -5).
|
||||
|
||||
## Special Slots
|
||||
|
||||
MacOS-Anwendungen haben nicht alles, was sie zur Ausführung benötigen, innerhalb der Binärdatei, sondern verwenden auch **externe Ressourcen** (normalerweise innerhalb des Anwendungs-**Bundles**). Daher gibt es einige Slots innerhalb der Binärdatei, die die Hashes einiger interessanter externer Ressourcen enthalten, um zu überprüfen, ob sie nicht modifiziert wurden.
|
||||
MacOS-Anwendungen enthalten nicht alles, was zur Ausführung nötig ist, im Binary selbst; sie nutzen außerdem **external resources** (in der Regel im Anwendungen **bundle**). Daher gibt es einige Slots im Binary, die die Hashes bestimmter externer Ressourcen enthalten, um zu prüfen, ob diese nicht verändert wurden.
|
||||
|
||||
Tatsächlich ist es möglich, in den Code Directory-Strukturen einen Parameter namens **`nSpecialSlots`** zu sehen, der die Anzahl der speziellen Slots angibt. Es gibt keinen speziellen Slot 0, und die häufigsten (von -1 bis -6) sind:
|
||||
Tatsächlich findet man in den Code Directory-Strukturen einen Parameter namens **`nSpecialSlots`**, der die Anzahl der special slots angibt. Es gibt keinen special slot 0; die gebräuchlichsten (von -1 bis -6) sind:
|
||||
|
||||
- Hash von `info.plist` (oder dem innerhalb von `__TEXT.__info__plist`).
|
||||
- Hash der Anforderungen
|
||||
- Hash des Ressourcenverzeichnisses (Hash der Datei `_CodeSignature/CodeResources` innerhalb des Bundles).
|
||||
- Anwendungsspezifisch (nicht verwendet)
|
||||
- Hash der Berechtigungen
|
||||
- DMG-Code-Signaturen nur
|
||||
- DER-Berechtigungen
|
||||
- Hash von `info.plist` (oder derjenigen in `__TEXT.__info__plist`).
|
||||
- Hash der Requirements
|
||||
- Hash des Resource Directory (Hash der Datei `_CodeSignature/CodeResources` im Bundle).
|
||||
- Anwendungsspezifisch (unbenutzt)
|
||||
- Hash der Entitlements
|
||||
- Nur DMG-Code-Signaturen
|
||||
- DER Entitlements
|
||||
|
||||
## Code Signing Flags
|
||||
|
||||
Jeder Prozess hat eine zugehörige Bitmaske, die als `status` bekannt ist und vom Kernel gestartet wird. Einige davon können durch die **Code-Signatur** überschrieben werden. Diese Flags, die in der Code-Signierung enthalten sein können, sind [im Code definiert](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L36):
|
||||
Jeder Prozess hat eine zugehörige Bitmaske namens `status`, die vom Kernel initialisiert wird, und einige Bits davon können durch die **code signature** überschrieben werden. Diese Flags, die in der Code-Signatur enthalten sein können, sind [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)
|
||||
```
|
||||
Beachten Sie, dass die Funktion [**exec_mach_imgact**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_exec.c#L1420) auch die `CS_EXEC_*`-Flags dynamisch hinzufügen kann, wenn die Ausführung gestartet wird.
|
||||
Beachte, dass die Funktion [**exec_mach_imgact**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_exec.c#L1420) auch die `CS_EXEC_*`-Flags dynamisch beim Start der Ausführung hinzufügen kann.
|
||||
|
||||
## Anforderungen an die Code-Signatur
|
||||
|
||||
Jede Anwendung speichert einige **Anforderungen**, die sie **erfüllen** muss, um ausgeführt werden zu können. Wenn die **Anforderungen der Anwendung nicht von der Anwendung erfüllt werden**, wird sie nicht ausgeführt (da sie wahrscheinlich verändert wurde).
|
||||
Jede Anwendung speichert einige **Anforderungen**, die sie **erfüllen** muss, um ausgeführt werden zu können. Wenn die **Anforderungen**, die die Anwendung enthält, nicht erfüllt sind, wird sie nicht ausgeführt (da sie wahrscheinlich verändert wurde).
|
||||
|
||||
Die Anforderungen einer Binärdatei verwenden eine **spezielle Grammatik**, die ein Stream von **Ausdrücken** ist und als Blobs mit `0xfade0c00` als Magie kodiert ist, deren **Hash in einem speziellen Codeslot gespeichert ist**.
|
||||
Die **Anforderungen** einer Binärdatei verwenden eine **spezielle Grammatik**, die aus einem Strom von **Ausdrücken** besteht, und werden als Blobs codiert, die `0xfade0c00` als Magic verwenden, dessen **Hash in einem speziellen Code-Slot gespeichert wird**.
|
||||
|
||||
Die Anforderungen einer Binärdatei können durch Ausführen von:
|
||||
Die Anforderungen einer Binärdatei lassen sich anzeigen, indem man ausführt:
|
||||
```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]
|
||||
> Beachten Sie, wie diese Signaturen Dinge wie Zertifizierungsinformationen, TeamID, IDs, Berechtigungen und viele andere Daten überprüfen können.
|
||||
> [!TIP]
|
||||
> Beachte, wie diese Signaturen Dinge wie Zertifikatsinformationen, TeamID, IDs, entitlements und viele andere Daten prüfen können.
|
||||
|
||||
Darüber hinaus ist es möglich, einige kompilierte Anforderungen mit dem `csreq`-Tool zu generieren:
|
||||
Zudem ist es möglich, einige kompilierte Anforderungen mit dem Tool `csreq` zu erzeugen:
|
||||
```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
|
||||
[...]
|
||||
```
|
||||
Es ist möglich, auf diese Informationen zuzugreifen und Anforderungen mit einigen APIs aus dem `Security.framework` zu erstellen oder zu ändern, wie:
|
||||
Es ist möglich, auf diese Informationen zuzugreifen und Anforderungen zu erstellen oder zu ändern mittels einiger APIs aus dem `Security.framework`, wie zum Beispiel:
|
||||
|
||||
#### **Überprüfung der Gültigkeit**
|
||||
#### **Gültigkeit prüfen**
|
||||
|
||||
- **`Sec[Static]CodeCheckValidity`**: Überprüft die Gültigkeit von SecCodeRef pro Anforderung.
|
||||
- **`SecRequirementEvaluate`**: Validiert die Anforderung im Kontext des Zertifikats.
|
||||
- **`SecTaskValidateForRequirement`**: Validiert eine laufende SecTask gegen die `CFString`-Anforderung.
|
||||
- **`Sec[Static]CodeCheckValidity`**: Prüft die Gültigkeit eines `SecCodeRef` anhand einer Requirement.
|
||||
- **`SecRequirementEvaluate`**: Validiert eine Requirement im Zertifikatskontext.
|
||||
- **`SecTaskValidateForRequirement`**: Validiert einen laufenden `SecTask` gegen eine `CFString`-Requirement.
|
||||
|
||||
#### **Erstellen und Verwalten von Code-Anforderungen**
|
||||
|
||||
- **`SecRequirementCreateWithData`:** Erstellt ein `SecRequirementRef` aus binären Daten, die die Anforderung darstellen.
|
||||
- **`SecRequirementCreateWithString`:** Erstellt ein `SecRequirementRef` aus einem String-Ausdruck der Anforderung.
|
||||
- **`SecRequirementCopy[Data/String]`**: Ruft die binäre Datenrepräsentation eines `SecRequirementRef` ab.
|
||||
- **`SecRequirementCreateGroup`**: Erstellt eine Anforderung für die Mitgliedschaft in einer App-Gruppe.
|
||||
- **`SecRequirementCreateWithData`:** Erstellt ein `SecRequirementRef` aus Binärdaten, die die Anforderung repräsentieren.
|
||||
- **`SecRequirementCreateWithString`:** Erstellt ein `SecRequirementRef` aus einer String-Expression der Anforderung.
|
||||
- **`SecRequirementCopy[Data/String]`**: Ruft die Binärdaten-Repräsentation eines `SecRequirementRef` ab.
|
||||
- **`SecRequirementCreateGroup`**: Erstellt eine Requirement für die Zugehörigkeit zu einer App-Gruppe
|
||||
|
||||
#### **Zugriff auf Code-Signaturinformationen**
|
||||
#### **Zugriff auf Informationen zur Code-Signierung**
|
||||
|
||||
- **`SecStaticCodeCreateWithPath`**: Initialisiert ein `SecStaticCodeRef`-Objekt von einem Dateisystempfad zur Überprüfung von Codesignaturen.
|
||||
- **`SecCodeCopySigningInformation`**: Erhält Signaturinformationen von einem `SecCodeRef` oder `SecStaticCodeRef`.
|
||||
- **`SecStaticCodeCreateWithPath`**: Initialisiert ein `SecStaticCodeRef`-Objekt aus einem Dateisystempfad zum Prüfen von Codesignaturen.
|
||||
- **`SecCodeCopySigningInformation`**: Ermittelt Signaturinformationen aus einem `SecCodeRef` oder `SecStaticCodeRef`.
|
||||
|
||||
#### **Ändern von Code-Anforderungen**
|
||||
|
||||
- **`SecCodeSignerCreate`**: Erstellt ein `SecCodeSignerRef`-Objekt für die Durchführung von Codesignierungsoperationen.
|
||||
- **`SecCodeSignerSetRequirement`**: Setzt eine neue Anforderung für den Codesigner, die während der Signierung angewendet werden soll.
|
||||
- **`SecCodeSignerAddSignature`**: Fügt eine Signatur zu dem zu signierenden Code mit dem angegebenen Signierer hinzu.
|
||||
- **`SecCodeSignerCreate`**: Erstellt ein `SecCodeSignerRef`-Objekt für Code-Signing-Operationen.
|
||||
- **`SecCodeSignerSetRequirement`**: Legt eine neue Requirement fest, die vom Code-Signer beim Signieren angewendet werden soll.
|
||||
- **`SecCodeSignerAddSignature`**: Fügt dem mit dem angegebenen Signer signierten Code eine Signatur hinzu.
|
||||
|
||||
#### **Validierung von Code mit Anforderungen**
|
||||
#### **Code mit Anforderungen validieren**
|
||||
|
||||
- **`SecStaticCodeCheckValidity`**: Validiert ein statisches Codeobjekt gegen die angegebenen Anforderungen.
|
||||
- **`SecStaticCodeCheckValidity`**: Validiert ein statisches Code-Objekt gegen angegebene Anforderungen.
|
||||
|
||||
#### **Zusätzliche nützliche APIs**
|
||||
#### **Weitere nützliche APIs**
|
||||
|
||||
- **`SecCodeCopy[Internal/Designated]Requirement`: Erhalte SecRequirementRef von SecCodeRef**
|
||||
- **`SecCodeCopyGuestWithAttributes`**: Erstellt ein `SecCodeRef`, das ein Codeobjekt basierend auf spezifischen Attributen darstellt, nützlich für Sandboxing.
|
||||
- **`SecCodeCopy[Internal/Designated]Requirement`: Get SecRequirementRef from SecCodeRef**: Gibt ein `SecRequirementRef` aus einem `SecCodeRef` zurück.
|
||||
- **`SecCodeCopyGuestWithAttributes`**: Erstellt ein `SecCodeRef`, das ein Code-Objekt basierend auf bestimmten Attributen repräsentiert — nützlich für Sandboxing.
|
||||
- **`SecCodeCopyPath`**: Ruft den Dateisystempfad ab, der mit einem `SecCodeRef` verknüpft ist.
|
||||
- **`SecCodeCopySigningIdentifier`**: Erhält die Signaturkennung (z. B. Team-ID) von einem `SecCodeRef`.
|
||||
- **`SecCodeCopySigningIdentifier`**: Ermittelt den Signing-Identifier (z. B. Team ID) aus einem `SecCodeRef`.
|
||||
- **`SecCodeGetTypeID`**: Gibt die Typkennung für `SecCodeRef`-Objekte zurück.
|
||||
- **`SecRequirementGetTypeID`**: Erhält eine CFTypeID eines `SecRequirementRef`.
|
||||
- **`SecRequirementGetTypeID`**: Gibt eine CFTypeID eines `SecRequirementRef` zurück.
|
||||
|
||||
#### **Code-Signierungsflags und Konstanten**
|
||||
#### **Code-Signing-Flags und Konstanten**
|
||||
|
||||
- **`kSecCSDefaultFlags`**: Standardflags, die in vielen Funktionen des Security.framework für Codesignierungsoperationen verwendet werden.
|
||||
- **`kSecCSDefaultFlags`**: Standard-Flags, die in vielen Funktionen des Security.framework für Code-Signing-Operationen verwendet werden.
|
||||
- **`kSecCSSigningInformation`**: Flag, das angibt, dass Signaturinformationen abgerufen werden sollen.
|
||||
|
||||
## Durchsetzung der Codesignatur
|
||||
|
||||
Der **Kernel** ist derjenige, der **die Codesignatur überprüft**, bevor er den Code der App ausführen lässt. Darüber hinaus ist eine Möglichkeit, neuen Code im Speicher zu schreiben und auszuführen, den JIT zu missbrauchen, wenn `mprotect` mit dem `MAP_JIT`-Flag aufgerufen wird. Beachten Sie, dass die Anwendung eine spezielle Berechtigung benötigt, um dies tun zu können.
|
||||
Der **Kernel** ist dafür verantwortlich, die Codesignatur zu prüfen, bevor der Code einer App ausgeführt wird. Außerdem ist eine Möglichkeit, neuen Code im Speicher zu schreiben und auszuführen, die Ausnutzung von JIT, wenn `mprotect` mit dem `MAP_JIT`-Flag aufgerufen wird. Beachte, dass die Anwendung ein spezielles Entitlement benötigt, um dies zu ermöglichen.
|
||||
|
||||
## `cs_blobs` & `cs_blob`
|
||||
|
||||
[**cs_blob**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/ubc_internal.h#L106) Struktur enthält die Informationen über die Berechtigung des laufenden Prozesses. `csb_platform_binary` informiert auch, ob die Anwendung ein Plattform-Binary ist (was zu verschiedenen Zeitpunkten vom OS überprüft wird, um Sicherheitsmechanismen anzuwenden, wie z. B. den Schutz der SEND-Rechte zu den Task-Ports dieser Prozesse).
|
||||
[**cs_blob**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/ubc_internal.h#L106) struct enthält Informationen über die Entitlements des laufenden Prozesses. `csb_platform_binary` gibt außerdem an, ob die Anwendung ein platform binary ist (was vom OS an verschiedenen Stellen geprüft wird, um Sicherheitsmechanismen anzuwenden, z. B. um die SEND-Rechte der task ports dieser Prozesse zu schützen).
|
||||
```c
|
||||
struct cs_blob {
|
||||
struct cs_blob *csb_next;
|
||||
|
Loading…
x
Reference in New Issue
Block a user