macOS xpc_connection_get_audit_token Atak
Reading time: 11 minutes
tip
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)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Po więcej informacji sprawdź oryginalny wpis: https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/. Poniżej streszczenie:
Mach Messages — podstawowe informacje
Jeśli nie wiesz, czym są Mach Messages, zacznij od sprawdzenia tej strony:
macOS IPC - Inter Process Communication
Na razie zapamiętaj, że (definicja stąd):
Mach messages są wysyłane przez mach port, który jest kanałem komunikacji single receiver, multiple sender wbudowanym w mach kernel. Wiele procesów może wysyłać wiadomości do mach portu, ale w danym momencie tylko jeden proces może z niego czytać. Podobnie jak deskryptory plików i gniazda, mach ports są przydzielane i zarządzane przez kernel, a procesy widzą jedynie liczbę całkowitą, której mogą użyć, aby wskazać kernelowi, którego z ich mach ports chcą użyć.
XPC Connection
Jeśli nie wiesz, jak nawiązywane jest połączenie XPC, sprawdź:
Podsumowanie podatności
Warto wiedzieć, że abstrakcja XPC to połączenie one-to-one, ale opiera się na technologii, która może mieć wielu nadawców, więc:
- Mach ports są single receiver, multiple sender.
- Audit token połączenia XPC jest skopiowany z ostatnio otrzymanej wiadomości.
- Uzyskanie audit token połączenia XPC jest krytyczne dla wielu kontroli bezpieczeństwa.
Mimo że powyższa sytuacja wygląda groźnie, istnieją scenariusze, w których to nie powoduje problemów (stąd):
- Audit tokens są często wykorzystywane do sprawdzenia autoryzacji decydującego o zaakceptowaniu połączenia. Ponieważ odbywa się to przez wiadomość do service portu, połączenie jeszcze nie zostało ustanowione. Kolejne wiadomości na tym porcie będą po prostu traktowane jako dodatkowe żądania połączenia. Zatem jakiekolwiek sprawdzenia przed zaakceptowaniem połączenia nie są podatne (to także oznacza, że wewnątrz
-listener:shouldAcceptNewConnection:audit token jest bezpieczny). W związku z tym szukamy połączeń XPC, które weryfikują konkretne akcje. - Handlery zdarzeń XPC są obsługiwane synchronicznie. Oznacza to, że handler zdarzenia dla jednej wiadomości musi zakończyć wykonanie, zanim wywoła się handler dla następnej, nawet na współbieżnych kolejkach dispatch. Zatem wewnątrz XPC event handler audit token nie może zostać nadpisany przez inne normalne (nie-reply!) wiadomości.
Dwa różne sposoby, w które to może być wykorzystane:
- Variant1:
- Exploit connects to service A and service B
- Service B can call a privileged functionality in service A that the user cannot
- Service A calls
xpc_connection_get_audit_tokenwhile not inside the event handler for a connection in adispatch_async. - So a different message could overwrite the Audit Token because it's being dispatched asynchronously outside of the event handler.
- The exploit passes to service B the SEND right to service A.
- So svc B will be actually sending the messages to service A.
- The exploit tries to call the privileged action. In a RC svc A checks the authorization of this action while svc B overwrote the Audit token (giving the exploit access to call the privileged action).
- Variant 2:
- Service B can call a privileged functionality in service A that the user cannot
- Exploit connects with service A which sends the exploit a message expecting a response in a specific replay port.
- Exploit sends service B a message passing that reply port.
- When service B replies, it sends the message to service A, while the exploit sends a different message to service A trying to reach a privileged functionality and expecting that the reply from service B will overwrite the Audit token in the perfect moment (Race Condition).
Variant 1: calling xpc_connection_get_audit_token outside of an event handler
Scenariusz:
- Dwa mach services
AiB, do których obieca możemy się podłączyć (na podstawie profilu sandbox i sprawdzeń autoryzacji przed zaakceptowaniem połączenia). - A musi mieć sprawdzenie autoryzacji dla konkretnej akcji, którą
Bmoże przekazać (ale nasza aplikacja nie). - Na przykład, jeśli B ma pewne entitlements lub działa jako root, może poprosić A o wykonanie uprzywilejowanej akcji.
- Dla tego sprawdzenia autoryzacji,
Apozyskuje audit token asynchronicznie, na przykład wywołującxpc_connection_get_audit_tokenz poziomudispatch_async.
caution
W takim przypadku atakujący może wywołać Race Condition, tworząc exploit, który prosi A o wykonanie akcji wielokrotnie, jednocześnie zmuszając B do wysyłania wiadomości do A. Gdy RC powiedzie się, audit token należący do B zostanie skopiowany do pamięci w trakcie obsługi żądania naszego exploita przez A, dając mu dostęp do uprzywilejowanej akcji, do której dostęp miało tylko B.
To miało miejsce z A jako smd i B jako diagnosticd. Funkcja SMJobBless z smb może być użyta do zainstalowania nowego uprzywilejowanego helpera (jako root). Jeśli proces działający jako root kontaktuje smd, nie będą wykonywane żadne dodatkowe sprawdzenia.
Dlatego service B to diagnosticd, ponieważ działa jako root i może być użyte do monitorowania procesu — po rozpoczęciu monitorowania będzie on wysyłać wiele wiadomości na sekundę.
Aby przeprowadzić atak:
- Nawiąż połączenie z service o nazwie
smdużywając standardowego protokołu XPC. - Utwórz drugorzędne połączenie z
diagnosticd. W przeciwieństwie do normalnej procedury, zamiast tworzyć i wysyłać dwa nowe mach ports, prawa wysyłki klienta są zastępowane duplikatem send right powiązanego z połączeniemsmd. - W rezultacie wiadomości XPC mogą być wysyłane do
diagnosticd, ale odpowiedzi zdiagnosticdsą przekierowywane dosmd. Dlasmdwygląda to tak, jakby wiadomości zarówno od użytkownika, jak i oddiagnosticdpochodziły z tego samego połączenia.

- Następnie instruuje się
diagnosticd, aby rozpoczął monitorowanie wybranego procesu (potencjalnie własnego procesu użytkownika). Równocześnie wysyłana jest zalewowa ilość rutynowych wiadomości 1004 dosmd. Celem jest zainstalowanie narzędzia z podwyższonymi uprawnieniami. - To powoduje race condition w funkcji
handle_bless. Czas jest krytyczny: wywołaniexpc_connection_get_pidmusi zwrócić PID procesu użytkownika (ponieważ uprzywilejowane narzędzie znajduje się w bundle aplikacji użytkownika). Jednakxpc_connection_get_audit_token, konkretnie w podprogramieconnection_is_authorized, musi odwoływać się do audit token należącego dodiagnosticd.
Variant 2: reply forwarding
W środowisku XPC, chociaż handlery zdarzeń nie wykonują się współbieżnie, przetwarzanie wiadomości reply ma specyficzne zachowanie. Konkretnie, istnieją dwa odrębne sposoby wysyłania wiadomości oczekujących na odpowiedź:
xpc_connection_send_message_with_reply: Tutaj wiadomość XPC jest odbierana i przetwarzana na wskazanej kolejce.xpc_connection_send_message_with_reply_sync: Natomiast w tej metodzie wiadomość XPC jest odbierana i przetwarzana na aktualnej kolejce dispatch.
To rozróżnienie jest kluczowe, ponieważ pozwala na możliwość, że pakiety reply są parsowane współbieżnie z wykonywaniem handlera zdarzenia XPC. Warto zauważyć, że chociaż _xpc_connection_set_creds implementuje blokowanie chroniące przed częściowym nadpisaniem audit token, nie rozszerza tej ochrony na cały obiekt połączenia. W konsekwencji powstaje luka, w której audit token może zostać zastąpiony w przedziale czasu pomiędzy parsowaniem pakietu a wykonaniem jego handlera zdarzenia.
Aby wykorzystać tę lukę, wymagane jest następujące ustawienie:
- Dwa mach services, oznaczone jako
AiB, które oba mogą nawiązać połączenie. - Service
Apowinien zawierać sprawdzenie autoryzacji dla konkretnej akcji, którą tylkoBmoże wykonać (aplikacja użytkownika nie). - Service
Apowinien wysłać wiadomość oczekującą na reply. - Użytkownik może wysłać wiadomość do
B, na którą B odpowie.
Proces eksploatacji obejmuje kroki:
- Czekaj, aż service
Awyśle wiadomość oczekującą na reply. - Zamiast odpowiadać bezpośrednio
A, port reply zostaje przechwycony i użyty do wysłania wiadomości do serviceB. - Następnie wysyłana jest wiadomość dotycząca zabronionej akcji, z oczekiwaniem, że zostanie przetworzona współbieżnie z reply od
B.
Poniżej wizualna reprezentacja opisanego scenariusza ataku:
 (1) (1) (1) (1) (1) (1).png)
.png)
Problemy z odkrywaniem
- Trudności w odnalezieniu wystąpień: Wyszukiwanie użyć
xpc_connection_get_audit_tokenbyło trudne, zarówno statycznie, jak i dynamicznie. - Metodologia: Użyto Frida do hookowania funkcji
xpc_connection_get_audit_token, filtrując wywołania niezależne od event handlerów. Jednak ta metoda była ograniczona do procesu, w którym zaaplikowano hook, i wymagała aktywnego użycia. - Narzędzia analityczne: Narzędzia takie jak IDA/Ghidra były używane do badania osiągalnych mach services, ale proces był czasochłonny, utrudniony wywołaniami z dyld shared cache.
- Ograniczenia skryptowe: Próby zautomatyzowania analizy pod kątem wywołań
xpc_connection_get_audit_tokenz blokówdispatch_asyncbyły utrudnione złożonością parsowania bloków i interakcjami z dyld shared cache.
Poprawka
- Zgłoszone problemy: Zgłoszono Apple ogólne i szczegółowe problemy znalezione w
smd. - Odpowiedź Apple: Apple zaadresowało problem w
smdzastępującxpc_connection_get_audit_tokenfunkcjąxpc_dictionary_get_audit_token. - Charakter poprawki: Funkcja
xpc_dictionary_get_audit_tokenjest uważana za bezpieczną, ponieważ pobiera audit token bezpośrednio z mach message związanego z otrzymaną wiadomością XPC. Jednak nie jest częścią publicznego API, podobnie jakxpc_connection_get_audit_token. - Brak szerszego rozwiązania: Nie jest jasne, dlaczego Apple nie wdrożyło bardziej ogólnego rozwiązania, takiego jak odrzucanie wiadomości, które nie zgadzają się z zapisanym audit token połączenia. Możliwe, że zmiana audit token w pewnych scenariuszach (np. użycie
setuid) może być uzasadniona. - Aktualny stan: Luka utrzymuje się w iOS 17 i macOS 14, co utrudnia jej identyfikację i zrozumienie.
Znajdowanie podatnych ścieżek kodu w praktyce (2024–2025)
Podczas audytu usług XPC pod kątem tej klasy błędów, skup się na autoryzacji wykonywanej poza handlerem wiadomości lub równocześnie z przetwarzaniem reply.
Wskazówki do statycznego triage:
- Szukaj wywołań
xpc_connection_get_audit_tokenosiągalnych z bloków umieszczonych za pomocądispatch_async/dispatch_afterlub innych worker queues, które działają poza handlerem wiadomości. - Szukaj helperów autoryzacyjnych, które mieszają stan per-connection i per-message (np. pobieranie PID przez
xpc_connection_get_pid, ale audit token przezxpc_connection_get_audit_token). - W kodzie NSXPC upewnij się, że sprawdzenia są wykonywane w
-listener:shouldAcceptNewConnection:, lub dla sprawdzeń per-message, że implementacja używa per-message audit token (np. słownika wiadomości przezxpc_dictionary_get_audit_tokenw kodzie niższego poziomu).
Wskazówki do dynamicznego triage:
- Hookuj
xpc_connection_get_audit_tokeni oznaczaj wywołania, których stos użytkownika nie zawiera ścieżki dostarczania zdarzeń (np._xpc_connection_mach_event). Przykład hooka Frida:
Interceptor.attach(Module.getExportByName(null, 'xpc_connection_get_audit_token'), {
onEnter(args) {
const bt = Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n');
if (!bt.includes('_xpc_connection_mach_event')) {
console.log('[!] xpc_connection_get_audit_token outside handler\n' + bt);
}
}
});
Notatki:
- Na macOS instrumentowanie protected/Apple binaries może wymagać wyłączenia SIP lub środowiska deweloperskiego; preferuj testowanie własnych builds lub userland services.
- Dla reply-forwarding races (Variant 2) monitoruj jednoczesne parsowanie reply packets, fuzzując timingi
xpc_connection_send_message_with_replywzględem normalnych requestów i sprawdzając, czy efektywny audit token używany podczas autoryzacji może być zmanipulowany.
Primitwy eksploatacji, których prawdopodobnie będziesz potrzebować
- Multi-sender setup (Variant 1): utwórz połączenia do A i B; zdubluj send right portu klienta A i użyj go jako portu klienta B, tak aby odpowiedzi B były dostarczane do A.
// Duplicate a SEND right you already hold
mach_port_t dup;
mach_port_insert_right(mach_task_self(), a_client, a_client, MACH_MSG_TYPE_MAKE_SEND);
dup = a_client; // use `dup` when crafting B’s connect packet instead of a fresh client port
- Reply hijack (Variant 2): przechwyć prawo send-once z oczekującego żądania A (reply port), a następnie wyślij spreparowaną wiadomość do B używając tego reply port, tak aby odpowiedź B trafiła do A podczas parsowania twojego uprzywilejowanego żądania.
These require low-level mach message crafting for the XPC bootstrap and message formats; review the mach/XPC primer pages in this section for the exact packet layouts and flags.
Przydatne narzędzia
- XPC sniffing/dynamic inspection: gxpc (open-source XPC sniffer) może pomóc w enumeracji połączeń i obserwacji ruchu, aby zweryfikować konfiguracje z wieloma nadawcami i synchronizację. Example:
gxpc -p <PID> --whitelist <service-name>. - Classic dyld interposing for libxpc: interpose on
xpc_connection_send_message*andxpc_connection_get_audit_tokenaby logować miejsca wywołań i stosy podczas testów black-box.
Źródła
- Sector 7 – Don’t Talk All at Once! Podnoszenie uprawnień na macOS przez Audit Token Spoofing: https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/
- Apple – O zawartości zabezpieczeń macOS Ventura 13.4 (CVE‑2023‑32405): https://support.apple.com/en-us/106333
tip
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)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
HackTricks