From 5d5313773f87495690b04a6b277ab0cd5aa99805 Mon Sep 17 00:00:00 2001 From: Translator Date: Wed, 23 Jul 2025 10:11:35 +0000 Subject: [PATCH] Translated ['src/macos-hardening/macos-security-and-privilege-escalation --- .../macos-thread-injection-via-task-port.md | 162 ++++++++++-------- 1 file changed, 87 insertions(+), 75 deletions(-) diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md index 396a89a94..141c4d85c 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md @@ -9,47 +9,47 @@ ## 1. Thread Hijacking -U početku, **`task_threads()`** funkcija se poziva na task portu da bi se dobila lista niti iz udaljenog taska. Niti se bira za preuzimanje. Ovaj pristup se razlikuje od konvencionalnih metoda injekcije koda jer je kreiranje nove udaljene niti zabranjeno zbog nove mitigacije koja blokira `thread_create_running()`. +U početku, `task_threads()` funkcija se poziva na task port da bi se dobila lista niti iz udaljenog taska. Niti se bira za preuzimanje. Ovaj pristup se razlikuje od konvencionalnih metoda injekcije koda jer je kreiranje nove udaljene niti zabranjeno zbog mitigacije koja blokira `thread_create_running()`. -Da bi se kontrolisala nit, poziva se **`thread_suspend()`**, zaustavljajući njeno izvršavanje. +Da bi se kontrolisala nit, poziva se `thread_suspend()`, zaustavljajući njeno izvršavanje. -Jedine operacije dozvoljene na udaljenoj niti uključuju **zaustavljanje** i **pokretanje** nje, **dobijanje** i **modifikovanje** njenih registarskih vrednosti. Udaljeni pozivi funkcija se iniciraju postavljanjem registara `x0` do `x7` na **argumente**, konfigurišući **`pc`** da cilja željenu funkciju, i aktivirajući nit. Osiguranje da nit ne sruši nakon povratka zahteva detekciju povratka. +Jedine operacije dozvoljene na udaljenoj niti uključuju **zaustavljanje** i **pokretanje** nje i **dobijanje**/**modifikovanje** njenih registarskih vrednosti. Udaljeni pozivi funkcija se iniciraju postavljanjem registara `x0` do `x7` na **argumente**, konfigurišući `pc` da cilja željenu funkciju, i nastavljajući nit. Osiguranje da nit ne sruši nakon povratka zahteva detekciju povratka. -Jedna strategija uključuje **registraciju handler-a za izuzetke** za udaljenu nit koristeći `thread_set_exception_ports()`, postavljajući `lr` registar na nevažeću adresu pre poziva funkcije. Ovo pokreće izuzetak nakon izvršenja funkcije, šaljući poruku na port izuzetaka, omogućavajući inspekciju stanja niti da se povrati povratna vrednost. Alternativno, kao što je preuzeto iz Ian Beer-ovog triple_fetch exploit-a, `lr` se postavlja da se beskonačno ponavlja. Registri niti se zatim kontinuirano prate dok **`pc` ne ukazuje na tu instrukciju**. +Jedna strategija uključuje registraciju **handler-a za izuzetke** za udaljenu nit koristeći `thread_set_exception_ports()`, postavljajući `lr` registar na nevalidnu adresu pre poziva funkcije. Ovo izaziva izuzetak nakon izvršenja funkcije, šaljući poruku na port izuzetaka, omogućavajući inspekciju stanja niti da se povrati povratna vrednost. Alternativno, kao što je preuzeto iz *triple_fetch* eksploita Iana Beera, `lr` se postavlja da beskonačno petlja; registri niti se zatim kontinuirano prate dok `pc` ne ukazuje na tu instrukciju. ## 2. Mach ports for communication -Sledeća faza uključuje uspostavljanje Mach portova za olakšavanje komunikacije sa udaljenom niti. Ovi portovi su ključni za prenos proizvoljnih prava slanja i primanja između taskova. +Sledeća faza uključuje uspostavljanje Mach portova za olakšavanje komunikacije sa udaljenom niti. Ovi portovi su ključni za prenos proizvoljnih prava slanja/primanja između taskova. -Za dvosmernu komunikaciju, kreiraju se dva Mach prava primanja: jedno u lokalnom i drugo u udaljenom tasku. Nakon toga, pravo slanja za svaki port se prenosi u odgovarajući task, omogućavajući razmenu poruka. +Za dvosmernu komunikaciju, kreiraju se dva Mach prava za primanje: jedno u lokalnom i drugo u udaljenom tasku. Nakon toga, pravo slanja za svaki port se prenosi u odgovarajući task, omogućavajući razmenu poruka. -Fokusirajući se na lokalni port, pravo primanja drži lokalni task. Port se kreira sa `mach_port_allocate()`. Izazov leži u prenosu prava slanja na ovaj port u udaljeni task. +Fokusirajući se na lokalni port, pravo za primanje drži lokalni task. Port se kreira pomoću `mach_port_allocate()`. Izazov leži u prenosu prava slanja na ovaj port u udaljeni task. Strategija uključuje korišćenje `thread_set_special_port()` da se postavi pravo slanja na lokalni port u `THREAD_KERNEL_PORT` udaljene niti. Zatim, udaljenoj niti se naređuje da pozove `mach_thread_self()` da bi dobila pravo slanja. -Za udaljeni port, proces se suštinski obrće. Udaljena nit se usmerava da generiše Mach port putem `mach_reply_port()` (jer `mach_port_allocate()` nije prikladan zbog svog mehanizma vraćanja). Nakon kreiranja porta, `mach_port_insert_right()` se poziva u udaljenoj niti da uspostavi pravo slanja. Ovo pravo se zatim čuva u kernelu koristeći `thread_set_special_port()`. Ponovo u lokalnom tasku, `thread_get_special_port()` se koristi na udaljenoj niti da bi se steklo pravo slanja na novokreirani Mach port u udaljenom tasku. +Za udaljeni port, proces je suštinski obrnut. Udaljenoj niti se naređuje da generiše Mach port putem `mach_reply_port()` (jer `mach_port_allocate()` nije prikladan zbog svog mehanizma vraćanja). Nakon kreiranja porta, `mach_port_insert_right()` se poziva u udaljenoj niti da bi se uspostavilo pravo slanja. Ovo pravo se zatim čuva u kernelu koristeći `thread_set_special_port()`. Ponovo u lokalnom tasku, `thread_get_special_port()` se koristi na udaljenoj niti da bi se steklo pravo slanja na novokreirani Mach port u udaljenom tasku. Završetak ovih koraka rezultira uspostavljanjem Mach portova, postavljajući temelje za dvosmernu komunikaciju. ## 3. Basic Memory Read/Write Primitives -U ovom odeljku, fokus je na korišćenju izvršnog primitiva za uspostavljanje osnovnih primitiva za čitanje i pisanje u memoriju. Ovi inicijalni koraci su ključni za sticanje veće kontrole nad udaljenim procesom, iako primitivi u ovoj fazi neće služiti mnogim svrhama. Ubrzo će biti unapređeni na naprednije verzije. +U ovom odeljku, fokus je na korišćenju izvršnog primitiva za uspostavljanje osnovnih primitiva za čitanje/pisanje u memoriju. Ovi inicijalni koraci su ključni za sticanje veće kontrole nad udaljenim procesom, iako primitivi u ovoj fazi neće služiti mnogim svrhama. Ubrzo će biti unapređeni na naprednije verzije. -### Memory Reading and Writing Using Execute Primitive +### Memory reading and writing using the execute primitive -Cilj je izvršiti čitanje i pisanje u memoriju koristeći specifične funkcije. Za čitanje memorije koriste se funkcije koje podsećaju na sledeću strukturu: +Cilj je izvršiti čitanje i pisanje u memoriju koristeći specifične funkcije. Za **čitanje memorije**: ```c uint64_t read_func(uint64_t *address) { return *address; } ``` -I za pisanje u memoriju koriste se funkcije slične ovoj strukturi: +Za **pisanje u memoriju**: ```c void write_func(uint64_t *address, uint64_t value) { *address = value; } ``` -Ove funkcije odgovaraju datim asembler instrukcijama: +Ove funkcije odgovaraju sledećem asembleru: ``` _read_func: ldr x0, [x0] @@ -58,104 +58,116 @@ _write_func: str x1, [x0] ret ``` -### Identifying Suitable Functions +### Identifikacija pogodnih funkcija -Skeneranje uobičajenih biblioteka otkrilo je odgovarajuće kandidate za ove operacije: +Skeniranje uobičajenih biblioteka otkrilo je odgovarajuće kandidate za ove operacije: -1. **Reading Memory:** -Funkcija `property_getName()` iz [Objective-C runtime library](https://opensource.apple.com/source/objc4/objc4-723/runtime/objc-runtime-new.mm.auto.html) je identifikovana kao pogodna funkcija za čitanje memorije. Funkcija je opisana u nastavku: +1. **Čitanje memorije — `property_getName()`** (libobjc): ```c const char *property_getName(objc_property_t prop) { return prop->name; } ``` -Ova funkcija efikasno deluje kao `read_func` vraćajući prvo polje `objc_property_t`. - -2. **Pisanje u Memoriju:** -Pronalaženje unapred izgrađene funkcije za pisanje u memoriju je izazovnije. Međutim, funkcija `_xpc_int64_set_value()` iz libxpc je odgovarajući kandidat sa sledećom disasembly: +2. **Pisanje u memoriju — `_xpc_int64_set_value()`** (libxpc): ```c __xpc_int64_set_value: str x1, [x0, #0x18] ret ``` -Da biste izvršili 64-bitno pisanje na specifičnu adresu, daleki poziv je strukturiran kao: +Da biste izvršili 64-bitno pisanje na proizvoljnu adresu: ```c -_xpc_int64_set_value(address - 0x18, value) +_xpc_int64_set_value(address - 0x18, value); ``` -Sa ovim postavljenim primitivima, scena je postavljena za kreiranje deljene memorije, što predstavlja značajan napredak u kontroli udaljenog procesa. +Sa ovim postavljenim primitivima, postavljena je scena za kreiranje deljene memorije, što predstavlja značajan napredak u kontroli udaljenog procesa. -## 4. Postavljanje Deljene Memorije +## 4. Postavljanje deljene memorije -Cilj je uspostaviti deljenu memoriju između lokalnih i udaljenih zadataka, pojednostavljujući prenos podataka i olakšavajući pozivanje funkcija sa više argumenata. Pristup uključuje korišćenje `libxpc` i njegovog `OS_xpc_shmem` tipa objekta, koji se zasniva na Mach memorijskim unosima. +Cilj je uspostaviti deljenu memoriju između lokalnih i udaljenih zadataka, pojednostavljujući prenos podataka i olakšavajući pozivanje funkcija sa više argumenata. Pristup koristi `libxpc` i njegov `OS_xpc_shmem` tip objekta, koji se zasniva na Mach memorijskim unosima. -### Pregled Procesa: +### Pregled procesa -1. **Alokacija Memorije**: +1. **Alokacija memorije** +* Alocirajte memoriju za deljenje koristeći `mach_vm_allocate()`. +* Koristite `xpc_shmem_create()` za kreiranje `OS_xpc_shmem` objekta za alociranu oblast. +2. **Kreiranje deljene memorije u udaljenom procesu** +* Alocirajte memoriju za `OS_xpc_shmem` objekat u udaljenom procesu (`remote_malloc`). +* Kopirajte lokalni šablon objekta; ispravka ugrađenog Mach prava slanja na offsetu `0x18` je još uvek potrebna. +3. **Ispravljanje Mach memorijskog unosa** +* Umetnite pravo slanja sa `thread_set_special_port()` i prepišite polje `0x18` imenom udaljenog unosa. +4. **Finalizacija** +* Validirajte udaljeni objekat i mapirajte ga sa udaljenim pozivom na `xpc_shmem_remote()`. -- Alocirajte memoriju za deljenje koristeći `mach_vm_allocate()`. -- Koristite `xpc_shmem_create()` za kreiranje `OS_xpc_shmem` objekta za alociranu memorijsku oblast. Ova funkcija će upravljati kreiranjem Mach memorijskog unosa i čuvati Mach send pravo na offsetu `0x18` objekta `OS_xpc_shmem`. +## 5. Postizanje potpune kontrole -2. **Kreiranje Deljene Memorije u Udaljenom Procesu**: +Kada su dostupne proizvoljne izvršne i deljene memorijske povratne veze, efikasno posedujete ciljni proces: -- Alocirajte memoriju za `OS_xpc_shmem` objekat u udaljenom procesu sa udaljenim pozivom na `malloc()`. -- Kopirajte sadržaj lokalnog `OS_xpc_shmem` objekta u udaljeni proces. Međutim, ova inicijalna kopija će imati netačne nazive Mach memorijskih unosa na offsetu `0x18`. +* **Proizvoljno čitanje/pisanje memorije** — koristite `memcpy()` između lokalnih i deljenih oblasti. +* **Pozivi funkcija sa > 8 argumenata** — stavite dodatne argumente na stek prema arm64 konvenciji pozivanja. +* **Prenos Mach portova** — prosledite prava u Mach porukama putem uspostavljenih portova. +* **Prenos deskriptora datoteka** — iskoristite fileports (vidi *triple_fetch*). -3. **Ispravljanje Mach Memorijskog Unosa**: +Sve ovo je obavijeno u [`threadexec`](https://github.com/bazad/threadexec) biblioteci za laku ponovnu upotrebu. -- Iskoristite metodu `thread_set_special_port()` da umetnete send pravo za Mach memorijski unos u udaljeni zadatak. -- Ispravite polje Mach memorijskog unosa na offsetu `0x18` prepisivanjem sa imenom udaljenog memorijskog unosa. +--- -4. **Finalizacija Postavljanja Deljene Memorije**: -- Validirajte udaljeni `OS_xpc_shmem` objekat. -- Uspostavite mapiranje deljene memorije sa udaljenim pozivom na `xpc_shmem_remote()`. +## 6. Nuance Apple Silicon (arm64e) -Prateći ove korake, deljena memorija između lokalnih i udaljenih zadataka biće efikasno postavljena, omogućavajući jednostavne prenose podataka i izvršavanje funkcija koje zahtevaju više argumenata. +Na Apple Silicon uređajima (arm64e) **Kodovi za autentifikaciju pokazivača (PAC)** štite sve adrese povratka i mnoge pokazivače funkcija. Tehnike preuzimanja niti koje *ponovo koriste postojeći kod* nastavljaju da funkcionišu jer originalne vrednosti u `lr`/`pc` već nose važeće PAC potpise. Problemi se javljaju kada pokušate da skočite na memoriju pod kontrolom napadača: -## Dodatni Kodni Snippets - -Za alokaciju memorije i kreiranje objekta deljene memorije: +1. Alocirajte izvršnu memoriju unutar cilja (udaljeni `mach_vm_allocate` + `mprotect(PROT_EXEC)`). +2. Kopirajte svoj payload. +3. Unutar *udaljenog* procesa potpišite pokazivač: ```c -mach_vm_allocate(); -xpc_shmem_create(); +uint64_t ptr = (uint64_t)payload; +ptr = ptrauth_sign_unauthenticated((void*)ptr, ptrauth_key_asia, 0); ``` -Za kreiranje i ispravljanje objekta deljene memorije u udaljenom procesu: -```c -malloc(); // for allocating memory remotely -thread_set_special_port(); // for inserting send right +4. Postavite `pc = ptr` u stanju otete niti. + +Alternativno, ostanite PAC-usaglasni povezivanjem postojećih gadgeta/funkcija (tradicionalni ROP). + +## 7. Detekcija i Ojačavanje sa EndpointSecurity + +**EndpointSecurity (ES)** okvir izlaže kernel događaje koji omogućavaju odbrambenim snagama da posmatraju ili blokiraju pokušaje injekcije niti: + +* `ES_EVENT_TYPE_AUTH_GET_TASK` – aktivira se kada proces zatraži port druge niti (npr. `task_for_pid()`). +* `ES_EVENT_TYPE_NOTIFY_REMOTE_THREAD_CREATE` – emituje se svaki put kada se niti kreira u *drugom* zadatku. +* `ES_EVENT_TYPE_NOTIFY_THREAD_SET_STATE` (dodato u macOS 14 Sonoma) – ukazuje na manipulaciju registrima postojeće niti. + +Minimalni Swift klijent koji ispisuje događaje udaljenih niti: +```swift +import EndpointSecurity + +let client = try! ESClient(subscriptions: [.notifyRemoteThreadCreate]) { +(_, msg) in +if let evt = msg.remoteThreadCreate { +print("[ALERT] remote thread in pid \(evt.target.pid) by pid \(evt.thread.pid)") +} +} +RunLoop.main.run() ``` -Zapamtite da pravilno obradite detalje Mach portova i imena ulaza u memoriju kako biste osigurali da podešavanje deljene memorije funkcioniše ispravno. +Upit sa **osquery** ≥ 5.8: +```sql +SELECT target_pid, source_pid, target_path +FROM es_process_events +WHERE event_type = 'REMOTE_THREAD_CREATE'; +``` +### Razmatranja o ojačanom izvršavanju -## 5. Postizanje Potpunog Kontrola +Distribucija vaše aplikacije **bez** `com.apple.security.get-task-allow` prava sprečava napadače koji nisu root da dobiju njen task-port. Sistem zaštite integriteta (SIP) i dalje blokira pristup mnogim Apple binarnim datotekama, ali softver trećih strana mora eksplicitno da se isključi. -Nakon uspešnog uspostavljanja deljene memorije i sticanja sposobnosti proizvoljnog izvršavanja, suštinski smo stekli potpunu kontrolu nad ciljnim procesom. Ključne funkcionalnosti koje omogućavaju ovu kontrolu su: +## 8. Nedavni javni alati (2023-2025) -1. **Proizvoljne Operacije sa Memorijom**: +| Alat | Godina | Napomene | +|------|------|---------| +| [`task_vaccine`](https://github.com/rodionovd/task_vaccine) | 2023 | Kompaktni PoC koji demonstrira PAC-svesti preuzimanje niti na Ventura/Sonoma | +| `remote_thread_es` | 2024 | EndpointSecurity pomoćnik koji koriste nekoliko EDR dobavljača za prikazivanje `REMOTE_THREAD_CREATE` događaja | -- Izvršite proizvoljna čitanja iz memorije pozivajući `memcpy()` da kopirate podatke iz deljene oblasti. -- Izvršite proizvoljna pisanja u memoriju koristeći `memcpy()` za prenos podataka u deljenu oblast. - -2. **Obrada Poziva Funkcija sa Više Argumenta**: - -- Za funkcije koje zahtevaju više od 8 argumenata, rasporedite dodatne argumente na steku u skladu sa konvencijom pozivanja. - -3. **Prenos Mach Portova**: - -- Prenesite Mach portove između zadataka putem Mach poruka preko prethodno uspostavljenih portova. - -4. **Prenos Fajl Deskriptora**: -- Prenesite fajl deskriptore između procesa koristeći fileports, tehniku koju je istakao Ian Beer u `triple_fetch`. - -Ova sveobuhvatna kontrola je obuhvaćena unutar [threadexec](https://github.com/bazad/threadexec) biblioteke, koja pruža detaljnu implementaciju i korisnički prijateljski API za interakciju sa procesom žrtve. - -## Važne Napomene: - -- Osigurajte pravilnu upotrebu `memcpy()` za operacije čitanja/pisanja u memoriju kako biste održali stabilnost sistema i integritet podataka. -- Prilikom prenosa Mach portova ili fajl deskriptora, pridržavajte se pravilnih protokola i odgovorno rukujte resursima kako biste sprečili curenje ili nepredviđeni pristup. - -Pridržavanjem ovih smernica i korišćenjem `threadexec` biblioteke, može se efikasno upravljati i interagovati sa procesima na granularnom nivou, postižući potpunu kontrolu nad ciljnim procesom. +> Čitanje izvornog koda ovih projekata je korisno za razumevanje promena API-ja uvedenih u macOS 13/14 i za održavanje kompatibilnosti između Intel ↔ Apple Silicon. ## Reference - [https://bazad.github.io/2018/10/bypassing-platform-binary-task-threads/](https://bazad.github.io/2018/10/bypassing-platform-binary-task-threads/) +- [https://github.com/rodionovd/task_vaccine](https://github.com/rodionovd/task_vaccine) +- [https://developer.apple.com/documentation/endpointsecurity/es_event_type_notify_remote_thread_create](https://developer.apple.com/documentation/endpointsecurity/es_event_type_notify_remote_thread_create) {{#include ../../../../banners/hacktricks-training.md}}