Translated ['src/generic-methodologies-and-resources/basic-forensic-meth

This commit is contained in:
Translator 2025-10-01 01:56:33 +00:00
parent a1992518e7
commit b05e1753ad
5 changed files with 471 additions and 170 deletions

View File

@ -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)

View File

@ -1,8 +1,8 @@
# Συγκεκριμένα κόλπα για λογισμικό/τύπους αρχείων
# Συγκεκριμένα Κόλπα για Λογισμικό/Τύπους Αρχείων
{{#include ../../../banners/hacktricks-training.md}}
Εδώ θα βρείτε ενδιαφέροντα κόλπα για συγκεκριμένους τύπους αρχείων και/ή λογισμικό:
Εδώ μπορείτε να βρείτε ενδιαφέροντα κόλπα για συγκεκριμένους τύπους αρχείων και/ή λογισμικό:
{{#ref}}
@ -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}}

View File

@ -0,0 +1,211 @@
# Mach-O Εξαγωγή Entitlements & Δεικτοδότηση IPSW
{{#include ../../../banners/hacktricks-training.md}}
## Επισκόπηση
Αυτή η σελίδα καλύπτει πώς να εξάγετε entitlements από Mach-O binaries προγραμματιστικά διασχίζοντας το LC_CODE_SIGNATURE και αναλύοντας το code signing SuperBlob, και πώς να κλιμακώσετε αυτό σε Apple IPSW firmwares προσαρτώντας και δεικτοδοτώντας το περιεχόμενό τους για ιατροδικαστική αναζήτηση/διαφορές.
Αν χρειάζεστε επανάληψη για τη μορφή Mach-O και το code signing, δείτε επίσης: macOS code signing and SuperBlob internals.
- Ελέγξτε τις λεπτομέρειες του macOS code signing (SuperBlob, Code Directory, special slots): [macOS Code Signing](../../../macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md)
- Ελέγξτε τις γενικές δομές Mach-O / 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 στο Mach-O: πού βρίσκονται
Τα entitlements αποθηκεύονται μέσα στα δεδομένα της code signature που αναφέρεται από το load command LC_CODE_SIGNATURE και τοποθετούνται στο segment __LINKEDIT. Η υπογραφή είναι ένα CS_SuperBlob που περιέχει πολλαπλά blobs (code directory, requirements, entitlements, CMS, κ.λπ.). Το entitlements blob είναι ένα CS_GenericBlob του οποίου τα δεδομένα είναι ένα Apple Binary Property List (bplist00) που αντιστοιχίζει κλειδιά entitlements σε τιμές.
Κύριες δομές (από xnu):
```c
/* mach-o/loader.h */
struct mach_header_64 {
uint32_t magic;
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
uint32_t filetype;
uint32_t ncmds;
uint32_t sizeofcmds;
uint32_t flags;
uint32_t reserved;
};
struct load_command {
uint32_t cmd;
uint32_t cmdsize;
};
/* Entitlements live behind LC_CODE_SIGNATURE (cmd=0x1d) */
struct linkedit_data_command {
uint32_t cmd; /* LC_CODE_SIGNATURE */
uint32_t cmdsize; /* sizeof(struct linkedit_data_command) */
uint32_t dataoff; /* file offset of data in __LINKEDIT */
uint32_t datasize; /* file size of data in __LINKEDIT */
};
/* osfmk/kern/cs_blobs.h */
typedef struct __SC_SuperBlob {
uint32_t magic; /* CSMAGIC_EMBEDDED_SIGNATURE = 0xfade0cc0 */
uint32_t length;
uint32_t count;
CS_BlobIndex index[];
} CS_SuperBlob;
typedef struct __BlobIndex {
uint32_t type; /* e.g., CSMAGIC_EMBEDDED_ENTITLEMENTS = 0xfade7171 */
uint32_t offset; /* offset of entry */
} CS_BlobIndex;
typedef struct __SC_GenericBlob {
uint32_t magic; /* same as type when standalone */
uint32_t length;
char data[]; /* Apple Binary Plist containing entitlements */
} CS_GenericBlob;
```
Σημαντικά σταθερά:
- LC_CODE_SIGNATURE cmd = 0x1d
- CS SuperBlob magic = 0xfade0cc0
- Entitlements blob type (CSMAGIC_EMBEDDED_ENTITLEMENTS) = 0xfade7171
- DER entitlements may be present via special slot (e.g., -7), see the macOS Code Signing page for special slots and DER entitlements notes
Σημείωση: Multi-arch (fat) binaries περιέχουν πολλαπλά Mach-O slices. Πρέπει να επιλέξετε το slice για την αρχιτεκτονική που θέλετε να εξετάσετε και μετά να διαβάσετε τα load commands.
## Βήματα εξαγωγής (γενικά, αρκετά χωρίς απώλειες)
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.
Σημειώσεις υλοποίησης:
- 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.
## Ελάχιστο περίγραμμα parsing (Python)
Ακολουθεί ένα συμπαγές περίγραμμα που δείχνει τη ροή ελέγχου για τον εντοπισμό και την αποκωδικοποίηση των entitlements. Εσκεμμένα παραλείπει αυστηρούς ελέγχους ορίων και πλήρη υποστήριξη fat binaries για συντομία.
```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
```
Συμβουλές χρήσης:
- Για να χειριστείτε fat binaries, πρώτα διαβάστε struct fat_header/fat_arch, επιλέξτε το επιθυμητό architecture slice, και στη συνέχεια περάστε το subrange στο parse_entitlements.
- Σε macOS μπορείτε να επικυρώσετε τα αποτελέσματα με: codesign -d --entitlements :- /path/to/binary
## Example findings
Privileged platform binaries often request sensitive entitlements such as:
- com.apple.security.network.server = true
- com.apple.rootless.storage.early_boot_mount = true
- com.apple.private.kernel.system-override = true
- com.apple.private.pmap.load-trust-cache = ["cryptex1.boot.os", "cryptex1.boot.app", "cryptex1.safari-downlevel"]
Η αναζήτηση αυτών σε μεγάλη κλίμακα σε firmware images είναι εξαιρετικά πολύτιμη για attack surface mapping και diffing across releases/devices.
## Scaling across IPSWs (mounting and indexing)
Για να απαριθμήσετε εκτελέσιμα και να εξαγάγετε entitlements σε μεγάλη κλίμακα χωρίς να αποθηκεύετε ολόκληρες εικόνες:
- Χρησιμοποιήστε το εργαλείο ipsw του @blacktop για να κατεβάσετε και να mount-άρετε τα firmware filesystems. Το mounting αξιοποιεί το apfs-fuse, οπότε μπορείτε να διασχίσετε APFS volumes χωρίς πλήρη εξαγωγή.
```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>
```
- Περιηγηθείτε στους mounted volumes για να εντοπίσετε Mach-O αρχεία (ελέγξτε magic και/ή χρησιμοποιήστε file/otool), και στη συνέχεια αναλύστε entitlements και εισαγόμενα frameworks.
- Διατηρήστε μια κανονικοποιημένη προβολή σε μια relational database για να αποφύγετε γραμμική αύξηση σε χιλιάδες IPSWs:
- executables, operating_system_versions, entitlements, frameworks
- many-to-many: executable↔OS version, executable↔entitlement, executable↔framework
Παράδειγμα query για να απαριθμήσετε όλες τις OS versions που περιέχουν ένα συγκεκριμένο 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";
```
Σημειώσεις για φορητότητα DB (αν υλοποιήσετε τον δικό σας indexer):
- Use an ORM/abstraction (π.χ., SeaORM) για να κρατήσετε τον κώδικα ανεξάρτητο από τη βάση (SQLite/PostgreSQL).
- Το SQLite απαιτεί το AUTOINCREMENT μόνο σε ένα INTEGER PRIMARY KEY· αν θέλετε i64 PKs σε Rust, δημιουργήστε οντότητες ως i32 και κάντε convert τύπων, το SQLite αποθηκεύει INTEGER ως 8-byte signed εσωτερικά.
## Open-source tooling and references for entitlement hunting
- Firmware mount/download: https://github.com/blacktop/ipsw
- Entitlement databases and references:
- Jonathan Levins entitlement DB: https://newosxbook.com/ent.php
- entdb: https://github.com/ChiChou/entdb
- Large-scale indexer (Rust, self-hosted Web UI + OpenAPI): https://github.com/synacktiv/appledb_rs
- Apple headers for structures and constants:
- loader.h (Mach-O headers, load commands)
- cs_blobs.h (SuperBlob, GenericBlob, CodeDirectory)
Για περισσότερα για τα code signing internals (Code Directory, special slots, DER entitlements), δείτε: [macOS Code Signing](../../../macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md)
## Αναφορές
- [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 Levins 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}}

View File

@ -1,6 +1,78 @@
# macOS Universal binaries & Mach-O Format
{{#
{{#include ../../../banners/hacktricks-training.md}}
## Βασικές Πληροφορίες
Τα binaries του Mac OS συνήθως μεταγλωττίζονται ως **universal binaries**. Ένα **universal binary** μπορεί να **υποστηρίξει πολλαπλές αρχιτεκτονικές στο ίδιο αρχείο**.
Αυτά τα binaries ακολουθούν τη **Mach-O δομή** η οποία βασικά αποτελείται από:
- Κεφαλίδα
- Εντολές Φόρτωσης (Load Commands)
- Δεδομένα
![https://alexdremov.me/content/images/2022/10/6XLCD.gif](<../../../images/image (470).png>)
## Fat Header
Search for the file with: `mdfind fat.h | grep -i mach-o | grep -E "fat.h$"`
<pre class="language-c"><code class="lang-c"><strong>#define FAT_MAGIC 0xcafebabe
</strong><strong>#define FAT_CIGAM 0xbebafeca /* NXSwapLong(FAT_MAGIC) */
</strong>
struct fat_header {
<strong> uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */
</strong><strong> uint32_t nfat_arch; /* number of structs that follow */
</strong>};
struct fat_arch {
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>
Η κεφαλίδα περιέχει τα **magic** bytes ακολουθούμενα από τον **αριθμό** των **αρχιτεκτονικών** που το αρχείο **περιέχει** (`nfat_arch`) και κάθε αρχιτεκτονική θα έχει μια δομή `fat_arch`.
Check it with:
<pre class="language-shell-session"><code class="lang-shell-session">% file /bin/ls
/bin/ls: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
/bin/ls (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>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>architecture arm64e
</strong> cputype CPU_TYPE_ARM64
cpusubtype CPU_SUBTYPE_ARM64E
capabilities PTR_AUTH_VERSION USERSPACE 0
<strong> offset 98304
</strong><strong> size 88816
</strong> align 2^14 (16384)
</code></pre>
or using the [Mach-O View](https://sourceforge.net/projects/machoview/) tool:
<figure><img src="../../../images/image (1094).png" alt=""><figcaption></figcaption></figure>
Όπως ίσως σκέφτεστε, συνήθως ένα universal binary που έχει μεταγλωττιστεί για 2 αρχιτεκτονικές **διπλασιάζει το μέγεθος** σε σχέση με ένα που έχει μεταγλωττιστεί για μόνον 1 αρχιτεκτονική.
## **Mach-O Header**
Η κεφαλίδα περιέχει βασικές πληροφορίες για το αρχείο, όπως τα magic bytes που το προσδιορίζουν ως Mach-O αρχείο και πληροφορίες σχετικά με την στοχευόμενη αρχιτεκτονική. Μπορείτε να τη βρείτε με: `mdfind loader.h | grep -i mach-o | grep -E "loader.h$"`
```c
#define MH_MAGIC 0xfeedface /* the mach magic number */
#define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */
@ -27,20 +99,20 @@ uint32_t flags; /* flags */
uint32_t reserved; /* reserved */
};
```
### Mach-O Τύποι Αρχείων
### Mach-O File Types
Υπάρχουν διάφοροι τύποι αρχείων, μπορείτε να τους βρείτε καθορισμένους στον [**πηγαίο κώδικα για παράδειγμα εδώ**](https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h). Οι πιο σημαντικοί είναι:
Υπάρχουν διάφοροι τύποι αρχείων· μπορείτε να τους βρείτε ορισμένους στον [**source code for example here**](https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h). Οι πιο σημαντικοί είναι:
- `MH_OBJECT`: Μεταθέσιμο αρχείο αντικειμένου (ενδιάμεσα προϊόντα της μεταγλώττισης, όχι εκτελέσιμα ακόμα).
- `MH_OBJECT`: Αρχείο αντικειμένου με δυνατότητα επανατοποθέτησης (ενδιάμεσα προϊόντα της μεταγλώττισης — όχι ακόμη εκτελέσιμα).
- `MH_EXECUTE`: Εκτελέσιμα αρχεία.
- `MH_FVMLIB`: Στατικό αρχείο βιβλιοθήκης VM.
- `MH_CORE`: Εκφορτώσεις Κώδικα
- `MH_PRELOAD`: Προφορτωμένο εκτελέσιμο αρχείο (δεν υποστηρίζεται πλέον στο XNU)
- `MH_DYLIB`: Δυναμικές Βιβλιοθήκες
- `MH_DYLINKER`: Δυναμικός Συνδέτης
- `MH_BUNDLE`: "Αρχεία Plugin". Δημιουργούνται χρησιμοποιώντας -bundle στο gcc και φορτώνονται ρητά από το `NSBundle` ή το `dlopen`.
- `MH_DYSM`: Συνοδευτικό αρχείο `.dSym` (αρχείο με σύμβολα για αποσφαλμάτωση).
- `MH_KEXT_BUNDLE`: Επεκτάσεις Πυρήνα.
- `MH_FVMLIB`: Αρχείο βιβλιοθήκης για Fixed VM.
- `MH_CORE`: Αρχεία dump κώδικα.
- `MH_PRELOAD`: Προφορτωμένο εκτελέσιμο αρχείο (πλέον δεν υποστηρίζεται στο XNU)
- `MH_DYLIB`: Δυναμικές βιβλιοθήκες
- `MH_DYLINKER`: Δυναμικός linker
- `MH_BUNDLE`: "Plugin files". Παράγονται χρησιμοποιώντας -bundle στο gcc και φορτώνονται ρητά από `NSBundle` ή `dlopen`.
- `MH_DYSM`: Συνοδευτικό `.dSym` αρχείο (αρχείο με σύμβολα για αποσφαλμάτωση).
- `MH_KEXT_BUNDLE`: Επεκτάσεις πυρήνα.
```bash
# Checking the mac header of a binary
otool -arch arm64e -hv /bin/ls
@ -56,46 +128,46 @@ MH_MAGIC_64 ARM64 E USR00 EXECUTE 19 1728 NOUNDEFS DY
Ο πηγαίος κώδικας ορίζει επίσης αρκετές σημαίες χρήσιμες για τη φόρτωση βιβλιοθηκών:
- `MH_NOUNDEFS`: Χωρίς μη καθορισμένες αναφορές (πλήρως συνδεδεμένο)
- `MH_DYLDLINK`: Σύνδεση Dyld
- `MH_PREBOUND`: Δυναμικές αναφορές προδεσμευμένες.
- `MH_SPLIT_SEGS`: Το αρχείο διαχωρίζει τα τμήματα r/o και r/w.
- `MH_WEAK_DEFINES`: Το δυαδικό έχει αδύνατα καθορισμένα σύμβολα
- `MH_BINDS_TO_WEAK`: Το δυαδικό χρησιμοποιεί αδύνατα σύμβολα
- `MH_ALLOW_STACK_EXECUTION`: Κάνει τη στοίβα εκτελέσιμη
- `MH_NOUNDEFS`: Καμία μη ορισμένη αναφορά (πλήρως συνδεδεμένο)
- `MH_DYLDLINK`: Σύνδεση dyld
- `MH_PREBOUND`: Οι δυναμικές αναφορές είναι προδεσμευμένες
- `MH_SPLIT_SEGS`: Το αρχείο χωρίζει τμήματα r/o και r/w
- `MH_WEAK_DEFINES`: Το δυαδικό έχει αδύναμα ορισμένα σύμβολα
- `MH_BINDS_TO_WEAK`: Το δυαδικό χρησιμοποιεί αδύναμα σύμβολα
- `MH_ALLOW_STACK_EXECUTION`: Κάνει την στοίβα εκτελέσιμη
- `MH_NO_REEXPORTED_DYLIBS`: Η βιβλιοθήκη δεν έχει εντολές LC_REEXPORT
- `MH_PIE`: Εκτελέσιμο ανεξάρτητης θέσης
- `MH_HAS_TLV_DESCRIPTORS`: Υπάρχει τμήμα με τοπικές μεταβλητές νήματος
- `MH_NO_HEAP_EXECUTION`: Καμία εκτέλεση για σελίδες heap/data
- `MH_HAS_OBJC`: Το δυαδικό έχει τμήματα oBject-C
- `MH_PIE`: Θέση-ανεξάρτητο εκτελέσιμο
- `MH_HAS_TLV_DESCRIPTORS`: Υπάρχει ενότητα με thread-local μεταβλητές
- `MH_NO_HEAP_EXECUTION`: Απαγορεύεται η εκτέλεση για σελίδες heap/data
- `MH_HAS_OBJC`: Το δυαδικό έχει τμήματα Objective-C
- `MH_SIM_SUPPORT`: Υποστήριξη προσομοιωτή
- `MH_DYLIB_IN_CACHE`: Χρησιμοποιείται σε dylibs/frameworks στην κοινή βιβλιοθήκη cache.
- `MH_DYLIB_IN_CACHE`: Χρησιμοποιείται σε dylibs/frameworks στην cache κοινής βιβλιοθήκης
## **Εντολές φόρτωσης Mach-O**
Η **διάταξη του αρχείου στη μνήμη** καθορίζεται εδώ, περιγράφοντας την **τοποθεσία του πίνακα συμβόλων**, το πλαίσιο του κύριου νήματος κατά την εκκίνηση εκτέλεσης και τις απαιτούμενες **κοινές βιβλιοθήκες**. Δίνονται οδηγίες στον δυναμικό φορτωτή **(dyld)** για τη διαδικασία φόρτωσης του δυαδικού στη μνήμη.
Η διάταξη του αρχείου στη μνήμη καθορίζεται εδώ, περιγράφοντας λεπτομερώς τη θέση του πίνακα συμβόλων, το πλαίσιο του κύριου νήματος κατά την έναρξη εκτέλεσης, και τις απαιτούμενες shared libraries. Παρέχονται οδηγίες στον dynamic loader **(dyld)** σχετικά με τη διαδικασία φόρτωσης του δυαδικού στη μνήμη.
Χρησιμοποιεί τη δομή **load_command**, που ορίζεται στο αναφερόμενο **`loader.h`**:
Χρησιμοποιεί τη δομή **load_command**, ορισμένη στο προαναφερθέν **`loader.h`**:
```objectivec
struct load_command {
uint32_t cmd; /* type of load command */
uint32_t cmdsize; /* total size of command in bytes */
};
```
Υπάρχουν περίπου **50 διαφορετικοί τύποι εντολών φόρτωσης** που το σύστημα χειρίζεται διαφορετικά. Οι πιο κοινοί είναι: `LC_SEGMENT_64`, `LC_LOAD_DYLINKER`, `LC_MAIN`, `LC_LOAD_DYLIB` και `LC_CODE_SIGNATURE`.
Υπάρχουν περίπου **50 διαφορετικοί τύποι εντολών φόρτωσης** που το σύστημα χειρίζεται διαφορετικά. Οι πιο συνηθισμένοι είναι: `LC_SEGMENT_64`, `LC_LOAD_DYLINKER`, `LC_MAIN`, `LC_LOAD_DYLIB`, και `LC_CODE_SIGNATURE`.
### **LC_SEGMENT/LC_SEGMENT_64**
> [!TIP]
> Βασικά, αυτός ο τύπος Εντολής Φόρτωσης καθορίζει **πώς να φορτώσει το \_\_TEXT** (εκτελέσιμο κώδικα) **και το \_\_DATA** (δεδομένα για τη διαδικασία) **τμήματα** σύμφωνα με τους **offsets που υποδεικνύονται στην ενότητα Δεδομένων** όταν εκτελείται το δυαδικό.
> Βασικά, αυτός ο τύπος εντολής φόρτωσης ορίζει **πώς να φορτωθούν τα \_\_TEXT** (εκτελέσιμος κώδικας) **και \_\_DATA** (δεδομένα για τη διεργασία) **τμήματα** σύμφωνα με τις **μετατοπίσεις που υποδεικνύονται στην ενότητα δεδομένων** όταν το binary εκτελείται.
Αυτές οι εντολές **καθορίζουν τμήματα** που είναι **χαρτογραφημένα** στο **εικονικό χώρο μνήμης** μιας διαδικασίας όταν εκτελείται.
Αυτές οι εντολές **ορίζουν τμήματα** που **χαρτογραφούνται** στον **εικονικό χώρο μνήμης** μιας διεργασίας όταν αυτή εκτελείται.
Υπάρχουν **διαφορετικοί τύποι** τμημάτων, όπως το **\_\_TEXT** τμήμα, το οποίο περιέχει τον εκτελέσιμο κώδικα ενός προγράμματος, και το **\_\_DATA** τμήμα, το οποίο περιέχει δεδομένα που χρησιμοποιούνται από τη διαδικασία. Αυτά τα **τμήματα βρίσκονται στην ενότητα δεδομένων** του αρχείου Mach-O.
Υπάρχουν **διάφοροι τύποι** τμημάτων, όπως το τμήμα **\_\_TEXT**, που περιέχει τον εκτελέσιμο κώδικα ενός προγράμματος, και το τμήμα **\_\_DATA**, που περιέχει δεδομένα που χρησιμοποιούνται από τη διεργασία. Αυτά τα **τμήματα βρίσκονται στην ενότητα δεδομένων** του αρχείου Mach-O.
**Κάθε τμήμα** μπορεί να **διαιρεθεί** περαιτέρω σε πολλαπλές **ενότητες**. Η **δομή εντολής φόρτωσης** περιέχει **πληροφορίες** σχετικά με **αυτές τις ενότητες** εντός του αντίστοιχου τμήματος.
**Κάθε τμήμα** μπορεί να διαιρεθεί περαιτέρω σε πολλαπλές **sections**. Η **δομή της εντολής φόρτωσης** περιέχει **πληροφορίες** για **αυτές τις sections** μέσα στο αντίστοιχο τμήμα.
Στην κεφαλίδα πρώτα βρίσκετε την **κεφαλίδα τμήματος**:
Στην κεφαλίδα πρώτα θα βρείτε την **κεφαλίδα τμήματος**:
<pre class="language-c"><code class="lang-c">struct segment_command_64 { /* for 64-bit architectures */
uint32_t cmd; /* LC_SEGMENT_64 */
@ -116,7 +188,7 @@ int32_t initprot; /* initial VM protection */
<figure><img src="../../../images/image (1126).png" alt=""><figcaption></figcaption></figure>
Αυτή η κεφαλίδα καθορίζει τον **αριθμό των ενοτήτων των οποίων οι κεφαλίδες εμφανίζονται μετά** από αυτήν:
Αυτή η κεφαλίδα ορίζει τον **αριθμό των sections των οποίων οι κεφαλίδες εμφανίζονται μετά** από αυτή:
```c
struct section_64 { /* for 64-bit architectures */
char sectname[16]; /* name of this section */
@ -133,62 +205,64 @@ uint32_t reserved2; /* reserved (for count or sizeof) */
uint32_t reserved3; /* reserved */
};
```
Παράδειγμα **επικεφαλίδας ενότητας**:
<figure><img src="../../../images/image (1108).png" alt=""><figcaption></figcaption></figure>
Αν **προσθέσετε** την **εκτροπή ενότητας** (0x37DC) + την **εκτροπή** όπου **ξεκινά η αρχιτεκτονική**, σε αυτή την περίπτωση `0x18000` --> `0x37DC + 0x18000 = 0x1B7DC`
Παράδειγμα **επικεφαλίδας τμήματος**:
<figure><img src="../../../images/image (701).png" alt=""><figcaption></figcaption></figure>
Είναι επίσης δυνατό να αποκτήσετε **πληροφορίες επικεφαλίδων** από τη **γραμμή εντολών** με:
Εάν **προσθέσετε** την **μετατόπιση τμήματος** (0x37DC) + την **μετατόπιση** όπου **η arch ξεκινά**, σε αυτή την περίπτωση `0x18000` --> `0x37DC + 0x18000 = 0x1B7DC`
<figure><img src="../../../images/image (701).png" alt=""><figcaption></figcaption></figure>
Είναι επίσης δυνατό να λάβετε πληροφορίες **κεφαλίδων** από τη **γραμμή εντολών** με:
```bash
otool -lv /bin/ls
```
Κοινά τμήματα που φορτώνονται από αυτή την εντολή:
Κοινά τμήματα που φορτώνονται από αυτήν την εντολή:
- **`__PAGEZERO`:** Δίνει εντολή στον πυρήνα να **χαρτογραφήσει** τη **διεύθυνση μηδέν** έτσι ώστε να **μην μπορεί να διαβαστεί, να γραφτεί ή να εκτελεστεί**. Οι μεταβλητές maxprot και minprot στη δομή είναι ρυθμισμένες σε μηδέν για να υποδείξουν ότι δεν υπάρχουν **δικαιώματα ανάγνωσης-γραφής-εκτέλεσης σε αυτή τη σελίδα**.
- Αυτή η κατανομή είναι σημαντική για να **μειώσει τις ευπάθειες αποδόμησης δείκτη NULL**. Αυτό συμβαίνει επειδή το XNU επιβάλλει μια σκληρή σελίδα μηδέν που διασφαλίζει ότι η πρώτη σελίδα (μόνο η πρώτη) της μνήμης είναι μη προσβάσιμη (εκτός από το i386). Ένα δυαδικό αρχείο θα μπορούσε να πληροί αυτές τις απαιτήσεις δημιουργώντας μια μικρή \_\_PAGEZERO (χρησιμοποιώντας το `-pagezero_size`) για να καλύψει τα πρώτα 4k και να έχει την υπόλοιπη μνήμη 32bit προσβάσιμη τόσο σε λειτουργία χρήστη όσο και σε λειτουργία πυρήνα.
- **`__TEXT`**: Περιέχει **εκτελέσιμο** **κώδικα** με **δικαιώματα ανάγνωσης** και **εκτέλεσης** (όχι εγγράψιμα)**.** Κοινές ενότητες αυτού του τμήματος:
- `__text`: Συμπιεσμένος δυαδικός κώδικας
- **`__PAGEZERO`:** Δίνει οδηγία στον kernel να **χαρτογραφήσει** τη **διεύθυνση μηδέν** ώστε **να μην μπορεί να διαβαστεί, να γραφτεί ή να εκτελεστεί**. Οι μεταβλητές maxprot και minprot στη δομή τίθενται στο μηδέν για να υποδείξουν ότι **δεν υπάρχουν δικαιώματα ανάγνωσης-εγγραφής-εκτέλεσης σε αυτή τη σελίδα**.
- Αυτή η κατανομή είναι σημαντική για να **μειώσει τις ευπάθειες NULL pointer dereference**. Αυτό συμβαίνει επειδή το XNU επιβάλλει μια σκληρή σελίδα μηδέν που εξασφαλίζει ότι η πρώτη σελίδα (μόνο η πρώτη) της μνήμης είναι μη προσβάσιμη (εκτός σε i386). Ένα binary μπορεί να ικανοποιήσει αυτή την απαίτηση δημιουργώντας ένα μικρό __PAGEZERO (χρησιμοποιώντας την επιλογή `-pagezero_size`) για να καλύψει τα πρώτα 4k και να έχει το υπόλοιπο της 32bit μνήμης προσβάσιμο τόσο σε user όσο και σε kernel mode.
- **`__TEXT`**: Περιέχει **εκτελέσιμο** **κώδικα** με δικαιώματα **ανάγνωσης** και **εκτέλεσης** (χωρίς εγγραφή). Κοινές ενότητες αυτού του segment:
- `__text`: Συνταγμένος κώδικας του binary
- `__const`: Σταθερά δεδομένα (μόνο ανάγνωση)
- `__[c/u/os_log]string`: Σταθερές συμβολοσειρές C, Unicode ή os logs
- `__stubs` και `__stubs_helper`: Συμμετέχουν κατά τη διαδικασία φόρτωσης δυναμικής βιβλιοθήκης
- `__unwind_info`: Δεδομένα αποδόμησης στοίβας.
- Σημειώστε ότι όλο αυτό το περιεχόμενο είναι υπογεγραμμένο αλλά και επισημασμένο ως εκτελέσιμο (δημιουργώντας περισσότερες επιλογές για εκμετάλλευση τμημάτων που δεν χρειάζονται απαραίτητα αυτό το προνόμιο, όπως οι τμήματα που είναι αφιερωμένα σε συμβολοσειρές).
- **`__DATA`**: Περιέχει δεδομένα που είναι **αναγνώσιμα** και **γραφόμενα** (όχι εκτελέσιμα)**.**
- `__got:` Παγκόσμιος Πίνακας Μεταθέσεων
- `__nl_symbol_ptr`: Μη τεμπέλης (δεσμευμένος κατά τη φόρτωση) δείκτης συμβόλου
- `__la_symbol_ptr`: Τεμπέλης (δεσμευμένος κατά τη χρήση) δείκτης συμβόλου
- `__const`: Θα έπρεπε να είναι δεδομένα μόνο ανάγνωσης (όχι πραγματικά)
- `__cfstring`: Συμβολοσειρές CoreFoundation
- `__[c/u/os_log]string`: Σταθερές συμβολοσειρές C, Unicode ή os log
- `__stubs` και `__stubs_helper`: Εμπλέκονται στη διαδικασία δυναμικής φόρτωσης βιβλιοθηκών
- `__unwind_info`: Δεδομένα αποκατάστασης στοίβας (stack unwind)
- Σημειώστε ότι όλο αυτό το περιεχόμενο είναι υπογεγραμμένο αλλά επίσης επισημασμένο ως εκτελέσιμο (δημιουργώντας περισσότερες επιλογές για εκμετάλλευση τμημάτων που δεν χρειάζονται απαραίτητα αυτό το προνόμιο, όπως τμήματα αφιερωμένα σε συμβολοσειρές).
- **`__DATA`**: Περιέχει δεδομένα που είναι **αναγνώσιμα** και **εγγράψιμα** (χωρίς εκτέλεση).
- `__got`: Global Offset Table
- `__nl_symbol_ptr`: Non-lazy (bind at load) pointer συμβόλων
- `__la_symbol_ptr`: Lazy (bind on use) pointer συμβόλων
- `__const`: Θα έπρεπε να είναι δεδομένα μόνο ανάγνωσης (δεν είναι πάντα)
- `__cfstring`: CoreFoundation συμβολοσειρές
- `__data`: Παγκόσμιες μεταβλητές (που έχουν αρχικοποιηθεί)
- `__bss`: Στατικές μεταβλητές (που δεν έχουν αρχικοποιηθεί)
- `__objc_*` (\_\_objc_classlist, \_\_objc_protolist, κ.λπ.): Πληροφορίες που χρησιμοποιούνται από το Objective-C runtime
- **`__DATA_CONST`**: \_\_DATA.\_\_const δεν εγγυάται ότι είναι σταθερό (δικαιώματα εγγραφής), ούτε είναι άλλοι δείκτες και ο GOT. Αυτή η ενότητα καθιστά το `__const`, κάποιους αρχικοποιητές και τον πίνακα GOT (μόλις επιλυθεί) **μόνο ανάγνωσης** χρησιμοποιώντας το `mprotect`.
- **`__LINKEDIT`**: Περιέχει πληροφορίες για τον συνδέτη (dyld) όπως, συμβόλων, συμβολοσειρών και καταχωρήσεων πίνακα μεταθέσεων. Είναι ένας γενικός κάδος για περιεχόμενα που δεν βρίσκονται ούτε στο `__TEXT` ούτε στο `__DATA` και το περιεχόμενό του περιγράφεται σε άλλες εντολές φόρτωσης.
- πληροφορίες dyld: Επαναφορά, Μη τεμπέλης/τεμπέλης/ασθενής κωδικοί δέσμευσης και πληροφορίες εξαγωγής
- Λειτουργίες εκκίνησης: Πίνακας διευθύνσεων εκκίνησης λειτουργιών
- Δεδομένα στον Κώδικα: Νησίδες δεδομένων στο \_\_text
- Πίνακας Συμβόλων: Συμβολα σε δυαδικό
- Πίνακας Έμμεσων Συμβόλων: Δείκτες/συμβολα στήριξης
- `__objc_*` (__objc_classlist, __objc_protolist, κ.λπ.): Πληροφορίες που χρησιμοποιούνται από το Objective-C runtime
- **`__DATA_CONST`**: Το __DATA.__const δεν είναι εγγυημένο ότι είναι σταθερό (έχει δικαιώματα εγγραφής), ούτε και άλλοι pointers και το GOT. Αυτό το τμήμα καθιστά το `__const`, μερικούς αρχικοποιητές και τον πίνακα GOT (μόλις επιλυθεί) **μόνο για ανάγνωση** χρησιμοποιώντας `mprotect`.
- **`__LINKEDIT`**: Περιέχει πληροφορίες για τον linker (dyld) όπως εγγραφές πινάκων συμβόλων, συμβολοσειρών και relocation. Είναι ένας γενικός κοντέινερ για περιεχόμενο που δεν ανήκει στο `__TEXT` ή το `__DATA` και το περιεχόμενό του περιγράφεται σε άλλες load commands.
- dyld πληροφορίες: Rebase, Non-lazy/lazy/weak binding opcodes και export info
- Functions starts: Πίνακας διευθύνσεων εκκίνησης συναρτήσεων
- Data In Code: Νησίδες δεδομένων μέσα στο `__text`
- Πίνακας Συμβόλων: Σύμβολα μέσα στο binary
- Έμμεσος Πίνακας Συμβόλων: Pointer/stub σύμβολα
- Πίνακας Συμβολοσειρών
- Υπογραφή Κώδικα
- **`__OBJC`**: Περιέχει πληροφορίες που χρησιμοποιούνται από το Objective-C runtime. Αν και αυτές οι πληροφορίες μπορεί επίσης να βρεθούν στο τμήμα \_\_DATA, μέσα σε διάφορες ενότητες \_\_objc\_\*.
- **`__RESTRICT`**: Ένα τμήμα χωρίς περιεχόμενο με μια μόνο ενότητα που ονομάζεται **`__restrict`** (επίσης κενή) που διασφαλίζει ότι κατά την εκτέλεση του δυαδικού αρχείου, θα αγνοήσει τις μεταβλητές περιβάλλοντος DYLD.
- **`__OBJC`**: Περιέχει πληροφορίες που χρησιμοποιούνται από το Objective-C runtime. Παρόλο που αυτές οι πληροφορίες μπορεί επίσης να βρεθούν στο τμήμα `__DATA`, μέσα σε διάφορα `__objc_*` sections.
- **`__RESTRICT`**: Ένα segment χωρίς περιεχόμενο με μία ενότητα που ονομάζεται **`__restrict`** (επίσης κενή) που εξασφαλίζει ότι κατά την εκτέλεση του binary θα αγνοεί τις περιβαλλοντικές μεταβλητές του DYLD.
Όπως ήταν δυνατόν να δούμε στον κώδικα, **τα τμήματα υποστηρίζουν επίσης σημαίες** (αν και δεν χρησιμοποιούνται πολύ):
Όπως φαίνεται στον κώδικα, **τα segments υποστηρίζουν επίσης flags** (αν και δεν χρησιμοποιούνται πολύ):
- `SG_HIGHVM`: Μόνο πυρήνας (δεν χρησιμοποιείται)
- `SG_FVMLIB`: Δεν χρησιμοποιείται
- `SG_NORELOC`: Το τμήμα δεν έχει μεταθέσεις
- `SG_PROTECTED_VERSION_1`: Κρυπτογράφηση. Χρησιμοποιείται για παράδειγμα από τον Finder για να κρυπτογραφήσει το τμήμα `__TEXT`.
- `SG_HIGHVM`: Core only (όχι χρησιμοποιούμενο)
- `SG_FVMLIB`: Όχι χρησιμοποιούμενο
- `SG_NORELOC`: Το segment δεν έχει relocation
- `SG_PROTECTED_VERSION_1`: Κρυπτογράφηση. Χρησιμοποιείται για παράδειγμα από το Finder για να κρυπτογραφήσει το `__TEXT` segment.
### **`LC_UNIXTHREAD/LC_MAIN`**
**`LC_MAIN`** περιέχει το σημείο εισόδου στην **ιδιότητα entryoff.** Κατά τη διάρκεια της φόρτωσης, το **dyld** απλά **προσθέτει** αυτή την τιμή στη (στη μνήμη) **βάση του δυαδικού αρχείου**, στη συνέχεια **πηδά** σε αυτή την εντολή για να ξεκινήσει την εκτέλεση του κώδικα του δυαδικού αρχείου.
**`LC_MAIN`** περιέχει το entrypoint στο **entryoff attribute.** Κατά το φόρτωμα, ο **dyld** απλώς **προσθέτει** αυτή την τιμή στη (στη μνήμη) **βάση του binary**, και στη συνέχεια **πηδάει** σε αυτή την εντολή για να ξεκινήσει η εκτέλεση του κώδικα του binary.
**`LC_UNIXTHREAD`** περιέχει τις τιμές που πρέπει να έχει ο καταχωρητής κατά την εκκίνηση του κύριου νήματος. Αυτό έχει ήδη αποσυρθεί αλλά το **`dyld`** εξακολουθεί να το χρησιμοποιεί. Είναι δυνατόν να δει κανείς τις τιμές των καταχωρητών που ορίζονται από αυτό με:
**`LC_UNIXTHREAD`** περιέχει τις τιμές που πρέπει να έχουν οι καταχωρητές κατά την εκκίνηση του main thread. Αυτό έχει ήδη αποσυρθεί αλλά ο **`dyld`** εξακολουθεί να το χρησιμοποιεί. Είναι δυνατόν να δείτε τις τιμές των καταχωρητών που θέτει αυτό με:
```bash
otool -l /usr/lib/dyld
[...]
@ -214,34 +288,39 @@ cpsr 0x00000000
```
### **`LC_CODE_SIGNATURE`**
Περιέχει πληροφορίες σχετικά με την **υπογραφή κώδικα του αρχείου Macho-O**. Περιέχει μόνο μια **μετατόπιση** που **δείχνει** στο **blob υπογραφής**. Αυτό είναι συνήθως στο τέλος του αρχείου.\
Ωστόσο, μπορείτε να βρείτε κάποιες πληροφορίες σχετικά με αυτή την ενότητα σε [**αυτή την ανάρτηση στο blog**](https://davedelong.com/blog/2018/01/10/reading-your-own-entitlements/) και σε αυτό το [**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}}
Περιέχει πληροφορίες για την **υπογραφή κώδικα του Mach-O αρχείου**. Περιλαμβάνει μόνο ένα **offset** που **δείχνει** στο **signature blob**. Αυτό βρίσκεται τυπικά στο τέλος του αρχείου.\
Ωστόσο, μπορείτε να βρείτε κάποιες πληροφορίες για αυτή την ενότητα στο [**this blog post**](https://davedelong.com/blog/2018/01/10/reading-your-own-entitlements/) και αυτό το [**gists**](https://gist.github.com/carlospolop/ef26f8eb9fafd4bc22e69e1a32b81da4).
### **`LC_ENCRYPTION_INFO[_64]`**
Υποστήριξη για κρυπτογράφηση δυαδικών αρχείων. Ωστόσο, φυσικά, αν ένας επιτιθέμενος καταφέρει να παραβιάσει τη διαδικασία, θα μπορεί να εκφορτώσει τη μνήμη χωρίς κρυπτογράφηση.
Υποστήριξη για κρυπτογράφηση του binary. Ωστόσο, φυσικά, αν ένας επιτιθέμενος καταφέρει να συμβιβάσει τη διεργασία, θα μπορεί να dump τη μνήμη μη κρυπτογραφημένη.
### **`LC_LOAD_DYLINKER`**
Περιέχει την **διαδρομή προς το εκτελέσιμο αρχείο του δυναμικού συνδέτη** που χαρτογραφεί τις κοινές βιβλιοθήκες στον χώρο διευθύνσεων της διαδικασίας. Η **τιμή είναι πάντα ρυθμισμένη σε `/usr/lib/dyld`**. Είναι σημαντικό να σημειωθεί ότι στο macOS, η χαρτογράφηση dylib συμβαίνει σε **λειτουργία χρήστη**, όχι σε λειτουργία πυρήνα.
Περιέχει την **διαδρομή προς το εκτελέσιμο του dynamic linker** που χαρτογραφεί τις shared libraries στον address space της διεργασίας. Η **τιμή είναι πάντα ορισμένη σε `/usr/lib/dyld`**. Είναι σημαντικό να σημειωθεί ότι στο macOS, το mapping των dylib γίνεται σε **λειτουργία χρήστη**, όχι σε λειτουργία πυρήνα.
### **`LC_IDENT`**
Απαρχαιωμένο αλλά όταν ρυθμίζεται για να δημιουργεί εκφορτώσεις σε πανικό, δημιουργείται μια πυρήνα Mach-O και η έκδοση του πυρήνα ρυθμίζεται στην εντολή `LC_IDENT`.
Παρωχημένο, αλλά όταν ρυθμιστεί να δημιουργεί dumps σε panic, δημιουργείται ένα Mach-O core dump και η έκδοση του πυρήνα ορίζεται στην εντολή `LC_IDENT`.
### **`LC_UUID`**
Τυχαίο UUID. Είναι χρήσιμο για οτιδήποτε άμεσα αλλά το XNU το αποθηκεύει με τις υπόλοιπες πληροφορίες της διαδικασίας. Μπορεί να χρησιμοποιηθεί σε αναφορές σφαλμάτων.
Τυχαίο UUID. Δεν είναι ιδιαίτερα χρήσιμο από μόνο του, αλλά το XNU το αποθηκεύει στην cache μαζί με τις υπόλοιπες πληροφορίες της διεργασίας. Μπορεί να χρησιμοποιηθεί σε crash reports.
### **`LC_DYLD_ENVIRONMENT`**
Επιτρέπει την ένδειξη μεταβλητών περιβάλλοντος στο dyld πριν εκτελεστεί η διαδικασία. Αυτό μπορεί να είναι πολύ επικίνδυνο καθώς μπορεί να επιτρέψει την εκτέλεση αυθαίρετου κώδικα μέσα στη διαδικασία, οπότε αυτή η εντολή φόρτωσης χρησιμοποιείται μόνο σε dyld που έχει κατασκευαστεί με `#define SUPPORT_LC_DYLD_ENVIRONMENT` και περιορίζει περαιτέρω την επεξεργασία μόνο σε μεταβλητές της μορφής `DYLD_..._PATH` που καθορίζουν διαδρομές φόρτωσης.
Επιτρέπει τον καθορισμό μεταβλητών περιβάλλοντος για το dyld πριν εκτελεστεί η διεργασία. Αυτό μπορεί να είναι πολύ επικίνδυνο καθώς μπορεί να επιτρέψει την εκτέλεση αυθαίρετου κώδικα μέσα στη διεργασία, γι' αυτό αυτή η load command χρησιμοποιείται μόνο σε dyld build με `#define SUPPORT_LC_DYLD_ENVIRONMENT` και επιπλέον περιορίζει την επεξεργασία μόνο σε μεταβλητές της μορφής `DYLD_..._PATH` που καθορίζουν load paths.
### **`LC_LOAD_DYLIB`**
Αυτή η εντολή φόρτωσης περιγράφει μια **δυναμική** **εξάρτηση βιβλιοθήκης** που **δίνει οδηγίες** στον **φορτωτή** (dyld) να **φορτώσει και να συνδέσει την εν λόγω βιβλιοθήκη**. Υπάρχει μια εντολή φόρτωσης `LC_LOAD_DYLIB` **για κάθε βιβλιοθήκη** που απαιτεί το δυαδικό Mach-O.
Αυτή η εντολή φόρτωσης περιγράφει μια εξάρτηση από δυναμική βιβλιοθήκη που **εντοπίζει** τον **loader** (dyld) να **φορτώσει και να συνδέσει τη συγκεκριμένη βιβλιοθήκη**. Υπάρχει μια εντολή `LC_LOAD_DYLIB` **για κάθε βιβλιοθήκη** που απαιτεί το Mach-O binary.
- Αυτή η εντολή φόρτωσης είναι μια δομή τύπου **`dylib_command`** (η οποία περιέχει μια δομή dylib, περιγράφοντας την πραγματική εξαρτώμενη δυναμική βιβλιοθήκη):
- Αυτή η εντολή φόρτωσης είναι μια δομή τύπου **`dylib_command`** (η οποία περιέχει μια struct dylib, περιγράφοντας την πραγματική εξαρτώμενη δυναμική βιβλιοθήκη):
```objectivec
struct dylib_command {
uint32_t cmd; /* LC_LOAD_{,WEAK_}DYLIB */
@ -258,7 +337,7 @@ uint32_t compatibility_version; /* library's compatibility vers number*/
```
![](<../../../images/image (486).png>)
Μπορείτε επίσης να αποκτήσετε αυτές τις πληροφορίες από το cli με:
Μπορείτε επίσης να λάβετε αυτές τις πληροφορίες από το cli με:
```bash
otool -L /bin/ls
/bin/ls:
@ -266,53 +345,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)
```
Ορισμένες πιθανές βιβλιοθήκες που σχετίζονται με κακόβουλο λογισμικό είναι:
Some potential malware related libraries are:
- **DiskArbitration**: Παρακολούθηση USB drives
- **DiskArbitration**: Παρακολούθηση συσκευών USB
- **AVFoundation:** Καταγραφή ήχου και βίντεο
- **CoreWLAN**: Σαρώσεις Wifi.
> [!NOTE]
> Ένα Mach-O δυαδικό μπορεί να περιέχει έναν ή **περισσότερους** **κατασκευαστές**, που θα **εκτελούνται** **πριν** από τη διεύθυνση που καθορίζεται στο **LC_MAIN**.\
> Οι μετατοπίσεις οποιωνδήποτε κατασκευαστών κρατούνται στην ενότητα **\_\_mod_init_func** του τμήματος **\_\_DATA_CONST**.
## **Δεδομένα Mach-O**
Στον πυρήνα του αρχείου βρίσκεται η περιοχή δεδομένων, η οποία αποτελείται από αρκετά τμήματα όπως ορίζονται στην περιοχή εντολών φόρτωσης. **Μια ποικιλία τμημάτων δεδομένων μπορεί να φιλοξενηθεί μέσα σε κάθε τμήμα**, με κάθε τμήμα **να περιέχει κώδικα ή δεδομένα** συγκεκριμένα για έναν τύπο.
- **CoreWLAN**: Σάρωση WiFi.
> [!TIP]
> Τα δεδομένα είναι βασικά το μέρος που περιέχει όλες τις **πληροφορίες** που φορτώνονται από τις εντολές φόρτωσης **LC_SEGMENTS_64**
> Ένα αρχείο Mach-O μπορεί να περιέχει έναν ή **περισσότερους** **constructors**, οι οποίοι θα **εκτελεστούν** **πριν** από τη διεύθυνση που καθορίζεται στο **LC_MAIN**.\
> Οι offsets οποιωνδήποτε constructors κρατούνται στην ενότητα **\_\_mod_init_func** του segment **\_\_DATA_CONST**.
## **Mach-O Data**
Στον πυρήνα του αρχείου βρίσκεται η περιοχή δεδομένων, η οποία αποτελείται από διάφορα τμήματα όπως ορίζονται στην περιοχή load-commands. **Μια ποικιλία ενοτήτων δεδομένων μπορεί να φιλοξενηθεί μέσα σε κάθε τμήμα**, με κάθε ενότητα **να περιέχει κώδικα ή δεδομένα** ειδικά για έναν τύπο.
> [!TIP]
> Τα δεδομένα είναι ουσιαστικά το τμήμα που περιέχει όλες τις **πληροφορίες** που φορτώνονται από τις load commands **LC_SEGMENTS_64**
![https://www.oreilly.com/api/v2/epubs/9781785883378/files/graphics/B05055_02_38.jpg](<../../../images/image (507) (3).png>)
Αυτό περιλαμβάνει:
This includes:
- **Πίνακας συναρτήσεων:** Ο οποίος περιέχει πληροφορίες σχετικά με τις συναρτήσεις του προγράμματος.
- **Πίνακας συμβόλων**: Ο οποίος περιέχει πληροφορίες σχετικά με τη εξωτερική συνάρτηση που χρησιμοποιείται από το δυαδικό
- Μπορεί επίσης να περιέχει εσωτερικές συναρτήσεις, ονόματα μεταβλητών καθώς και περισσότερα.
- **Function table:** Που περιέχει πληροφορίες για τις συναρτήσεις του προγράμματος.
- **Symbol table**: Που περιέχει πληροφορίες για τις εξωτερικές συναρτήσεις που χρησιμοποιεί το binary
- Μπορεί επίσης να περιέχει εσωτερικές συναρτήσεις, ονόματα μεταβλητών και άλλα.
Για να το ελέγξετε μπορείτε να χρησιμοποιήσετε το [**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>
Ή από το cli:
Or from the cli:
```bash
size -m /bin/ls
```
## Objetive-C Κοινές Ενότητες
## Objetive-C Common Sections
Στο `__TEXT` τμήμα (r-x):
Στο τμήμα `__TEXT` (r-x):
- `__objc_classname`: Ονόματα κλάσεων (αλφαριθμητικά)
- `__objc_methname`: Ονόματα μεθόδων (αλφαριθμητικά)
- `__objc_methtype`: Τύποι μεθόδων (αλφαριθμητικά)
- `__objc_classname`: Ονόματα κλάσεων (συμβολοσειρές)
- `__objc_methname`: Ονόματα μεθόδων (συμβολοσειρές)
- `__objc_methtype`: Τύποι μεθόδων (συμβολοσειρές)
Στο `__DATA` τμήμα (rw-):
Στο τμήμα `__DATA` (rw-):
- `__objc_classlist`: Δείκτες σε όλες τις κλάσεις Objetive-C
- `__objc_nlclslist`: Δείκτες σε μη-τεμπέλικες κλάσεις Objective-C
- `__objc_catlist`: Δείκτης σε Κατηγορίες
- `__objc_nlcatlist`: Δείκτης σε μη-τεμπέλικες Κατηγορίες
- `__objc_classlist`: Δείκτες προς όλες τις κλάσεις Objetive-C
- `__objc_nlclslist`: Δείκτες προς Non-Lazy κλάσεις Objective-C
- `__objc_catlist`: Δείκτης σε Categories
- `__objc_nlcatlist`: Δείκτης σε Non-Lazy Categories
- `__objc_protolist`: Λίστα πρωτοκόλλων
- `__objc_const`: Σταθερά δεδομένα
- `__objc_imageinfo`, `__objc_selrefs`, `objc__protorefs`...

View File

@ -1,15 +1,20 @@
# macOS Code Signing
# Υπογραφή κώδικα macOS
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
## Βασικές Πληροφορίες
Τα Mach-o binaries περιέχουν μια εντολή φόρτωσης που ονομάζεται **`LC_CODE_SIGNATURE`** που υποδεικνύει την **offset** και το **size** των υπογραφών μέσα στο binary. Στην πραγματικότητα, χρησιμοποιώντας το εργαλείο GUI MachOView, είναι δυνατόν να βρείτε στο τέλος του binary μια ενότητα που ονομάζεται **Code Signature** με αυτές τις πληροφορίες:
{{#ref}}
../../../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md
{{#endref}}
Τα Mach-o binaries περιέχουν μια load command που ονομάζεται **`LC_CODE_SIGNATURE`** η οποία υποδεικνύει το **offset** και το **size** των signatures μέσα στο binary. Στην πραγματικότητα, χρησιμοποιώντας το GUI εργαλείο MachOView, είναι δυνατό να βρείτε στο τέλος του binary μια ενότητα που ονομάζεται **Code Signature** με αυτές τις πληροφορίες:
<figure><img src="../../../images/image (1) (1) (1) (1).png" alt="" width="431"><figcaption></figcaption></figure>
Η μαγική κεφαλίδα της Code Signature είναι **`0xFADE0CC0`**. Στη συνέχεια, έχετε πληροφορίες όπως το μήκος και τον αριθμό των blobs του superBlob που τα περιέχει.\
Είναι δυνατόν να βρείτε αυτές τις πληροφορίες στον [κώδικα πηγής εδώ](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L276):
Το magic header του Code Signature είναι **`0xFADE0CC0`**. Έπειτα υπάρχουν πληροφορίες όπως το length και ο αριθμός των blobs του superBlob που τα περιέχει.\
Είναι δυνατό να βρείτε αυτές τις πληροφορίες στον [source code εδώ](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)));
```
Κοινά blobs που περιέχονται είναι ο Κατάλογος Κωδικών, οι Απαιτήσεις και τα Δικαιώματα και μια Κρυπτογραφική Σύνθεση Μηνυμάτων (CMS).\
Τα κοινά blobs που περιέχονται είναι Code Directory, Requirements and Entitlements και ένα Cryptographic Message Syntax (CMS).\
Επιπλέον, σημειώστε πώς τα δεδομένα που κωδικοποιούνται στα blobs είναι κωδικοποιημένα σε **Big Endian.**
Επιπλέον, οι υπογραφές μπορούν να αποσπαστούν από τα δυαδικά αρχεία και να αποθηκευτούν στο `/var/db/DetachedSignatures` (χρησιμοποιείται από το iOS).
Επιπλέον, οι υπογραφές μπορούν να αποσπαστούν από τα binaries και να αποθηκευτούν στο `/var/db/DetachedSignatures` (χρησιμοποιείται από iOS).
## Blob Καταλόγου Κωδικών
## Code Directory Blob
Είναι δυνατόν να βρείτε τη δήλωση του [Blob Καταλόγου Κωδικών στον κώδικα](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L104):
Είναι δυνατό να βρείτε τη δήλωση του [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)));
```
Σημειώστε ότι υπάρχουν διαφορετικές εκδόσεις αυτής της δομής όπου οι παλιές μπορεί να περιέχουν λιγότερες πληροφορίες.
Σημειώστε ότι υπάρχουν διαφορετικές εκδόσεις αυτού του struct όπου οι παλαιότερες μπορεί να περιέχουν λιγότερες πληροφορίες.
## Σελίδες Υπογραφής Κώδικα
## Υπογραφή Σελίδων Κώδικα
Η κατακερματισμένη πλήρης δυαδική μορφή θα ήταν αναποτελεσματική και ακόμη και άχρηστη αν φορτωθεί μόνο μερικώς στη μνήμη. Επομένως, η υπογραφή κώδικα είναι στην πραγματικότητα ένας κατακερματισμός κατακερματισμών όπου κάθε δυαδική σελίδα κατακερματίζεται ατομικά.\
Στην πραγματικότητα, στον προηγούμενο κώδικα **Καταλόγου Κώδικα** μπορείτε να δείτε ότι το **μέγεθος της σελίδας καθορίζεται** σε ένα από τα πεδία του. Επιπλέον, αν το μέγεθος της δυαδικής μορφής δεν είναι πολλαπλάσιο του μεγέθους μιας σελίδας, το πεδίο **CodeLimit** καθορίζει πού είναι το τέλος της υπογραφής.
Το hashing ολόκληρου του binary θα ήταν αναποτελεσματικό και ακόμη και άχρηστο εάν αυτό φορτώνεται στη μνήμη μόνο μερικώς. Επομένως, το code signature είναι στην πραγματικότητα ένα hash από hashes όπου κάθε σελίδα του binary γίνεται hash ξεχωριστά.\
Στην πραγματικότητα, στον προηγούμενο κώδικα του **Code Directory** μπορείτε να δείτε ότι το **page size is specified** σε ένα από τα πεδία του. Επιπλέον, αν το μέγεθος του binary δεν είναι πολλαπλάσιο του μεγέθους μιας σελίδας, το πεδίο **CodeLimit** καθορίζει πού βρίσκεται το τέλος της υπογραφής.
```bash
# Get all hashes of /bin/ps
codesign -d -vvvvvv /bin/ps
@ -144,25 +149,25 @@ openssl sha256 /tmp/*.page.*
```
## Entitlements Blob
Σημειώστε ότι οι εφαρμογές μπορεί επίσης να περιέχουν ένα **entitlement blob** όπου ορίζονται όλα τα δικαιώματα. Επιπλέον, ορισμένα iOS binaries μπορεί να έχουν τα δικαιώματά τους συγκεκριμένα στη ειδική θέση -7 (αντί για τη θέση -5 των δικαιωμάτων).
Σημειώστε ότι οι εφαρμογές μπορεί επίσης να περιέχουν ένα **entitlement blob** όπου ορίζονται όλα τα entitlements. Επιπλέον, μερικά iOS binaries μπορεί να έχουν τα entitlements τους συγκεκριμένα στην ειδική θέση -7 (αντί της ειδικής θέσης -5 για entitlements).
## Special Slots
Οι εφαρμογές MacOS δεν έχουν όλα όσα χρειάζονται για να εκτελούνται μέσα στο binary, αλλά χρησιμοποιούν επίσης **εξωτερικούς πόρους** (συνήθως μέσα στο **bundle** των εφαρμογών). Επομένως, υπάρχουν ορισμένες θέσεις μέσα στο binary που θα περιέχουν τα hashes ορισμένων ενδιαφέροντων εξωτερικών πόρων για να ελέγξουν ότι δεν έχουν τροποποιηθεί.
Οι εφαρμογές MacOS δεν έχουν όλα όσα χρειάζονται για να εκτελεστούν μέσα στο binary, αλλά χρησιμοποιούν επίσης **external resources** (συνήθως μέσα στο applications **bundle**). Επομένως, υπάρχουν κάποια slots μέσα στο binary που θα περιέχουν τα hashes ορισμένων ενδιαφερόντων external resources για να ελεγχθεί ότι δεν τροποποιήθηκαν.
Στην πραγματικότητα, είναι δυνατόν να δούμε στις δομές του Code Directory μια παράμετρο που ονομάζεται **`nSpecialSlots`** που υποδεικνύει τον αριθμό των ειδικών θέσεων. Δεν υπάρχει ειδική θέση 0 και οι πιο κοινές (από -1 έως -6) είναι:
Στην πραγματικότητα, είναι δυνατό να δει κανείς στα Code Directory structs μια παράμετρο που ονομάζεται **`nSpecialSlots`** η οποία υποδεικνύει τον αριθμό των special slots. Δεν υπάρχει special slot 0 και τα πιο κοινά (από -1 έως -6) είναι:
- Hash του `info.plist` (ή του μέσα στο `__TEXT.__info__plist`).
- Hash των Απαιτήσεων
- Hash του Resource Directory (hash του αρχείου `_CodeSignature/CodeResources` μέσα στο bundle).
- Ειδικό για την εφαρμογή (μη χρησιμοποιούμενο)
- Hash των δικαιωμάτων
- Μόνο υπογραφές κώδικα DMG
- Hash of `info.plist` (or the one inside `__TEXT.__info__plist`).
- Hash of the Requirements
- Hash of the Resource Directory (hash of `_CodeSignature/CodeResources` file inside the bundle).
- Application specific (unused)
- Hash of the entitlements
- DMG code signatures only
- DER Entitlements
## Code Signing Flags
Κάθε διαδικασία έχει σχετιζόμενο ένα bitmask γνωστό ως `status` που ξεκινά από τον πυρήνα και ορισμένα από αυτά μπορούν να παρακαμφθούν από την **υπογραφή κώδικα**. Αυτές οι σημαίες που μπορούν να περιληφθούν στην υπογραφή κώδικα είναι [ορισμένες στον κώδικα](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L36):
Every process has related a bitmask known as the `status` which is started by the kernel and some of them can be overridden by the **code signature**. These flags that can be included in the code signing are [defined in the code](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L36):
```c
/* code signing attributes of a process */
#define CS_VALID 0x00000001 /* dynamically valid */
@ -207,15 +212,15 @@ CS_RESTRICT | CS_ENFORCEMENT | CS_REQUIRE_LV | CS_RUNTIME | CS_LINKER_SIGNED)
#define CS_ENTITLEMENT_FLAGS (CS_GET_TASK_ALLOW | CS_INSTALLER | CS_DATAVAULT_CONTROLLER | CS_NVRAM_UNRESTRICTED)
```
Σημειώστε ότι η λειτουργία [**exec_mach_imgact**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_exec.c#L1420) μπορεί επίσης να προσθέσει τις σημαίες `CS_EXEC_*` δυναμικά κατά την εκκίνηση της εκτέλεσης.
Note that the function [**exec_mach_imgact**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_exec.c#L1420) can also add the `CS_EXEC_*` flags dynamically when starting the execution.
## Απαιτήσεις Υπογραφής Κώδικα
## Απαιτήσεις υπογραφής κώδικα
Κάθε εφαρμογή αποθηκεύει κάποιες **απαιτήσεις** που πρέπει να **ικανοποιούνται** προκειμένου να μπορεί να εκτελείται. Εάν οι **απαιτήσεις της εφαρμογής δεν ικανοποιούνται από την εφαρμογή**, δεν θα εκτελείται (καθώς πιθανώς έχει τροποποιηθεί).
Κάθε εφαρμογή αποθηκεύει κάποιες **απαιτήσεις** που πρέπει να **ικανοποιηθούν** ώστε να μπορεί να εκτελεστεί. Αν οι **απαιτήσεις που περιέχει η εφαρμογή δεν ικανοποιούνται**, δεν θα εκτελεστεί (καθώς πιθανότατα έχει τροποποιηθεί).
Οι απαιτήσεις ενός δυαδικού αρχείου χρησιμοποιούν μια **ειδική γραμματική** που είναι μια ροή **εκφράσεων** και κωδικοποιούνται ως blobs χρησιμοποιώντας το `0xfade0c00` ως το μαγικό, του οποίου το **hash αποθηκεύεται σε μια ειδική θέση κώδικα**.
Οι απαιτήσεις ενός binary χρησιμοποιούν μια **ειδική γραμματική** η οποία είναι μια ροή **expressions** και κωδικοποιούνται ως blobs χρησιμοποιώντας `0xfade0c00` ως magic, του οποίου το **hash αποθηκεύεται σε μια ειδική code slot**.
Οι απαιτήσεις ενός δυαδικού αρχείου μπορούν να δουν εκτελώντας:
Οι απαιτήσεις ενός binary μπορούν να εμφανιστούν τρέχοντας:
```bash
codesign -d -r- /bin/ls
Executable=/bin/ls
@ -225,10 +230,10 @@ codesign -d -r- /Applications/Signal.app/
Executable=/Applications/Signal.app/Contents/MacOS/Signal
designated => identifier "org.whispersystems.signal-desktop" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = U68MSDN6DR
```
> [!NOTE]
> Σημειώστε πώς αυτές οι υπογραφές μπορούν να ελέγξουν πράγματα όπως πληροφορίες πιστοποίησης, TeamID, IDs, δικαιώματα και πολλά άλλα δεδομένα.
> [!TIP]
> Παρατηρήστε πώς αυτές οι υπογραφές μπορούν να ελέγξουν στοιχεία όπως πληροφορίες πιστοποιητικών, TeamID, IDs, entitlements και πολλά άλλα δεδομένα.
Επιπλέον, είναι δυνατόν να δημιουργηθούν κάποιες συμπιεσμένες απαιτήσεις χρησιμοποιώντας το εργαλείο `csreq`:
Επιπλέον, είναι δυνατό να δημιουργήσετε μερικές μεταγλωττισμένες προϋποθέσεις χρησιμοποιώντας το εργαλείο `csreq`:
```bash
# Generate compiled requirements
csreq -b /tmp/output.csreq -r='identifier "org.whispersystems.signal-desktop" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = U68MSDN6DR'
@ -240,57 +245,57 @@ od -A x -t x1 /tmp/output.csreq
0000020 00 00 00 21 6f 72 67 2e 77 68 69 73 70 65 72 73
[...]
```
Είναι δυνατόν να αποκτήσετε πρόσβαση σε αυτές τις πληροφορίες και να δημιουργήσετε ή να τροποποιήσετε απαιτήσεις με ορισμένα APIs από το `Security.framework` όπως:
It's possible to access this information and create or modify requirements with some APIs from the `Security.framework` like:
#### **Έλεγχος Εγκυρότητας**
#### **Checking Validity**
- **`Sec[Static]CodeCheckValidity`**: Ελέγχει την εγκυρότητα του SecCodeRef ανά απαιτήση.
- **`SecRequirementEvaluate`**: Επικυρώνει την απαίτηση στο πλαίσιο του πιστοποιητικού.
- **`SecTaskValidateForRequirement`**: Επικυρώνει μια εκτελούμενη SecTask έναντι της απαίτησης `CFString`.
- **`Sec[Static]CodeCheckValidity`**: Ελέγχει την εγκυρότητα του SecCodeRef ανά Requirement.
- **`SecRequirementEvaluate`**: Επικυρώνει την απαίτηση στο πλαίσιο πιστοποιητικού.
- **`SecTaskValidateForRequirement`**: Επικυρώνει ένα εκτελούμενο SecTask σε σχέση με απαίτηση τύπου `CFString`.
#### **Δημιουργία και Διαχείριση Απαιτήσεων Κώδικα**
#### **Creating and Managing Code Requirements**
- **`SecRequirementCreateWithData`:** Δημιουργεί ένα `SecRequirementRef` από δυαδικά δεδομένα που αντιπροσωπεύουν την απαίτηση.
- **`SecRequirementCreateWithString`:** Δημιουργεί ένα `SecRequirementRef` από μια συμβολοσειρά έκφρασης της απαίτησης.
- **`SecRequirementCopy[Data/String]`**: Ανακτά την δυαδική αναπαράσταση δεδομένων ενός `SecRequirementRef`.
- **`SecRequirementCreateGroup`**: Δημιουργεί μια απαίτηση για την ιδιότητα μέλους ομάδας εφαρμογών.
- **`SecRequirementCreateWithString`:** Δημιουργεί ένα `SecRequirementRef` από μια συμβολοσειρά που εκφράζει την απαίτηση.
- **`SecRequirementCopy[Data/String]`**: Ανακτά τη δυαδική αναπαράσταση δεδομένων ενός `SecRequirementRef`.
- **`SecRequirementCreateGroup`**: Δημιουργεί μια απαίτηση για συμμετοχή σε app-group.
#### **Πρόσβαση σε Πληροφορίες Υπογραφής Κώδικα**
#### **Accessing Code Signing Information**
- **`SecStaticCodeCreateWithPath`**: Αρχικοποιεί ένα αντικείμενο `SecStaticCodeRef` από μια διαδρομή συστήματος αρχείων για την επιθεώρηση υπογραφών κώδικα.
- **`SecCodeCopySigningInformation`**: Αποκτά πληροφορίες υπογραφής από ένα `SecCodeRef` ή `SecStaticCodeRef`.
- **`SecStaticCodeCreateWithPath`**: Αρχικοποιεί ένα αντικείμενο `SecStaticCodeRef` από μονοπάτι του συστήματος αρχείων για την επιθεώρηση υπογραφών κώδικα.
- **`SecCodeCopySigningInformation`**: Λαμβάνει πληροφορίες υπογραφής από `SecCodeRef` ή `SecStaticCodeRef`.
#### **Τροποποίηση Απαιτήσεων Κώδικα**
#### **Modifying Code Requirements**
- **`SecCodeSignerCreate`**: Δημιουργεί ένα αντικείμενο `SecCodeSignerRef` για την εκτέλεση λειτουργιών υπογραφής κώδικα.
- **`SecCodeSignerSetRequirement`**: Ορίζει μια νέα απαίτηση για τον υπογράφοντα κώδικα να εφαρμόσει κατά την υπογραφή.
- **`SecCodeSignerAddSignature`**: Προσθέτει μια υπογραφή στον κώδικα που υπογράφεται με τον καθορισμένο υπογράφοντα.
- **`SecCodeSignerCreate`**: Δημιουργεί ένα `SecCodeSignerRef` για την εκτέλεση λειτουργιών υπογραφής κώδικα.
- **`SecCodeSignerSetRequirement`**: Ορίζει μια νέα απαίτηση που ο signer θα εφαρμόσει κατά την υπογραφή.
- **`SecCodeSignerAddSignature`**: Προσθέτει μια υπογραφή στον κώδικα που υπογράφεται με τον συγκεκριμένο signer.
#### **Επικύρωση Κώδικα με Απαιτήσεις**
#### **Validating Code with Requirements**
- **`SecStaticCodeCheckValidity`**: Επικυρώνει ένα στατικό αντικείμενο κώδικα έναντι καθορισμένων απαιτήσεων.
#### **Επιπλέον Χρήσιμα APIs**
#### **Additional Useful APIs**
- **`SecCodeCopy[Internal/Designated]Requirement`: Λάβετε SecRequirementRef από SecCodeRef**
- **`SecCodeCopyGuestWithAttributes`**: Δημιουργεί ένα `SecCodeRef` που αντιπροσωπεύει ένα αντικείμενο κώδικα με βάση συγκεκριμένα χαρακτηριστικά, χρήσιμο για sandboxing.
- **`SecCodeCopyPath`**: Ανακτά τη διαδρομή συστήματος αρχείων που σχετίζεται με ένα `SecCodeRef`.
- **`SecCodeCopySigningIdentifier`**: Αποκτά τον αναγνωριστικό υπογραφής (π.χ. Team ID) από ένα `SecCodeRef`.
- **`SecCodeGetTypeID`**: Επιστρέφει τον τύπο αναγνωριστικού για αντικείμενα `SecCodeRef`.
- **`SecRequirementGetTypeID`**: Λαμβάνει ένα CFTypeID ενός `SecRequirementRef`.
- **`SecCodeCopy[Internal/Designated]Requirement`: Get SecRequirementRef from SecCodeRef** — Αποκτά SecRequirementRef από SecCodeRef.
- **`SecCodeCopyGuestWithAttributes`**: Δημιουργεί ένα `SecCodeRef` που αντιπροσωπεύει ένα αντικείμενο κώδικα βασισμένο σε συγκεκριμένα attributes, χρήσιμο για sandboxing.
- **`SecCodeCopyPath`**: Ανακτά το μονοπάτι του συστήματος αρχείων που σχετίζεται με ένα `SecCodeRef`.
- **`SecCodeCopySigningIdentifier`**: Αποκτά το signing identifier (π.χ. Team ID) από ένα `SecCodeRef`.
- **`SecCodeGetTypeID`**: Επιστρέφει το type identifier για αντικείμενα `SecCodeRef`.
- **`SecRequirementGetTypeID`**: Επιστρέφει το CFTypeID ενός `SecRequirementRef`.
#### **Σημαίες και Σταθερές Υπογραφής Κώδικα**
#### **Code Signing Flags and Constants**
- **`kSecCSDefaultFlags`**: Προεπιλεγμένες σημαίες που χρησιμοποιούνται σε πολλές λειτουργίες του Security.framework για λειτουργίες υπογραφής κώδικα.
- **`kSecCSSigningInformation`**: Σημαία που χρησιμοποιείται για να δηλώσει ότι οι πληροφορίες υπογραφής πρέπει να ανακτηθούν.
- **`kSecCSDefaultFlags`**: Προεπιλεγμένες σημαίες που χρησιμοποιούνται σε πολλές συναρτήσεις του Security.framework για λειτουργίες υπογραφής κώδικα.
- **`kSecCSSigningInformation`**: Σημαία που χρησιμοποιείται για να δηλώσει ότι πρέπει να ανακτηθούν πληροφορίες υπογραφής.
## Επιβολή Υπογραφής Κώδικα
## Code Signature Enforcement
Ο **kernel** είναι αυτός που **ελέγχει την υπογραφή κώδικα** πριν επιτρέψει την εκτέλεση του κώδικα της εφαρμογής. Επιπλέον, ένας τρόπος για να μπορείτε να γράφετε και να εκτελείτε νέο κώδικα στη μνήμη είναι η κατάχρηση του JIT εάν η `mprotect` καλείται με τη σημαία `MAP_JIT`. Σημειώστε ότι η εφαρμογή χρειάζεται μια ειδική εξουσιοδότηση για να μπορεί να το κάνει αυτό.
The **kernel** is the one that **checks the code signature** before allowing the code of the app to execute. Moreover, one way to be able to write and execute in memory new code is abusing JIT if `mprotect` is called with `MAP_JIT` flag. Note that the application needs a special entitlement to be able to do this.
## `cs_blobs` & `cs_blob`
[**cs_blob**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/ubc_internal.h#L106) δομή περιέχει τις πληροφορίες σχετικά με την εξουσιοδότηση της εκτελούμενης διαδικασίας πάνω σε αυτήν. Το `csb_platform_binary` ενημερώνει επίσης αν η εφαρμογή είναι μια πλατφόρμα δυαδικού (η οποία ελέγχεται σε διάφορες στιγμές από το OS για την εφαρμογή μηχανισμών ασφαλείας όπως η προστασία των δικαιωμάτων SEND στους θύρες εργασίας αυτών των διαδικασιών).
[**cs_blob**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/ubc_internal.h#L106) struct περιέχει πληροφορίες σχετικά με το entitlement της τρέχουσας διεργασίας πάνω σε αυτήν. `csb_platform_binary` επίσης δείχνει εάν η εφαρμογή είναι platform binary (το οποίο ελέγχεται σε διάφορες στιγμές από το OS για να εφαρμόσει μηχανισμούς ασφάλειας, όπως η προστασία των SEND rights στα task ports αυτών των διεργασιών).
```c
struct cs_blob {
struct cs_blob *csb_next;