macOS XPC
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)
XPC, co oznacza XNU (jądro używane przez macOS) inter-Process Communication, to framework do komunikacji między procesami na macOS i iOS. XPC zapewnia mechanizm do bezpiecznych, asynchronicznych wywołań metod między różnymi procesami w systemie. Jest częścią paradygmatu bezpieczeństwa Apple, umożliwiając tworzenie aplikacji z oddzielonymi uprawnieniami, gdzie każdy komponent działa z tylko tymi uprawnieniami, które są mu potrzebne do wykonania swojej pracy, ograniczając w ten sposób potencjalne szkody wynikające z kompromitacji procesu.
XPC wykorzystuje formę komunikacji międzyprocesowej (IPC), która jest zestawem metod dla różnych programów działających w tym samym systemie do przesyłania danych w obie strony.
Główne korzyści z XPC obejmują:
Bezpieczeństwo: Dzięki oddzieleniu pracy na różne procesy, każdy proces może otrzymać tylko te uprawnienia, które są mu potrzebne. Oznacza to, że nawet jeśli proces zostanie skompromitowany, ma ograniczone możliwości wyrządzenia szkód.
Stabilność: XPC pomaga izolować awarie do komponentu, w którym występują. Jeśli proces ulegnie awarii, można go ponownie uruchomić bez wpływu na resztę systemu.
Wydajność: XPC umożliwia łatwą współbieżność, ponieważ różne zadania mogą być wykonywane jednocześnie w różnych procesach.
Jedynym minusem jest to, że oddzielanie aplikacji na kilka procesów i ich komunikacja za pomocą XPC jest mniej wydajne. Jednak w dzisiejszych systemach nie jest to prawie zauważalne, a korzyści są lepsze.
Komponenty XPC aplikacji znajdują się wewnątrz samej aplikacji. Na przykład, w Safari można je znaleźć w /Applications/Safari.app/Contents/XPCServices
. Mają rozszerzenie .xpc
(jak com.apple.Safari.SandboxBroker.xpc
) i są również pakietami z głównym binarnym plikiem w środku: /Applications/Safari.app/Contents/XPCServices/com.apple.Safari.SandboxBroker.xpc/Contents/MacOS/com.apple.Safari.SandboxBroker
oraz Info.plist: /Applications/Safari.app/Contents/XPCServices/com.apple.Safari.SandboxBroker.xpc/Contents/Info.plist
Jak możesz się domyślać, komponent XPC będzie miał różne uprawnienia i przywileje niż inne komponenty XPC lub główny plik binarny aplikacji. Z WYJĄTKIEM przypadku, gdy usługa XPC jest skonfigurowana z JoinExistingSession ustawionym na „True” w swoim pliku Info.plist. W takim przypadku usługa XPC będzie działać w tej samej sesji bezpieczeństwa, co aplikacja, która ją wywołała.
Usługi XPC są uruchamiane przez launchd w razie potrzeby i zatrzymywane po zakończeniu wszystkich zadań, aby zwolnić zasoby systemowe. Specyficzne dla aplikacji komponenty XPC mogą być wykorzystywane tylko przez aplikację, co zmniejsza ryzyko związane z potencjalnymi lukami.
Usługi XPC w systemie są dostępne dla wszystkich użytkowników. Te usługi, czy to launchd, czy typu Mach, muszą być zdefiniowane w plikach plist znajdujących się w określonych katalogach, takich jak /System/Library/LaunchDaemons
, /Library/LaunchDaemons
, /System/Library/LaunchAgents
lub /Library/LaunchAgents
.
Te pliki plist będą miały klucz o nazwie MachServices
z nazwą usługi oraz klucz o nazwie Program
z ścieżką do pliku binarnego:
The ones in LaunchDameons
są uruchamiane przez root. Więc jeśli proces bez uprawnień może komunikować się z jednym z nich, może być w stanie eskalować uprawnienia.
xpc_object_t
Każda wiadomość XPC jest obiektem słownika, który upraszcza serializację i deserializację. Ponadto, libxpc.dylib
deklaruje większość typów danych, więc możliwe jest upewnienie się, że otrzymane dane są oczekiwanego typu. W API C każdy obiekt jest xpc_object_t
(a jego typ można sprawdzić za pomocą xpc_get_type(object)
).
Ponadto, funkcja xpc_copy_description(object)
może być używana do uzyskania reprezentacji tekstowej obiektu, co może być przydatne do celów debugowania.
Te obiekty mają również pewne metody do wywołania, takie jak xpc_<object>_copy
, xpc_<object>_equal
, xpc_<object>_hash
, xpc_<object>_serialize
, xpc_<object>_deserialize
...
Obiekty xpc_object_t
są tworzone przez wywołanie funkcji xpc_<objetType>_create
, która wewnętrznie wywołuje _xpc_base_create(Class, Size)
, gdzie wskazany jest typ klasy obiektu (jeden z XPC_TYPE_*
) oraz jego rozmiar (do rozmiaru zostanie dodane dodatkowe 40B na metadane). Co oznacza, że dane obiektu będą zaczynały się od offsetu 40B.
Dlatego xpc_<objectType>_t
jest rodzajem podklasy xpc_object_t
, która byłaby podklasą os_object_t*
.
Należy zauważyć, że to deweloper powinien używać xpc_dictionary_[get/set]_<objectType>
, aby uzyskać lub ustawić typ i rzeczywistą wartość klucza.
xpc_pipe
xpc_pipe
to rura FIFO, którą procesy mogą używać do komunikacji (komunikacja wykorzystuje wiadomości Mach).
Możliwe jest utworzenie serwera XPC, wywołując xpc_pipe_create()
lub xpc_pipe_create_from_port()
, aby utworzyć go za pomocą konkretnego portu Mach. Następnie, aby odbierać wiadomości, można wywołać xpc_pipe_receive
i xpc_pipe_try_receive
.
Należy zauważyć, że obiekt xpc_pipe
jest xpc_object_t
z informacjami w swojej strukturze o dwóch używanych portach Mach oraz nazwie (jeśli istnieje). Nazwa, na przykład, demona secinitd
w jego plist /System/Library/LaunchDaemons/com.apple.secinitd.plist
konfiguruje rurę o nazwie com.apple.secinitd
.
Przykładem xpc_pipe
jest bootstrap pipe utworzona przez launchd
, co umożliwia udostępnianie portów Mach.
NSXPC*
To są obiekty wysokiego poziomu Objective-C, które umożliwiają abstrakcję połączeń XPC. Ponadto łatwiej jest debugować te obiekty za pomocą DTrace niż poprzednie.
GCD Queues
XPC używa GCD do przesyłania wiadomości, ponadto generuje pewne kolejki dyspozycyjne, takie jak xpc.transactionq
, xpc.io
, xpc-events.add-listenerq
, xpc.service-instance
...
To są bundles z rozszerzeniem .xpc
znajdujące się w folderze XPCServices
innych projektów, a w Info.plist
mają ustawiony CFBundlePackageType
na XPC!
.
Ten plik ma inne klucze konfiguracyjne, takie jak ServiceType
, które mogą być Application, User, System lub _SandboxProfile
, które mogą definiować piaskownicę, lub _AllowedClients
, które mogą wskazywać uprawnienia lub ID wymagane do kontaktu z serwisem. Te i inne opcje konfiguracyjne będą przydatne do skonfigurowania usługi podczas uruchamiania.
Aplikacja próbuje połączyć się z usługą XPC, używając xpc_connection_create_mach_service
, następnie launchd lokalizuje demona i uruchamia xpcproxy
. xpcproxy
egzekwuje skonfigurowane ograniczenia i uruchamia usługę z podanymi FD i portami Mach.
Aby poprawić szybkość wyszukiwania usługi XPC, używana jest pamięć podręczna.
Możliwe jest śledzenie działań xpcproxy
za pomocą:
The XPC library używa kdebug
do logowania działań wywołując xpc_ktrace_pid0
i xpc_ktrace_pid1
. Kody, których używa, są niedokumentowane, więc należy je dodać do /usr/share/misc/trace.codes
. Mają prefiks 0x29
, a na przykład jeden z nich to 0x29000004
: XPC_serializer_pack
.
Narzędzie xpcproxy
używa prefiksu 0x22
, na przykład: 0x2200001c: xpcproxy:will_do_preexec
.
Aplikacje mogą subskrybować różne wiadomości zdarzeń, co umożliwia ich inicjowanie na żądanie, gdy takie zdarzenia występują. Konfiguracja tych usług odbywa się w plikach launchd plist, znajdujących się w tych samych katalogach co poprzednie i zawierających dodatkowy klucz LaunchEvent
.
Gdy proces próbuje wywołać metodę za pośrednictwem połączenia XPC, usługa XPC powinna sprawdzić, czy ten proces ma prawo się połączyć. Oto powszechne sposoby sprawdzania tego oraz typowe pułapki:
macOS XPC Connecting Process CheckApple również pozwala aplikacjom na konfigurowanie niektórych praw i sposobów ich uzyskania, więc jeśli wywołujący proces je ma, będzie mógł wywołać metodę z usługi XPC:
macOS XPC AuthorizationAby podsłuchiwać wiadomości XPC, możesz użyć xpcspy, które używa Frida.
Innym możliwym narzędziem do użycia jest XPoCe2.
Ta funkcjonalność dostarczana przez RemoteXPC.framework
(z libxpc
) pozwala na komunikację za pomocą XPC między różnymi hostami.
Usługi, które obsługują zdalne XPC, będą miały w swoim plist klucz UsesRemoteXPC, jak ma to miejsce w przypadku /System/Library/LaunchDaemons/com.apple.SubmitDiagInfo.plist
. Jednakże, chociaż usługa będzie zarejestrowana w launchd
, to UserEventAgent
z wtyczkami com.apple.remoted.plugin
i com.apple.remoteservicediscovery.events.plugin
zapewnia tę funkcjonalność.
Co więcej, RemoteServiceDiscovery.framework
pozwala na uzyskanie informacji z com.apple.remoted.plugin
, udostępniając funkcje takie jak get_device
, get_unique_device
, connect
...
Gdy connect
zostanie użyty i gniazdo fd
usługi zostanie zebrane, możliwe jest użycie klasy remote_xpc_connection_*
.
Możliwe jest uzyskanie informacji o zdalnych usługach za pomocą narzędzia cli /usr/libexec/remotectl
, używając parametrów takich jak:
Komunikacja między BridgeOS a hostem odbywa się przez dedykowany interfejs IPv6. MultiverseSupport.framework
umożliwia nawiązywanie gniazd, których fd
będzie używane do komunikacji.
Można znaleźć te komunikacje za pomocą netstat
, nettop
lub opcji open source, netbottom
.
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)