macOS Launch/Environment Constraints & Trust Cache
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ograniczenia uruchamiania w macOS zostały wprowadzone w celu zwiększenia bezpieczeństwa poprzez regulowanie, jak, kto i skąd proces może być inicjowany. Wprowadzone w macOS Ventura, zapewniają ramy, które klasyfikują każdy systemowy plik binarny w różne kategorie ograniczeń, które są zdefiniowane w pamięci zaufania, liście zawierającej pliki binarne systemu i ich odpowiednie hashe. Ograniczenia te obejmują każdy wykonywalny plik binarny w systemie, co wiąże się z zestawem reguł określających wymagania dotyczące uruchamiania konkretnego pliku binarnego. Reguły obejmują ograniczenia własne, które musi spełnić plik binarny, ograniczenia rodzica, które musi spełnić jego proces nadrzędny, oraz ograniczenia odpowiedzialne, które muszą być przestrzegane przez inne odpowiednie podmioty.
Mechanizm ten rozszerza się na aplikacje firm trzecich poprzez Ograniczenia Środowiskowe, począwszy od macOS Sonoma, umożliwiając programistom ochronę swoich aplikacji poprzez określenie zestawu kluczy i wartości dla ograniczeń środowiskowych.
Definiujesz ograniczenia środowiskowe i biblioteczne w słownikach ograniczeń, które zapisujesz w plikach listy właściwości launchd
, lub w osobnych plikach listy właściwości, które używasz w podpisywaniu kodu.
Istnieją 4 typy ograniczeń:
Ograniczenia własne: Ograniczenia stosowane do uruchamianego pliku binarnego.
Proces nadrzędny: Ograniczenia stosowane do rodzica procesu (na przykład launchd
uruchamiającego usługę XP)
Ograniczenia odpowiedzialne: Ograniczenia stosowane do procesu wywołującego usługę w komunikacji XPC
Ograniczenia ładowania biblioteki: Użyj ograniczeń ładowania biblioteki, aby selektywnie opisać kod, który może być załadowany
Gdy proces próbuje uruchomić inny proces — wywołując execve(_:_:_:)
lub posix_spawn(_:_:_:_:_:_:)
— system operacyjny sprawdza, czy plik wykonywalny spełnia swoje własne ograniczenie własne. Sprawdza również, czy plik wykonywalny procesu nadrzędnego spełnia ograniczenie nadrzędne pliku wykonywalnego oraz czy plik wykonywalny procesu odpowiedzialnego spełnia ograniczenie procesu odpowiedzialnego pliku wykonywalnego. Jeśli którekolwiek z tych ograniczeń uruchamiania nie jest spełnione, system operacyjny nie uruchamia programu.
Jeśli podczas ładowania biblioteki jakakolwiek część ograniczenia biblioteki nie jest prawdziwa, twój proces nie ładuje biblioteki.
LC składa się z faktów i operacji logicznych (i, lub..) łączących fakty.
Fakty, które LC może wykorzystać, są udokumentowane. Na przykład:
is-init-proc: Wartość logiczna, która wskazuje, czy plik wykonywalny musi być procesem inicjalizacji systemu operacyjnego (launchd
).
is-sip-protected: Wartość logiczna, która wskazuje, czy plik wykonywalny musi być plikiem chronionym przez System Integrity Protection (SIP).
on-authorized-authapfs-volume:
Wartość logiczna, która wskazuje, czy system operacyjny załadował plik wykonywalny z autoryzowanego, uwierzytelnionego woluminu APFS.
on-authorized-authapfs-volume
: Wartość logiczna, która wskazuje, czy system operacyjny załadował plik wykonywalny z autoryzowanego, uwierzytelnionego woluminu APFS.
Wolumin Cryptexes
on-system-volume:
Wartość logiczna, która wskazuje, czy system operacyjny załadował plik wykonywalny z aktualnie uruchomionego woluminu systemowego.
Wewnątrz /System...
...
Gdy plik binarny Apple jest podpisany, przypisuje go do kategorii LC w pamięci zaufania.
Kategorie LC iOS 16 zostały odwrócone i udokumentowane tutaj.
Aktualne Kategorie LC (macOS 14 - Somona) zostały odwrócone, a ich opisy można znaleźć tutaj.
Na przykład Kategoria 1 to:
(on-authorized-authapfs-volume || on-system-volume)
: Musi być w woluminie System lub Cryptexes.
launch-type == 1
: Musi być usługą systemową (plist w LaunchDaemons).
validation-category == 1
: Wykonywalny plik systemu operacyjnego.
is-init-proc
: Launchd
Masz więcej informacji na ten temat tutaj, ale zasadniczo są one zdefiniowane w AMFI (AppleMobileFileIntegrity), więc musisz pobrać Zestaw Narzędzi do Rozwoju Jądra, aby uzyskać KEXT. Symbole zaczynające się od kConstraintCategory
są interesujące. Ekstrahując je, otrzymasz strumień zakodowany w DER (ASN.1), który musisz zdekodować za pomocą ASN.1 Decoder lub biblioteki python-asn1 i jej skryptu dump.py
, andrivet/python-asn1, co da ci bardziej zrozumiały ciąg.
To są ograniczenia uruchamiania ustawione w aplikacjach stron trzecich. Programista może wybrać fakty i operatory logiczne do użycia w swojej aplikacji, aby ograniczyć dostęp do niej.
Możliwe jest enumerowanie ograniczeń środowiskowych aplikacji za pomocą:
W macOS istnieje kilka pamięci podręcznych zaufania:
/System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/BaseSystemTrustCache.img4
/System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/StaticTrustCache.img4
/System/Library/Security/OSLaunchPolicyData
A w iOS wygląda to na /usr/standalone/firmware/FUD/StaticTrustCache.img4
.
Na macOS działającym na urządzeniach Apple Silicon, jeśli binarny plik podpisany przez Apple nie znajduje się w pamięci podręcznej zaufania, AMFI odmówi jego załadowania.
Poprzednie pliki pamięci podręcznej zaufania są w formacie IMG4 i IM4P, przy czym IM4P to sekcja ładunku formatu IMG4.
Możesz użyć pyimg4, aby wyodrębnić ładunek baz danych:
(Inna opcja to użycie narzędzia img4tool, które będzie działać nawet na M1, mimo że wydanie jest stare, oraz na x86_64, jeśli zainstalujesz je w odpowiednich lokalizacjach).
Teraz możesz użyć narzędzia trustcache, aby uzyskać informacje w czytelnym formacie:
Cache zaufania ma następującą strukturę, więc kategoria LC to 4. kolumna
Then, you could use a script such as this one to extract data.
From that data you can check the Apps with a launch constraints value of 0
, which are the ones that aren't constrained (check here for what each value is).
Launch Constrains mogłyby złagodzić kilka starych ataków poprzez zapewnienie, że proces nie będzie wykonywany w nieoczekiwanych warunkach: Na przykład z nieoczekiwanych lokalizacji lub wywoływany przez nieoczekiwany proces nadrzędny (jeśli tylko launchd powinien go uruchamiać).
Ponadto, Launch Constraints również łagodzi ataki downgrade.
Jednakże, nie łagodzą one powszechnych nadużyć XPC, wstrzyknięć kodu Electron ani wstrzyknięć dylib bez walidacji biblioteki (chyba że znane są identyfikatory zespołów, które mogą ładować biblioteki).
W wydaniu Sonoma, istotnym punktem jest konfiguracja odpowiedzialności usługi daemon XPC. Usługa XPC odpowiada sama za siebie, w przeciwieństwie do klienta łączącego, który jest odpowiedzialny. Jest to udokumentowane w raporcie zwrotnym FB13206884. Ta konfiguracja może wydawać się wadliwa, ponieważ pozwala na pewne interakcje z usługą XPC:
Uruchamianie usługi XPC: Jeśli uznane za błąd, ta konfiguracja nie pozwala na inicjowanie usługi XPC za pomocą kodu atakującego.
Łączenie z aktywną usługą: Jeśli usługa XPC już działa (prawdopodobnie aktywowana przez swoją oryginalną aplikację), nie ma przeszkód w łączeniu się z nią.
Chociaż wprowadzenie ograniczeń na usłudze XPC może być korzystne poprzez zawężenie okna dla potencjalnych ataków, nie rozwiązuje to podstawowego problemu. Zapewnienie bezpieczeństwa usługi XPC zasadniczo wymaga skutecznej walidacji łączącego klienta. To pozostaje jedyną metodą na wzmocnienie bezpieczeństwa usługi. Warto również zauważyć, że wspomniana konfiguracja odpowiedzialności jest obecnie operacyjna, co może nie być zgodne z zamierzonym projektem.
Nawet jeśli wymagane jest, aby aplikacja była otwierana przez LaunchService (w ograniczeniach rodziców). Można to osiągnąć za pomocą open
(które może ustawiać zmienne środowiskowe) lub korzystając z API Launch Services (gdzie można wskazać zmienne środowiskowe).
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)