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
44bddfc1c9
commit
1cf7bb3f50
@ -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,8 +1,8 @@
|
||||
# Specyficzne sztuczki dla oprogramowania i typów plików
|
||||
# Triki dla konkretnych programów i typów plików
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Poniżej znajdziesz interesujące sztuczki dotyczące konkretnych typów plików i/lub oprogramowania:
|
||||
Tutaj znajdziesz interesujące triki dla konkretnych typów plików i/lub oprogramowania:
|
||||
|
||||
|
||||
{{#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}}
|
||||
|
@ -0,0 +1,213 @@
|
||||
# Wydobywanie entitlements Mach-O i indeksowanie IPSW
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Przegląd
|
||||
|
||||
Ta strona opisuje, jak programowo wyodrębnić entitlements z binariów Mach-O, przechodząc po LC_CODE_SIGNATURE i parsując code signing SuperBlob, oraz jak skalować to na firmware Apple IPSW przez montowanie i indeksowanie ich zawartości do celów przeszukiwania/porównywania kryminalistycznego.
|
||||
|
||||
Jeśli potrzebujesz przypomnienia dotyczącego formatu Mach-O i code signing, zobacz także: macOS code signing and SuperBlob internals.
|
||||
- Sprawdź 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)
|
||||
- Sprawdź 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: gdzie się znajdują
|
||||
|
||||
Entitlements są przechowywane wewnątrz danych podpisu kodu, na które wskazuje polecenie ładowania LC_CODE_SIGNATURE i które umieszczone są w segmencie __LINKEDIT. Podpis to CS_SuperBlob zawierający wiele blobów (Code Directory, requirements, entitlements, CMS itd.). Blok entitlements to CS_GenericBlob, którego dane są Apple Binary Property List (bplist00) mapującą klucze entitlements na wartości.
|
||||
|
||||
Kluczowe struktury (z 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;
|
||||
```
|
||||
Ważne stałe:
|
||||
- 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
|
||||
|
||||
Uwaga: Multi-arch (fat) binaries contain multiple Mach-O slices. Musisz wybrać slice dla architektury, którą chcesz zbadać, a następnie przejść przez jej load commands.
|
||||
|
||||
|
||||
## Extraction steps (generic, lossless-enough)
|
||||
|
||||
1) Parsuj nagłówek Mach-O; iteruj ncmds rekordów load_command.
|
||||
2) Zlokalizuj LC_CODE_SIGNATURE; odczytaj linkedit_data_command.dataoff/datasize, aby zmapować Code Signing SuperBlob umieszczony w __LINKEDIT.
|
||||
3) Zwaliduj CS_SuperBlob.magic == 0xfade0cc0; iteruj count wpisów CS_BlobIndex.
|
||||
4) Zlokalizuj index.type == 0xfade7171 (embedded entitlements). Odczytaj wskazywany CS_GenericBlob i sparsuj jego dane jako Apple binary plist (bplist00) na pary klucz/wartość entitlements.
|
||||
|
||||
Implementation notes:
|
||||
- Struktury Code Signature używają pól big-endian; zamień kolejność bajtów przy parsowaniu na little-endian hostach.
|
||||
- Dane entitlements GenericBlob same w sobie są binary plist (obsługiwane przez standardowe biblioteki plist).
|
||||
- Niektóre iOS binaries mogą mieć DER entitlements; też niektóre stores/slots różnią się między platformami/wersjami. Sprawdź zarówno standardowe, jak i DER entitlements w razie potrzeby.
|
||||
- Dla fat binaries użyj fat headers (FAT_MAGIC/FAT_MAGIC_64), aby zlokalizować właściwy slice i offset przed przejściem przez Mach-O load commands.
|
||||
|
||||
|
||||
## Minimal parsing outline (Python)
|
||||
|
||||
Poniżej znajduje się zwarty zarys pokazujący przepływ sterowania do znalezienia i dekodowania entitlements. Celowo pomija solidne sprawdzanie granic i pełne wsparcie dla fat binaries ze względów zwięzłości.
|
||||
```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:
|
||||
- Aby obsłużyć fat binaries, najpierw przeczytaj struct fat_header/fat_arch, wybierz żądany architecture slice, a następnie przekaż podzakres do parse_entitlements.
|
||||
- On macOS you can validate results with: codesign -d --entitlements :- /path/to/binary
|
||||
|
||||
|
||||
## Example findings
|
||||
|
||||
Privileged platform binaries często żądają wrażliwych entitlements, takich jak:
|
||||
- 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"]
|
||||
|
||||
Wyszukiwanie ich na dużą skalę w obrazach firmware jest niezwykle cenne do attack surface mapping oraz diffing między releases/devices.
|
||||
|
||||
|
||||
## Scaling across IPSWs (mounting and indexing)
|
||||
|
||||
Aby enumerate executables i extract entitlements na dużą skalę bez przechowywania pełnych obrazów:
|
||||
|
||||
- Use the ipsw tool by @blacktop to download and mount firmware filesystems. Montowanie wykorzystuje apfs-fuse, więc możesz przeglądać wolumeny APFS bez pełnej ekstrakcji.
|
||||
```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>
|
||||
```
|
||||
- Przeglądaj zamontowane wolumeny, aby odnaleźć pliki Mach-O (sprawdź magic i/lub użyj file/otool), a następnie sparsuj entitlements i zaimportowane frameworks.
|
||||
- Utrwal znormalizowany widok w relacyjnej bazie danych, aby uniknąć liniowego wzrostu przy tysiącach IPSWs:
|
||||
- executables, operating_system_versions, entitlements, frameworks
|
||||
- many-to-many: executable↔OS version, executable↔entitlement, executable↔framework
|
||||
|
||||
Przykładowe zapytanie do wylistowania wszystkich wersji OS zawierających daną nazwę executable:
|
||||
```sql
|
||||
SELECT osv.version AS "Versions"
|
||||
FROM device d
|
||||
LEFT JOIN operating_system_version osv ON osv.device_id = d.id
|
||||
LEFT JOIN executable_operating_system_version eosv ON eosv.operating_system_version_id = osv.id
|
||||
LEFT JOIN executable e ON e.id = eosv.executable_id
|
||||
WHERE e.name = "launchd";
|
||||
```
|
||||
Uwagi dotyczące przenośności bazy danych (jeśli implementujesz własny indeksator):
|
||||
- Użyj ORM/abstrakcji (np. SeaORM), aby kod był niezależny od bazy danych (SQLite/PostgreSQL).
|
||||
- SQLite wymaga AUTOINCREMENT tylko dla INTEGER PRIMARY KEY; jeśli chcesz i64 PKs w Rust, generuj encje jako i32 i konwertuj typy — SQLite wewnętrznie przechowuje INTEGER jako 8-bajtową liczbę ze znakiem.
|
||||
|
||||
|
||||
## Open-source tooling i odniesienia dla entitlement hunting
|
||||
|
||||
- Firmware mount/download: https://github.com/blacktop/ipsw
|
||||
- Entitlement databases and references:
|
||||
- Entitlement DB Jonathana Levina: https://newosxbook.com/ent.php
|
||||
- entdb: https://github.com/ChiChou/entdb
|
||||
- Indeksator na dużą skalę (Rust, self-hosted Web UI + OpenAPI): https://github.com/synacktiv/appledb_rs
|
||||
- Apple headers for structures and constants:
|
||||
- loader.h (Mach-O headers, load commands)
|
||||
- cs_blobs.h (SuperBlob, GenericBlob, CodeDirectory)
|
||||
|
||||
For more on code signing internals (Code Directory, special slots, DER entitlements), see: [macOS Code Signing](../../../macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md)
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- [appledb_rs: a research support tool for Apple platforms](https://www.synacktiv.com/publications/appledbrs-un-outil-daide-a-la-recherche-sur-plateformes-apple.html)
|
||||
- [synacktiv/appledb_rs](https://github.com/synacktiv/appledb_rs)
|
||||
- [blacktop/ipsw](https://github.com/blacktop/ipsw)
|
||||
- [Jonathan Levin’s entitlement DB](https://newosxbook.com/ent.php)
|
||||
- [ChiChou/entdb](https://github.com/ChiChou/entdb)
|
||||
- [XNU cs_blobs.h](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/kern/cs_blobs.h)
|
||||
- [XNU mach-o/loader.h](https://github.com/apple-oss-distributions/xnu/blob/main/EXTERNAL_HEADERS/mach-o/loader.h)
|
||||
- [SQLite Datatypes](https://sqlite.org/datatype3.html)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
@ -1,48 +1,48 @@
|
||||
# macOS Universal binaries & Mach-O Format
|
||||
# macOS Uniwersalne binaria i format Mach-O
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Podstawowe informacje
|
||||
|
||||
Binaries Mac OS są zazwyczaj kompilowane jako **universal binaries**. **Universal binary** może **obsługiwać wiele architektur w tym samym pliku**.
|
||||
Binarne pliki macOS są zwykle kompilowane jako **uniwersalne binaria**. **Uniwersalne binarium** może **obsługiwać wiele architektur w tym samym pliku**.
|
||||
|
||||
Te binaries mają **strukturę Mach-O**, która składa się zasadniczo z:
|
||||
Te binaria mają strukturę **Mach-O**, która zasadniczo składa się z:
|
||||
|
||||
- Nagłówka
|
||||
- Komend ładowania
|
||||
- Danych
|
||||
- Nagłówek
|
||||
- Load Commands
|
||||
- Dane
|
||||
|
||||
.png>)
|
||||
|
||||
## Fat Header
|
||||
|
||||
Szukaj pliku za pomocą: `mdfind fat.h | grep -i mach-o | grep -E "fat.h$"`
|
||||
Wyszukaj plik za pomocą: `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 lub FAT_MAGIC_64 */
|
||||
</strong><strong> uint32_t nfat_arch; /* liczba struktur, które następują */
|
||||
<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; /* specyfikator CPU (int) */
|
||||
cpu_subtype_t cpusubtype; /* specyfikator maszyny (int) */
|
||||
uint32_t offset; /* przesunięcie pliku do tego pliku obiektowego */
|
||||
uint32_t size; /* rozmiar tego pliku obiektowego */
|
||||
uint32_t align; /* wyrównanie jako potęga 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>
|
||||
|
||||
Nagłówek zawiera **magiczne** bajty, a następnie **liczbę** **architektur**, które plik **zawiera** (`nfat_arch`), a każda architektura będzie miała strukturę `fat_arch`.
|
||||
Nagłówek zawiera bajty **magic**, a następnie **liczbę** **architektur** zawartych w pliku (`nfat_arch`), a każda architektura ma strukturę `fat_arch`.
|
||||
|
||||
Sprawdź to za pomocą:
|
||||
|
||||
<pre class="language-shell-session"><code class="lang-shell-session">% file /bin/ls
|
||||
/bin/ls: Mach-O universal binary z 2 architekturami: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
|
||||
/bin/ls (dla architektury x86_64): Mach-O 64-bit executable x86_64
|
||||
/bin/ls (dla architektury arm64e): Mach-O 64-bit executable arm64e
|
||||
/bin/ls: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
|
||||
/bin/ls (for architecture x86_64): Mach-O 64-bit executable x86_64
|
||||
/bin/ls (for architecture arm64e): Mach-O 64-bit executable arm64e
|
||||
|
||||
% otool -f -v /bin/ls
|
||||
Fat headers
|
||||
@ -64,15 +64,15 @@ capabilities PTR_AUTH_VERSION USERSPACE 0
|
||||
</strong> align 2^14 (16384)
|
||||
</code></pre>
|
||||
|
||||
lub używając narzędzia [Mach-O View](https://sourceforge.net/projects/machoview/):
|
||||
or using the [Mach-O View](https://sourceforge.net/projects/machoview/) tool:
|
||||
|
||||
<figure><img src="../../../images/image (1094).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jak możesz myśleć, zazwyczaj **universal binary** skompilowane dla 2 architektur **podwaja rozmiar** jednego skompilowanego tylko dla 1 architektury.
|
||||
Jak można się spodziewać, uniwersalne binarium skompilowane dla 2 architektur **zwykle podwaja rozmiar** w porównaniu z binarium skompilowanym tylko dla 1 architektury.
|
||||
|
||||
## **Nagłówek Mach-O**
|
||||
|
||||
Nagłówek zawiera podstawowe informacje o pliku, takie jak magiczne bajty identyfikujące go jako plik Mach-O oraz informacje o docelowej architekturze. Możesz go znaleźć w: `mdfind loader.h | grep -i mach-o | grep -E "loader.h$"`
|
||||
Nagłówek zawiera podstawowe informacje o pliku, takie jak magic bytes służące do identyfikacji pliku Mach-O oraz informacje o docelowej architekturze. Można go znaleźć w: `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,17 +101,17 @@ uint32_t reserved; /* reserved */
|
||||
```
|
||||
### Typy plików Mach-O
|
||||
|
||||
Istnieją różne typy plików, które można znaleźć zdefiniowane w [**kodzie źródłowym, na przykład tutaj**](https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h). Najważniejsze z nich to:
|
||||
Istnieją różne typy plików — można je znaleźć zdefiniowane w [**source code for example here**](https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h). Najważniejsze z nich to:
|
||||
|
||||
- `MH_OBJECT`: Plik obiektowy do relokacji (produkty pośrednie kompilacji, jeszcze nie wykonywalne).
|
||||
- `MH_EXECUTE`: Pliki wykonywalne.
|
||||
- `MH_FVMLIB`: Plik biblioteki VM o stałej wielkości.
|
||||
- `MH_CORE`: Zrzuty kodu
|
||||
- `MH_PRELOAD`: Wstępnie załadowany plik wykonywalny (już nieobsługiwany w XNU)
|
||||
- `MH_DYLIB`: Biblioteki dynamiczne
|
||||
- `MH_DYLINKER`: Ładowarka dynamiczna
|
||||
- `MH_BUNDLE`: "Pliki wtyczek". Generowane za pomocą -bundle w gcc i ładowane explicite przez `NSBundle` lub `dlopen`.
|
||||
- `MH_DYSM`: Towarzyszący plik `.dSym` (plik z symbolami do debugowania).
|
||||
- `MH_FVMLIB`: Plik biblioteki Fixed VM.
|
||||
- `MH_CORE`: Zrzuty pamięci.
|
||||
- `MH_PRELOAD`: Wstępnie załadowany plik wykonywalny (już nieobsługiwany w XNU).
|
||||
- `MH_DYLIB`: Biblioteki dynamiczne.
|
||||
- `MH_DYLINKER`: Dynamiczny linker.
|
||||
- `MH_BUNDLE`: Pliki wtyczek. Generowane przy użyciu -bundle w gcc i jawnie ładowane przez `NSBundle` lub `dlopen`.
|
||||
- `MH_DYSM`: Plik towarzyszący `.dSym` (plik z symbolami do debugowania).
|
||||
- `MH_KEXT_BUNDLE`: Rozszerzenia jądra.
|
||||
```bash
|
||||
# Checking the mac header of a binary
|
||||
@ -120,67 +120,67 @@ Mach header
|
||||
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
|
||||
MH_MAGIC_64 ARM64 E USR00 EXECUTE 19 1728 NOUNDEFS DYLDLINK TWOLEVEL PIE
|
||||
```
|
||||
Lub używając [Mach-O View](https://sourceforge.net/projects/machoview/):
|
||||
Or using [Mach-O View](https://sourceforge.net/projects/machoview/):
|
||||
|
||||
<figure><img src="../../../images/image (1133).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## **Flagi Mach-O**
|
||||
|
||||
Kod źródłowy definiuje również kilka flag przydatnych do ładowania bibliotek:
|
||||
Kode źródłowy definiuje również kilka flag przydatnych przy ładowaniu bibliotek:
|
||||
|
||||
- `MH_NOUNDEFS`: Brak niezdefiniowanych odniesień (w pełni powiązane)
|
||||
- `MH_DYLDLINK`: Łączenie Dyld
|
||||
- `MH_PREBOUND`: Dynamiczne odniesienia wstępnie powiązane.
|
||||
- `MH_SPLIT_SEGS`: Plik dzieli segmenty r/o i r/w.
|
||||
- `MH_WEAK_DEFINES`: Plik binarny ma słabo zdefiniowane symbole
|
||||
- `MH_BINDS_TO_WEAK`: Plik binarny używa słabych symboli
|
||||
- `MH_ALLOW_STACK_EXECUTION`: Umożliwia wykonanie na stosie
|
||||
- `MH_NO_REEXPORTED_DYLIBS`: Biblioteka nie ma poleceń LC_REEXPORT
|
||||
- `MH_PIE`: Wykonywalny niezależny od pozycji
|
||||
- `MH_HAS_TLV_DESCRIPTORS`: Istnieje sekcja z lokalnymi zmiennymi wątku
|
||||
- `MH_NO_HEAP_EXECUTION`: Brak wykonania dla stron heap/data
|
||||
- `MH_HAS_OBJC`: Plik binarny ma sekcje oBject-C
|
||||
- `MH_NOUNDEFS`: Brak niezdefiniowanych referencji (w pełni połączony)
|
||||
- `MH_DYLDLINK`: Linkowanie przez dyld
|
||||
- `MH_PREBOUND`: Dynamiczne referencje wstępnie powiązane
|
||||
- `MH_SPLIT_SEGS`: Plik rozdziela segmenty tylko do odczytu (r/o) i do zapisu (r/w)
|
||||
- `MH_WEAK_DEFINES`: Binar posiada słabo zdefiniowane symbole (weak)
|
||||
- `MH_BINDS_TO_WEAK`: Binar używa słabych (weak) symboli
|
||||
- `MH_ALLOW_STACK_EXECUTION`: Pozwala na wykonywanie na stosie
|
||||
- `MH_NO_REEXPORTED_DYLIBS`: Biblioteka nie zawiera poleceń LC_REEXPORT
|
||||
- `MH_PIE`: Wykonywalny niezależny od położenia (PIE)
|
||||
- `MH_HAS_TLV_DESCRIPTORS`: Zawiera sekcję ze zmiennymi lokalnymi w wątku
|
||||
- `MH_NO_HEAP_EXECUTION`: Brak wykonywania na stronach sterty/danych
|
||||
- `MH_HAS_OBJC`: Binar zawiera sekcje Objective-C
|
||||
- `MH_SIM_SUPPORT`: Wsparcie dla symulatora
|
||||
- `MH_DYLIB_IN_CACHE`: Używane w dylibach/frameworkach w pamięci podręcznej biblioteki współdzielonej.
|
||||
- `MH_DYLIB_IN_CACHE`: Używane dla dylibów/frameworków w udostępnionej pamięci podręcznej bibliotek
|
||||
|
||||
## **Polecenia ładowania Mach-O**
|
||||
|
||||
**Układ pliku w pamięci** jest określony tutaj, szczegółowo opisując **lokalizację tabeli symboli**, kontekst głównego wątku na początku wykonania oraz wymagane **biblioteki współdzielone**. Instrukcje są przekazywane do dynamicznego loadera **(dyld)** dotyczące procesu ładowania pliku binarnego do pamięci.
|
||||
Układ pliku w pamięci jest tu określony, wraz ze szczegółami dotyczącymi położenia tablicy symboli, kontekstu głównego wątku na początku wykonania oraz wymaganych bibliotek współdzielonych. Dostarczane są instrukcje dla dynamicznego loadera (dyld) dotyczące procesu ładowania binarki do pamięci.
|
||||
|
||||
Używa struktury **load_command**, zdefiniowanej w wspomnianym **`loader.h`**:
|
||||
Używa struktury load_command, zdefiniowanej w wymienionym `loader.h`:
|
||||
```objectivec
|
||||
struct load_command {
|
||||
uint32_t cmd; /* type of load command */
|
||||
uint32_t cmdsize; /* total size of command in bytes */
|
||||
};
|
||||
```
|
||||
Są około **50 różnych typów poleceń ładujących**, które system obsługuje w różny sposób. Najczęstsze z nich to: `LC_SEGMENT_64`, `LC_LOAD_DYLINKER`, `LC_MAIN`, `LC_LOAD_DYLIB` i `LC_CODE_SIGNATURE`.
|
||||
Istnieje około **50 różnych typów poleceń ładowania**, które system obsługuje w odmienny sposób. Do najczęstszych należą: `LC_SEGMENT_64`, `LC_LOAD_DYLINKER`, `LC_MAIN`, `LC_LOAD_DYLIB` i `LC_CODE_SIGNATURE`.
|
||||
|
||||
### **LC_SEGMENT/LC_SEGMENT_64**
|
||||
|
||||
> [!TIP]
|
||||
> Zasadniczo ten typ polecenia ładującego definiuje **jak załadować \_\_TEXT** (kod wykonywalny) **i \_\_DATA** (dane dla procesu) **segmenty** zgodnie z **offsetami wskazanymi w sekcji danych** podczas wykonywania binarnego.
|
||||
> W praktyce ten typ Load Command określa, **jak załadować \_\_TEXT** (kod wykonywalny) **i \_\_DATA** (dane procesu) **segmenty** zgodnie z **offsetami wskazanymi w sekcji Data** podczas wykonywania binarki.
|
||||
|
||||
Te polecenia **definiują segmenty**, które są **mapowane** do **przestrzeni pamięci wirtualnej** procesu, gdy jest on wykonywany.
|
||||
Te polecenia definiują segmenty, które są mapowane do wirtualnej przestrzeni pamięci procesu podczas jego wykonywania.
|
||||
|
||||
Istnieją **różne typy** segmentów, takie jak segment **\_\_TEXT**, który zawiera kod wykonywalny programu, oraz segment **\_\_DATA**, który zawiera dane używane przez proces. Te **segmenty znajdują się w sekcji danych** pliku Mach-O.
|
||||
Istnieją różne typy segmentów, takie jak \_\_TEXT, który zawiera kod wykonywalny programu, oraz \_\_DATA, który zawiera dane używane przez proces. Segmenty te znajdują się w sekcji danych pliku Mach-O.
|
||||
|
||||
**Każdy segment** może być dalej **podzielony** na wiele **sekcji**. Struktura **polecenia ładującego** zawiera **informacje** o **tych sekcjach** w odpowiednim segmencie.
|
||||
Każdy segment może być dalej podzielony na wiele sekcji. Struktura load command zawiera informacje o tych sekcjach w ramach odpowiedniego segmentu.
|
||||
|
||||
W nagłówku najpierw znajdziesz **nagłówek segmentu**:
|
||||
W nagłówku najpierw znajduje się nagłówek segmentu:
|
||||
|
||||
<pre class="language-c"><code class="lang-c">struct segment_command_64 { /* dla architektur 64-bitowych */
|
||||
<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; /* obejmuje sizeof section_64 structs */
|
||||
char segname[16]; /* nazwa segmentu */
|
||||
uint64_t vmaddr; /* adres pamięci tego segmentu */
|
||||
uint64_t vmsize; /* rozmiar pamięci tego segmentu */
|
||||
uint64_t fileoff; /* offset pliku tego segmentu */
|
||||
uint64_t filesize; /* ilość do zmapowania z pliku */
|
||||
int32_t maxprot; /* maksymalna ochrona VM */
|
||||
int32_t initprot; /* początkowa ochrona VM */
|
||||
<strong> uint32_t nsects; /* liczba sekcji w segmencie */
|
||||
</strong> uint32_t flags; /* flagi */
|
||||
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>
|
||||
|
||||
@ -188,7 +188,7 @@ Przykład nagłówka segmentu:
|
||||
|
||||
<figure><img src="../../../images/image (1126).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Ten nagłówek definiuje **liczbę sekcji, których nagłówki pojawiają się po** nim:
|
||||
Ten nagłówek określa liczbę sekcji, których nagłówki pojawiają się po nim:
|
||||
```c
|
||||
struct section_64 { /* for 64-bit architectures */
|
||||
char sectname[16]; /* name of this section */
|
||||
@ -209,58 +209,58 @@ Przykład **nagłówka sekcji**:
|
||||
|
||||
<figure><img src="../../../images/image (1108).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Jeśli **dodasz** **przesunięcie sekcji** (0x37DC) + **przesunięcie**, w którym **arch zaczyna się**, w tym przypadku `0x18000` --> `0x37DC + 0x18000 = 0x1B7DC`
|
||||
Jeśli **dodasz** **offset sekcji** (0x37DC) + **offset**, gdzie **arch** się zaczyna, w tym przypadku `0x18000` --> `0x37DC + 0x18000 = 0x1B7DC`
|
||||
|
||||
<figure><img src="../../../images/image (701).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Możliwe jest również uzyskanie **informacji o nagłówkach** z **linii poleceń** za pomocą:
|
||||
Można też uzyskać **informacje o nagłówkach** z **wiersza poleceń** przy użyciu:
|
||||
```bash
|
||||
otool -lv /bin/ls
|
||||
```
|
||||
Common segments loaded by this cmd:
|
||||
|
||||
- **`__PAGEZERO`:** Instrukcja dla jądra, aby **mapować** **adres zero**, aby **nie można go było odczytać, zapisać ani wykonać**. Zmienne maxprot i minprot w strukturze są ustawione na zero, aby wskazać, że **nie ma praw do odczytu-zapisu-wykonania na tej stronie**.
|
||||
- Ta alokacja jest ważna, aby **złagodzić podatności na dereferencję wskaźnika NULL**. Dzieje się tak, ponieważ XNU egzekwuje twardą stronę zero, która zapewnia, że pierwsza strona (tylko pierwsza) pamięci jest niedostępna (z wyjątkiem i386). Plik binarny może spełniać te wymagania, tworząc mały \_\_PAGEZERO (używając `-pagezero_size`), aby pokryć pierwsze 4k i mając resztę pamięci 32-bitowej dostępną zarówno w trybie użytkownika, jak i jądra.
|
||||
- **`__TEXT`**: Zawiera **wykonywalny** **kod** z **uprawnieniami do odczytu** i **wykonywania** (brak zapisu)**.** Typowe sekcje tego segmentu:
|
||||
- `__text`: Skonstruowany kod binarny
|
||||
- **`__PAGEZERO`:** Wskazuje jądru, aby **zmapowało** **adres zero**, tak żeby **nie można było z niego czytać, zapisywać ani wykonywać**. Zmienne maxprot i minprot w strukturze są ustawione na zero, aby wskazać, że **na tej stronie nie ma praw do odczytu-zapisu-wykonania**.
|
||||
- Ta alokacja jest ważna, aby **łagodzić luki wynikające z dereferencji NULL pointera**. XNU wymusza twardą stronę zero, która zapewnia, że pierwsza strona (tylko pierwsza) pamięci jest niedostępna (oprócz i386). Binarna może spełnić te wymagania przez stworzenie małego __PAGEZERO (używając `-pagezero_size`) aby pokryć pierwsze 4k i udostępnienie reszty pamięci 32-bitowej zarówno w trybie użytkownika, jak i jądra.
|
||||
- **`__TEXT`**: Zawiera **kod wykonywalny** z prawami **odczytu** i **wykonania** (bez zapisu)**.** Typowe sekcje tego segmentu:
|
||||
- `__text`: Skompilowany kod binarny
|
||||
- `__const`: Dane stałe (tylko do odczytu)
|
||||
- `__[c/u/os_log]string`: Stałe ciągi C, Unicode lub os logów
|
||||
- `__stubs` i `__stubs_helper`: Uczestniczą w procesie ładowania dynamicznej biblioteki
|
||||
- `__unwind_info`: Dane o rozwijaniu stosu.
|
||||
- Zauważ, że cała ta zawartość jest podpisana, ale również oznaczona jako wykonywalna (tworząc więcej opcji do wykorzystania sekcji, które niekoniecznie potrzebują tego przywileju, jak sekcje dedykowane ciągom).
|
||||
- **`__DATA`**: Zawiera dane, które są **czytelne** i **zapisywalne** (brak wykonywalnych)**.**
|
||||
- `__got:` Globalna tabela przesunięć
|
||||
- `__nl_symbol_ptr`: Wskaźnik symbolu non lazy (wiąże przy ładowaniu)
|
||||
- `__la_symbol_ptr`: Wskaźnik symbolu lazy (wiąże przy użyciu)
|
||||
- `__const`: Powinny być danymi tylko do odczytu (nie do końca)
|
||||
- `__cfstring`: Ciągi CoreFoundation
|
||||
- `__data`: Zmienne globalne (które zostały zainicjowane)
|
||||
- `__bss`: Zmienne statyczne (które nie zostały zainicjowane)
|
||||
- `__objc_*` (\_\_objc_classlist, \_\_objc_protolist, itd): Informacje używane przez środowisko uruchomieniowe Objective-C
|
||||
- **`__DATA_CONST`**: \_\_DATA.\_\_const nie jest gwarantowane jako stałe (uprawnienia do zapisu), ani inne wskaźniki i GOT. Ta sekcja sprawia, że `__const`, niektóre inicjalizatory i tabela GOT (po rozwiązaniu) są **tylko do odczytu** przy użyciu `mprotect`.
|
||||
- **`__LINKEDIT`**: Zawiera informacje dla linkera (dyld), takie jak symbole, ciągi i wpisy tabeli relokacji. Jest to ogólny kontener dla treści, które nie znajdują się w `__TEXT` ani `__DATA`, a jego zawartość jest opisana w innych poleceniach ładowania.
|
||||
- Informacje dyld: Rebase, opcodes wiązania non-lazy/lazy/weak i informacje o eksporcie
|
||||
- Funkcje startowe: Tabela adresów startowych funkcji
|
||||
- Dane w kodzie: Wyspy danych w \_\_text
|
||||
- Tabela symboli: Symbole w binarnym
|
||||
- Tabela symboli pośrednich: Wskaźniki/stuby symboli
|
||||
- Tabela ciągów
|
||||
- Podpis kodu
|
||||
- **`__OBJC`**: Zawiera informacje używane przez środowisko uruchomieniowe Objective-C. Chociaż te informacje mogą być również znalezione w segmencie \_\_DATA, w różnych sekcjach \_\_objc\_\*.
|
||||
- **`__RESTRICT`**: Segment bez zawartości z jedną sekcją o nazwie **`__restrict`** (również pusta), która zapewnia, że podczas uruchamiania binarnego zignoruje zmienne środowiskowe DYLD.
|
||||
- `__[c/u/os_log]string`: Stałe łańcuchy znaków C, Unicode lub logów os
|
||||
- `__stubs` i `__stubs_helper`: Używane podczas procesu ładowania bibliotek dynamicznych
|
||||
- `__unwind_info`: Dane do rozwijania stosu
|
||||
- Należy zauważyć, że cała ta zawartość jest podpisana, ale także oznaczona jako wykonywalna (co stwarza więcej możliwości wykorzystania sekcji, które niekoniecznie potrzebują tego przywileju, jak sekcje przeznaczone dla łańcuchów znaków).
|
||||
- **`__DATA`**: Zawiera dane, które są **do odczytu** i **zapisu** (bez możliwości wykonania)**.**
|
||||
- `__got:` Global Offset Table
|
||||
- `__nl_symbol_ptr`: Wskaźnik symbolu niedługiego (bind at load)
|
||||
- `__la_symbol_ptr`: Wskaźnik symbolu leniwego (bind on use)
|
||||
- `__const`: Powinny to być dane tylko do odczytu (w praktyce nie zawsze)
|
||||
- `__cfstring`: Stringi CoreFoundation
|
||||
- `__data`: Zmienne globalne (zainicjalizowane)
|
||||
- `__bss`: Zmienne statyczne (niezainicjalizowane)
|
||||
- `__objc_*` (__objc_classlist, __objc_protolist, itd): Informacje używane przez runtime Objective-C
|
||||
- **`__DATA_CONST`**: __DATA.__const nie jest gwarantowane jako stałe (ma prawa zapisu), podobnie inne wskaźniki i GOT. Ta sekcja ustawia `__const`, niektóre inicjalizatory i tabelę GOT (po rozwiązaniu) jako tylko do odczytu przy użyciu `mprotect`.
|
||||
- **`__LINKEDIT`**: Zawiera informacje dla linkera (dyld), takie jak wpisy tablic symboli, łańcuchów i relokacji. To ogólny kontener dla treści, które nie znajdują się w `__TEXT` ani `__DATA`, a jego zawartość jest opisana w innych poleceniach ładowania.
|
||||
- informacje dyld: Rebase, Non-lazy/lazy/weak binding opcodes oraz informacje o eksporcie
|
||||
- Początki funkcji: Tabela adresów początkowych funkcji
|
||||
- Data In Code: Wyspy danych w __text
|
||||
- Tabela symboli: Symbole w binarce
|
||||
- Indirect Symbol Table: Symbole wskaźników/stubów
|
||||
- String Table
|
||||
- Code Signature
|
||||
- **`__OBJC`**: Zawiera informacje używane przez runtime Objective-C. Chociaż te informacje mogą też występować w segmencie __DATA, w różnych sekcjach __objc_*.
|
||||
- **`__RESTRICT`**: Segment bez zawartości z pojedynczą sekcją o nazwie **`__restrict`** (również pustą), który zapewnia, że podczas uruchamiania binarki będą ignorowane zmienne środowiskowe DYLD.
|
||||
|
||||
Jak można było zobaczyć w kodzie, **segmenty również wspierają flagi** (chociaż nie są zbyt często używane):
|
||||
Jak można było zobaczyć w kodzie, **segmenty również obsługują flagi** (chociaż nie są one zbyt często używane):
|
||||
|
||||
- `SG_HIGHVM`: Tylko rdzeń (nieużywane)
|
||||
- `SG_HIGHVM`: Tylko Core (nieużywane)
|
||||
- `SG_FVMLIB`: Nieużywane
|
||||
- `SG_NORELOC`: Segment nie ma relokacji
|
||||
- `SG_PROTECTED_VERSION_1`: Szyfrowanie. Używane na przykład przez Findera do szyfrowania tekstu w segmencie `__TEXT`.
|
||||
- `SG_PROTECTED_VERSION_1`: Szyfrowanie. Używane na przykład przez Finder do zaszyfrowania segmentu tekstowego `__TEXT`.
|
||||
|
||||
### **`LC_UNIXTHREAD/LC_MAIN`**
|
||||
|
||||
**`LC_MAIN`** zawiera punkt wejścia w atrybucie **entryoff.** W czasie ładowania, **dyld** po prostu **dodaje** tę wartość do (w pamięci) **bazy binarnej**, a następnie **skacze** do tej instrukcji, aby rozpocząć wykonanie kodu binarnego.
|
||||
**`LC_MAIN`** zawiera punkt wejścia w atrybucie **entryoff.** Podczas ładowania **dyld** po prostu **dodaje** tę wartość do (w pamięci) **bazy binarki**, a następnie **skacze** do tej instrukcji, aby rozpocząć wykonywanie kodu binarki.
|
||||
|
||||
**`LC_UNIXTHREAD`** zawiera wartości, jakie rejestry muszą mieć przy uruchamianiu głównego wątku. To już zostało wycofane, ale **`dyld`** nadal to wykorzystuje. Można zobaczyć wartości rejestrów ustawione przez to za pomocą:
|
||||
**`LC_UNIXTHREAD`** zawiera wartości, jakie rejestry muszą mieć przy uruchamianiu głównego wątku. To zostało już zdeprecjonowane, ale **`dyld`** nadal z tego korzysta. Można zobaczyć ustawione wartości rejestrów za pomocą:
|
||||
```bash
|
||||
otool -l /usr/lib/dyld
|
||||
[...]
|
||||
@ -286,34 +286,39 @@ cpsr 0x00000000
|
||||
```
|
||||
### **`LC_CODE_SIGNATURE`**
|
||||
|
||||
Zawiera informacje o **podpisie kodu pliku Macho-O**. Zawiera tylko **offset**, który **wskazuje** na **blob podpisu**. Zazwyczaj znajduje się on na samym końcu pliku.\
|
||||
Jednak można znaleźć pewne informacje na temat tej sekcji w [**tym wpisie na blogu**](https://davedelong.com/blog/2018/01/10/reading-your-own-entitlements/) oraz w tym [**gists**](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}}
|
||||
|
||||
|
||||
Zawiera informacje o **podpisie kodu pliku Macho-O**. Zawiera jedynie **offset**, który **wskazuje** na **signature blob**. Zazwyczaj znajduje się to na samym końcu pliku.\
|
||||
However, you can find some information about this section in [**this blog post**](https://davedelong.com/blog/2018/01/10/reading-your-own-entitlements/) and this [**gists**](https://gist.github.com/carlospolop/ef26f8eb9fafd4bc22e69e1a32b81da4).
|
||||
|
||||
### **`LC_ENCRYPTION_INFO[_64]`**
|
||||
|
||||
Wsparcie dla szyfrowania binarnego. Jednak, oczywiście, jeśli atakujący zdoła skompromitować proces, będzie mógł zrzucić pamięć w postaci nieszyfrowanej.
|
||||
Obsługa szyfrowania binarnego. Oczywiście, jeśli atakującemu uda się przejąć proces, będzie mógł zrzucić pamięć w formie nieszyfrowanej.
|
||||
|
||||
### **`LC_LOAD_DYLINKER`**
|
||||
|
||||
Zawiera **ścieżkę do wykonywalnego pliku dynamicznego linkera**, który mapuje biblioteki współdzielone w przestrzeni adresowej procesu. **Wartość jest zawsze ustawiona na `/usr/lib/dyld`**. Ważne jest, aby zauważyć, że w macOS, mapowanie dylib odbywa się w **trybie użytkownika**, a nie w trybie jądra.
|
||||
Zawiera **ścieżkę do wykonywalnego dynamic linker-a**, który mapuje shared libraries do przestrzeni adresowej procesu. **Wartość jest zawsze ustawiona na `/usr/lib/dyld`**. Ważne jest, że w macOS mapowanie dylib odbywa się w **trybie użytkownika**, a nie w **trybie jądra**.
|
||||
|
||||
### **`LC_IDENT`**
|
||||
|
||||
Nieaktualne, ale gdy jest skonfigurowane do generowania zrzutów w przypadku paniki, tworzony jest zrzut rdzenia Mach-O, a wersja jądra jest ustawiana w poleceniu `LC_IDENT`.
|
||||
Przestarzały, lecz jeśli skonfigurowano generowanie zrzutów przy panic, tworzony jest core dump Mach-O, a wersja kernela jest zapisywana w poleceniu `LC_IDENT`.
|
||||
|
||||
### **`LC_UUID`**
|
||||
|
||||
Losowy UUID. Jest przydatny do czegokolwiek bezpośrednio, ale XNU buforuje go z resztą informacji o procesie. Może być używany w raportach o awariach.
|
||||
Losowy UUID. Sam w sobie nie jest bezpośrednio bardzo użyteczny, ale XNU buforuje go wraz z resztą informacji o procesie. Może być używany w raportach awarii.
|
||||
|
||||
### **`LC_DYLD_ENVIRONMENT`**
|
||||
|
||||
Pozwala wskazać zmienne środowiskowe dla dyld przed wykonaniem procesu. Może to być bardzo niebezpieczne, ponieważ może pozwolić na wykonanie dowolnego kodu wewnątrz procesu, więc to polecenie ładowania jest używane tylko w dyld zbudowanym z `#define SUPPORT_LC_DYLD_ENVIRONMENT` i dodatkowo ogranicza przetwarzanie tylko do zmiennych w formie `DYLD_..._PATH` określających ścieżki ładowania.
|
||||
Pozwala wskazać zmienne środowiskowe dla dyld przed uruchomieniem procesu. Może to być bardzo niebezpieczne, ponieważ może umożliwić wykonanie dowolnego kodu wewnątrz procesu, dlatego to polecenie ładowania jest używane tylko w buildzie dyld z `#define SUPPORT_LC_DYLD_ENVIRONMENT` i dodatkowo ogranicza przetwarzanie tylko do zmiennych w formie `DYLD_..._PATH` określających ścieżki ładowania.
|
||||
|
||||
### **`LC_LOAD_DYLIB`**
|
||||
|
||||
To polecenie ładowania opisuje zależność od **dynamicznej** **biblioteki**, która **instrukuje** **ładowarkę** (dyld) do **załadowania i powiązania wspomnianej biblioteki**. Istnieje polecenie ładowania `LC_LOAD_DYLIB` **dla każdej biblioteki**, której wymaga binarny plik Mach-O.
|
||||
To polecenie ładowania opisuje zależność od **dynamic library**, które **nakazuje** loader-owi (dyld) **załadować i zlinkować tę bibliotekę**. Istnieje polecenie `LC_LOAD_DYLIB` **dla każdej biblioteki**, której wymaga binarka Mach-O.
|
||||
|
||||
- To polecenie ładowania jest strukturą typu **`dylib_command`** (która zawiera strukturę dylib, opisującą rzeczywistą zależną dynamiczną bibliotekę):
|
||||
- This load command is a structure of type **`dylib_command`** (which contains a struct dylib, describing the actual dependent dynamic library):
|
||||
```objectivec
|
||||
struct dylib_command {
|
||||
uint32_t cmd; /* LC_LOAD_{,WEAK_}DYLIB */
|
||||
@ -330,7 +335,7 @@ uint32_t compatibility_version; /* library's compatibility vers number*/
|
||||
```
|
||||
.png>)
|
||||
|
||||
Możesz również uzyskać te informacje z cli za pomocą:
|
||||
Możesz też uzyskać te informacje z cli za pomocą:
|
||||
```bash
|
||||
otool -L /bin/ls
|
||||
/bin/ls:
|
||||
@ -338,36 +343,36 @@ 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)
|
||||
```
|
||||
Niektóre potencjalne biblioteki związane z złośliwym oprogramowaniem to:
|
||||
Niektóre potencjalne biblioteki związane z malware to:
|
||||
|
||||
- **DiskArbitration**: Monitorowanie dysków USB
|
||||
- **AVFoundation:** Rejestracja audio i wideo
|
||||
- **CoreWLAN**: Skanowanie Wifi.
|
||||
- **DiskArbitration**: monitorowanie dysków USB
|
||||
- **AVFoundation:** przechwytywanie audio i wideo
|
||||
- **CoreWLAN**: skanowanie Wifi.
|
||||
|
||||
> [!NOTE]
|
||||
> Plik binarny Mach-O może zawierać jednego lub **więcej** **konstruktorów**, które będą **wykonywane** **przed** adresem określonym w **LC_MAIN**.\
|
||||
> Offsety wszelkich konstruktorów są przechowywane w sekcji **\_\_mod_init_func** segmentu **\_\_DATA_CONST**.
|
||||
> [!TIP]
|
||||
> Plik **Mach-O** może zawierać jednego lub **więcej** **konstruktorów**, które zostaną **wykonane** **przed** adresem określonym w **LC_MAIN**.\
|
||||
> Offsety wszystkich konstruktorów znajdują się w sekcji **\_\_mod_init_func** segmentu **\_\_DATA_CONST**.
|
||||
|
||||
## **Dane Mach-O**
|
||||
|
||||
W rdzeniu pliku znajduje się obszar danych, który składa się z kilku segmentów zdefiniowanych w obszarze poleceń ładujących. **W każdym segmencie może być przechowywanych wiele sekcji danych**, z których każda **zawiera kod lub dane** specyficzne dla danego typu.
|
||||
W rdzeniu pliku znajduje się obszar danych, który składa się z kilku segmentów zdefiniowanych w obszarze load-commands. **W każdym segmencie może być umieszczona różnorodność sekcji danych**, z każdą sekcją **zawierającą kod lub dane** specyficzne dla typu.
|
||||
|
||||
> [!TIP]
|
||||
> Dane to zasadniczo część zawierająca wszystkie **informacje**, które są ładowane przez polecenia ładujące **LC_SEGMENTS_64**
|
||||
> Dane to zasadniczo część zawierająca wszystkie **informacje**, które są ładowane przez load commands **LC_SEGMENTS_64**
|
||||
|
||||
 (3).png>)
|
||||
|
||||
To obejmuje:
|
||||
|
||||
- **Tabela funkcji:** Która zawiera informacje o funkcjach programu.
|
||||
- **Tabela symboli**: Która zawiera informacje o zewnętrznych funkcjach używanych przez plik binarny
|
||||
- Może również zawierać wewnętrzne funkcje, nazwy zmiennych oraz inne.
|
||||
- **Tabela funkcji:** która zawiera informacje o funkcjach programu.
|
||||
- **Tablica symboli**: która zawiera informacje o funkcjach zewnętrznych używanych przez plik binarny
|
||||
- Może też zawierać nazwy funkcji wewnętrznych, nazw zmiennych oraz inne informacje.
|
||||
|
||||
Aby to sprawdzić, możesz użyć narzędzia [**Mach-O View**](https://sourceforge.net/projects/machoview/):
|
||||
|
||||
<figure><img src="../../../images/image (1120).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Lub z poziomu cli:
|
||||
Albo z poziomu CLI:
|
||||
```bash
|
||||
size -m /bin/ls
|
||||
```
|
||||
@ -375,16 +380,16 @@ size -m /bin/ls
|
||||
|
||||
W segmencie `__TEXT` (r-x):
|
||||
|
||||
- `__objc_classname`: Nazwy klas (ciągi)
|
||||
- `__objc_methname`: Nazwy metod (ciągi)
|
||||
- `__objc_methtype`: Typy metod (ciągi)
|
||||
- `__objc_classname`: Nazwy klas (łańcuchy znaków)
|
||||
- `__objc_methname`: Nazwy metod (łańcuchy znaków)
|
||||
- `__objc_methtype`: Typy metod (łańcuchy znaków)
|
||||
|
||||
W segmencie `__DATA` (rw-):
|
||||
|
||||
- `__objc_classlist`: Wskaźniki do wszystkich klas Objective-C
|
||||
- `__objc_nlclslist`: Wskaźniki do klas Objective-C bez leniwego ładowania
|
||||
- `__objc_catlist`: Wskaźnik do Kategorii
|
||||
- `__objc_nlcatlist`: Wskaźnik do Kategorii bez leniwego ładowania
|
||||
- `__objc_nlclslist`: Wskaźniki do Non-Lazy klas Objective-C
|
||||
- `__objc_catlist`: Wskaźnik do kategorii
|
||||
- `__objc_nlcatlist`: Wskaźnik do Non-Lazy kategorii
|
||||
- `__objc_protolist`: Lista protokołów
|
||||
- `__objc_const`: Dane stałe
|
||||
- `__objc_imageinfo`, `__objc_selrefs`, `objc__protorefs`...
|
||||
|
@ -1,14 +1,19 @@
|
||||
# macOS Code Signing
|
||||
# Podpisywanie kodu w macOS
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Podstawowe informacje
|
||||
|
||||
Binarne pliki Mach-o zawierają polecenie ładujące zwane **`LC_CODE_SIGNATURE`**, które wskazuje **offset** i **rozmiar** podpisów wewnątrz binarnego pliku. W rzeczywistości, używając narzędzia GUI MachOView, można znaleźć na końcu binarnego pliku sekcję o nazwie **Code Signature** z tymi informacjami:
|
||||
{{#ref}}
|
||||
../../../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/mach-o-entitlements-and-ipsw-indexing.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
Pliki binarne Mach-o zawierają polecenie ładowania o nazwie **`LC_CODE_SIGNATURE`**, które wskazuje **offset** i **size** podpisów wewnątrz binarki. Za pomocą narzędzia GUI MachOView można znaleźć na końcu binarki sekcję nazwaną **Code Signature** z tymi informacjami:
|
||||
|
||||
<figure><img src="../../../images/image (1) (1) (1) (1).png" alt="" width="431"><figcaption></figcaption></figure>
|
||||
|
||||
Magiczny nagłówek podpisu kodu to **`0xFADE0CC0`**. Następnie znajdują się informacje takie jak długość i liczba blobów superBlob, które je zawierają.\
|
||||
Magiczny nagłówek Code Signature to **`0xFADE0CC0`**. Następnie znajdują się informacje takie jak długość oraz liczba blobów superBlob, który je zawiera.
|
||||
Można znaleźć te informacje w [kodzie źródłowym tutaj](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L276):
|
||||
```c
|
||||
/*
|
||||
@ -38,14 +43,14 @@ char data[];
|
||||
} CS_GenericBlob
|
||||
__attribute__ ((aligned(1)));
|
||||
```
|
||||
Zwykłe bloby zawierają Code Directory, Requirements i Entitlements oraz Cryptographic Message Syntax (CMS).\
|
||||
Ponadto, zauważ, że dane zakodowane w blobach są zakodowane w **Big Endian.**
|
||||
Typowe bloby zawierają Code Directory, Requirements i Entitlements oraz Cryptographic Message Syntax (CMS).\
|
||||
Zwróć również uwagę, że dane zakodowane w blobach są zapisane w **Big Endian.**
|
||||
|
||||
Ponadto, podpisy mogą być odłączane od binariów i przechowywane w `/var/db/DetachedSignatures` (używane przez iOS).
|
||||
Ponadto podpisy mogą być odłączone od binarek i przechowywane w `/var/db/DetachedSignatures` (używane w iOS).
|
||||
|
||||
## Code Directory Blob
|
||||
|
||||
Możliwe jest znalezienie deklaracji [Code Directory Blob w kodzie](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L104):
|
||||
Można znaleźć deklarację [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)));
|
||||
```
|
||||
Zauważ, że istnieją różne wersje tej struktury, w których starsze mogą zawierać mniej informacji.
|
||||
Note that there are different versions of this struct where old ones might contain less information.
|
||||
|
||||
## Strony podpisu kodu
|
||||
## Podpisywanie stron kodu
|
||||
|
||||
Haszowanie pełnego binarnego pliku byłoby nieefektywne, a nawet bezużyteczne, jeśli jest on ładowany w pamięci tylko częściowo. Dlatego podpis kodu jest w rzeczywistości haszem haszy, gdzie każda strona binarna jest haszowana indywidualnie.\
|
||||
W rzeczywistości, w poprzednim kodzie **Code Directory** możesz zobaczyć, że **rozmiar strony jest określony** w jednym z jego pól. Co więcej, jeśli rozmiar binarnego pliku nie jest wielokrotnością rozmiaru strony, pole **CodeLimit** określa, gdzie kończy się podpis.
|
||||
Haszowanie całego pliku binarnego byłoby nieefektywne, a nawet bezużyteczne, jeśli jest on ładowany do pamięci tylko częściowo. Dlatego code signature jest w rzeczywistości haszem hashów, gdzie każda strona binarna jest haszowana indywidualnie.\
|
||||
W rzeczywistości, w poprzednim kodzie **Code Directory** możesz zobaczyć, że **page size is specified** w jednym z jego pól. Co więcej, jeśli rozmiar binarki nie jest wielokrotnością rozmiaru strony, pole **CodeLimit** określa, gdzie kończy się podpis.
|
||||
```bash
|
||||
# Get all hashes of /bin/ps
|
||||
codesign -d -vvvvvv /bin/ps
|
||||
@ -144,25 +149,25 @@ openssl sha256 /tmp/*.page.*
|
||||
```
|
||||
## Entitlements Blob
|
||||
|
||||
Zauważ, że aplikacje mogą również zawierać **blob uprawnień**, w którym zdefiniowane są wszystkie uprawnienia. Co więcej, niektóre binaria iOS mogą mieć swoje uprawnienia specyficzne w specjalnym slocie -7 (zamiast w specjalnym slocie -5 dla uprawnień).
|
||||
Zauważ, że aplikacje mogą także zawierać **entitlement blob**, w którym zdefiniowane są wszystkie entitlements. Dodatkowo niektóre binaria iOS mogą mieć swoje entitlements umieszczone w specjalnym slocie -7 (zamiast w specjalnym slocie entitlements -5).
|
||||
|
||||
## Special Slots
|
||||
|
||||
Aplikacje MacOS nie mają wszystkiego, co potrzebne do wykonania wewnątrz binarnego, ale korzystają również z **zewnętrznych zasobów** (zwykle wewnątrz **bundla** aplikacji). Dlatego w binarnym znajdują się pewne sloty, które będą zawierać hashe niektórych interesujących zewnętrznych zasobów, aby sprawdzić, czy nie zostały zmodyfikowane.
|
||||
Aplikacje MacOS nie mają wszystkiego, co potrzebne do uruchomienia bezpośrednio w binarium — używają też **external resources** (zwykle wewnątrz **bundle** aplikacji). W związku z tym w binarium znajdują się sloty, które zawierają hashe niektórych interesujących external resources, aby sprawdzić, czy nie zostały zmodyfikowane.
|
||||
|
||||
W rzeczywistości można zobaczyć w strukturach Code Directory parametr zwany **`nSpecialSlots`**, który wskazuje liczbę specjalnych slotów. Nie ma slotu specjalnego 0, a najczęstsze z nich (od -1 do -6) to:
|
||||
W praktyce w strukturach Code Directory można zobaczyć parametr **`nSpecialSlots`**, wskazujący liczbę special slots. Nie istnieje specjalny slot 0, a najczęstsze (od -1 do -6) to:
|
||||
|
||||
- Hash `info.plist` (lub ten wewnątrz `__TEXT.__info__plist`).
|
||||
- Hash Wymagań
|
||||
- Hash Katalogu Zasobów (hash pliku `_CodeSignature/CodeResources` wewnątrz bundla).
|
||||
- Specyficzny dla aplikacji (niewykorzystany)
|
||||
- Hash uprawnień
|
||||
- Tylko podpisy kodu DMG
|
||||
- Uprawnienia DER
|
||||
- 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
|
||||
|
||||
Każdy proces ma powiązany bitmaskę znaną jako `status`, która jest inicjowana przez jądro, a niektóre z nich mogą być nadpisane przez **podpis kodu**. Te flagi, które mogą być zawarte w podpisie kodu, są [zdefiniowane w kodzie](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/cs_blobs.h#L36):
|
||||
Każdy proces ma powiązany bitmask znany jako `status`, który jest ustawiany przez kernel, i niektóre jego bity mogą być nadpisane przez **code signature**. Flagi, które mogą być uwzględnione w podpisie kodu, są [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)
|
||||
```
|
||||
Zauważ, że funkcja [**exec_mach_imgact**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_exec.c#L1420) może również dynamicznie dodawać flagi `CS_EXEC_*` podczas uruchamiania.
|
||||
Zwróć uwagę, że funkcja [**exec_mach_imgact**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/kern_exec.c#L1420) może również dynamicznie dodać flagi `CS_EXEC_*` podczas rozpoczynania wykonania.
|
||||
|
||||
## Wymagania dotyczące podpisu kodu
|
||||
## Wymagania podpisu kodu
|
||||
|
||||
Każda aplikacja przechowuje **wymagania**, które musi **spełniać**, aby mogła być uruchomiona. Jeśli **wymagania aplikacji nie są spełnione**, nie zostanie ona uruchomiona (prawdopodobnie została zmieniona).
|
||||
Każda aplikacja przechowuje pewne **wymagania**, które musi **spełnić**, aby mogła zostać uruchomiona. Jeśli **wymagania zawarte w aplikacji nie są spełnione**, aplikacja nie zostanie uruchomiona (prawdopodobnie została zmodyfikowana).
|
||||
|
||||
Wymagania binarne używają **specjalnej gramatyki**, która jest strumieniem **wyrażeń** i są kodowane jako blob za pomocą `0xfade0c00` jako magii, której **hash jest przechowywany w specjalnym slocie kodu**.
|
||||
Wymagania pliku binarnego używają **specjalnej gramatyki**, która jest strumieniem **wyrażeń**, i są kodowane jako bloby używając `0xfade0c00` jako magicznej wartości, której **hash jest przechowywany w specjalnym code slot**.
|
||||
|
||||
Wymagania binarne można zobaczyć, uruchamiając:
|
||||
Wymagania binarnego można zobaczyć uruchamiając:
|
||||
```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]
|
||||
> Zauważ, jak te podpisy mogą sprawdzać takie rzeczy jak informacje o certyfikacie, TeamID, identyfikatory, uprawnienia i wiele innych danych.
|
||||
|
||||
Ponadto możliwe jest generowanie niektórych skompilowanych wymagań za pomocą narzędzia `csreq`:
|
||||
> [!TIP]
|
||||
> Zwróć uwagę, że te podpisy mogą sprawdzać takie rzeczy jak informacje o certyfikacie, TeamID, IDs, entitlements i wiele innych danych.
|
||||
>
|
||||
> Ponadto możliwe jest wygenerowanie skompilowanych wymagań przy użyciu narzędzia `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
|
||||
[...]
|
||||
```
|
||||
Możliwe jest uzyskanie dostępu do tych informacji oraz tworzenie lub modyfikowanie wymagań za pomocą niektórych API z `Security.framework`, takich jak:
|
||||
It's possible to access this information and create or modify requirements with some APIs from the `Security.framework` like:
|
||||
|
||||
#### **Sprawdzanie ważności**
|
||||
#### **Sprawdzanie poprawności**
|
||||
|
||||
- **`Sec[Static]CodeCheckValidity`**: Sprawdza ważność SecCodeRef według wymagań.
|
||||
- **`SecRequirementEvaluate`**: Waliduje wymaganie w kontekście certyfikatu.
|
||||
- **`SecTaskValidateForRequirement`**: Waliduje działający SecTask w odniesieniu do wymagań `CFString`.
|
||||
- **`Sec[Static]CodeCheckValidity`**: Sprawdza ważność `SecCodeRef` względem wymagań.
|
||||
- **`SecRequirementEvaluate`**: Weryfikuje wymaganie w kontekście certyfikatu.
|
||||
- **`SecTaskValidateForRequirement`**: Weryfikuje uruchomiony `SecTask` względem wymagania `CFString`.
|
||||
|
||||
#### **Tworzenie i zarządzanie wymaganiami kodu**
|
||||
|
||||
- **`SecRequirementCreateWithData`:** Tworzy `SecRequirementRef` z danych binarnych reprezentujących wymaganie.
|
||||
- **`SecRequirementCreateWithString`:** Tworzy `SecRequirementRef` z wyrażenia tekstowego wymagania.
|
||||
- **`SecRequirementCopy[Data/String]`**: Pobiera binarną reprezentację danych `SecRequirementRef`.
|
||||
- **`SecRequirementCreateGroup`**: Tworzy wymaganie dla członkostwa w grupie aplikacji.
|
||||
- **`SecRequirementCreateWithData`:** Tworzy `SecRequirementRef` z binarnych danych reprezentujących wymaganie.
|
||||
- **`SecRequirementCreateWithString`:** Tworzy `SecRequirementRef` z tekstowego wyrażenia wymagania.
|
||||
- **`SecRequirementCopy[Data/String]`**: Pobiera binarną reprezentację `SecRequirementRef`.
|
||||
- **`SecRequirementCreateGroup`**: Tworzy wymaganie dotyczące członkostwa w app-group
|
||||
|
||||
#### **Uzyskiwanie informacji o podpisywaniu kodu**
|
||||
#### **Uzyskiwanie informacji o podpisie kodu**
|
||||
|
||||
- **`SecStaticCodeCreateWithPath`**: Inicjalizuje obiekt `SecStaticCodeRef` z ścieżki systemu plików do inspekcji podpisów kodu.
|
||||
- **`SecCodeCopySigningInformation`**: Uzyskuje informacje o podpisie z `SecCodeRef` lub `SecStaticCodeRef`.
|
||||
- **`SecStaticCodeCreateWithPath`**: Inicjalizuje obiekt `SecStaticCodeRef` z ścieżki w systemie plików w celu inspekcji podpisów kodu.
|
||||
- **`SecCodeCopySigningInformation`**: Pobiera informacje o podpisie z `SecCodeRef` lub `SecStaticCodeRef`.
|
||||
|
||||
#### **Modyfikowanie wymagań kodu**
|
||||
|
||||
- **`SecCodeSignerCreate`**: Tworzy obiekt `SecCodeSignerRef` do wykonywania operacji podpisywania kodu.
|
||||
- **`SecCodeSignerSetRequirement`**: Ustala nowe wymaganie dla podpisującego kod, które ma być zastosowane podczas podpisywania.
|
||||
- **`SecCodeSignerAddSignature`**: Dodaje podpis do kodu, który jest podpisywany przez określonego podpisującego.
|
||||
- **`SecCodeSignerSetRequirement`**: Ustawia nowe wymaganie, które zostanie zastosowane przez `SecCodeSignerRef` podczas podpisywania.
|
||||
- **`SecCodeSignerAddSignature`**: Dodaje podpis do kodu podpisywanego przez określony `SecCodeSignerRef`.
|
||||
|
||||
#### **Walidacja kodu z wymaganiami**
|
||||
#### **Weryfikacja kodu za pomocą wymagań**
|
||||
|
||||
- **`SecStaticCodeCheckValidity`**: Waliduje statyczny obiekt kodu w odniesieniu do określonych wymagań.
|
||||
- **`SecStaticCodeCheckValidity`**: Weryfikuje obiekt statycznego kodu względem określonych wymagań.
|
||||
|
||||
#### **Dodatkowe przydatne API**
|
||||
|
||||
- **`SecCodeCopy[Internal/Designated]Requirement`: Uzyskaj SecRequirementRef z SecCodeRef**
|
||||
- **`SecCodeCopy[Internal/Designated]Requirement`: Pobiera `SecRequirementRef` z `SecCodeRef`**
|
||||
- **`SecCodeCopyGuestWithAttributes`**: Tworzy `SecCodeRef` reprezentujący obiekt kodu na podstawie określonych atrybutów, przydatne do sandboxingu.
|
||||
- **`SecCodeCopyPath`**: Pobiera ścieżkę systemu plików powiązaną z `SecCodeRef`.
|
||||
- **`SecCodeCopyPath`**: Pobiera ścieżkę w systemie plików powiązaną z `SecCodeRef`.
|
||||
- **`SecCodeCopySigningIdentifier`**: Uzyskuje identyfikator podpisu (np. Team ID) z `SecCodeRef`.
|
||||
- **`SecCodeGetTypeID`**: Zwraca identyfikator typu dla obiektów `SecCodeRef`.
|
||||
- **`SecRequirementGetTypeID`**: Uzyskuje CFTypeID `SecRequirementRef`.
|
||||
- **`SecRequirementGetTypeID`**: Zwraca CFTypeID dla `SecRequirementRef`
|
||||
|
||||
#### **Flagi i stałe podpisywania kodu**
|
||||
|
||||
- **`kSecCSDefaultFlags`**: Domyślne flagi używane w wielu funkcjach Security.framework do operacji podpisywania kodu.
|
||||
- **`kSecCSSigningInformation`**: Flaga używana do określenia, że informacje o podpisie powinny być pobrane.
|
||||
- **`kSecCSDefaultFlags`**: Domyślne flagi używane w wielu funkcjach `Security.framework` dla operacji podpisywania kodu.
|
||||
- **`kSecCSSigningInformation`**: Flaga używana do wskazania, że należy pobrać informacje o podpisie.
|
||||
|
||||
## Egzekwowanie podpisu kodu
|
||||
|
||||
**Jądro** to ono, które **sprawdza podpis kodu** przed zezwoleniem na wykonanie kodu aplikacji. Ponadto, jednym ze sposobów na możliwość pisania i wykonywania nowego kodu w pamięci jest nadużycie JIT, jeśli `mprotect` jest wywoływane z flagą `MAP_JIT`. Należy zauważyć, że aplikacja potrzebuje specjalnego uprawnienia, aby móc to zrobić.
|
||||
The **kernel** jest tym, który **sprawdza podpis kodu** zanim pozwoli aplikacji wykonać kod. Co więcej, jednym ze sposobów na zapisanie i wykonanie w pamięci nowego kodu jest nadużycie JIT, jeśli `mprotect` zostanie wywołane z flagą `MAP_JIT`. Zwróć uwagę, że aplikacja potrzebuje specjalnego uprawnienia (entitlement), aby móc to zrobić.
|
||||
|
||||
## `cs_blobs` & `cs_blob`
|
||||
|
||||
[**cs_blob**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/ubc_internal.h#L106) struktura zawiera informacje o uprawnieniach działającego procesu. `csb_platform_binary` informuje również, czy aplikacja jest binarną platformą (co jest sprawdzane w różnych momentach przez system operacyjny w celu zastosowania mechanizmów zabezpieczających, takich jak ochrona praw SEND do portów zadań tych procesów).
|
||||
[**cs_blob**](https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/ubc_internal.h#L106) struct zawiera informacje o entitlements uruchomionego procesu. `csb_platform_binary` informuje również, czy aplikacja jest platform binary (co jest sprawdzane w różnych momentach przez OS w celu stosowania mechanizmów bezpieczeństwa, takich jak ochrona praw SEND do portów task tych procesów).
|
||||
```c
|
||||
struct cs_blob {
|
||||
struct cs_blob *csb_next;
|
||||
@ -349,7 +354,7 @@ bool csb_csm_managed;
|
||||
#endif
|
||||
};
|
||||
```
|
||||
## Odniesienia
|
||||
## Źródła
|
||||
|
||||
- [**\*OS Internals Volume III**](https://newosxbook.com/home.html)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user