macOS Thread Injection via Task port

Reading time: 8 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Code

1. Thread Hijacking

Kwanza, task_threads() inaitwa kwenye task port ili kupata orodha ya nyuzi kutoka kwa kazi ya mbali. Nyuzi moja inachaguliwa kwa ajili ya hijacking. Njia hii inatofautiana na mbinu za kawaida za kuingiza msimbo kwani kuunda nyuzi mpya za mbali kunakatazwa kutokana na kuzuia mpya inayozuia thread_create_running().

Ili kudhibiti nyuzi, thread_suspend() inaitwa, ikisimamisha utekelezaji wake.

Operesheni pekee zinazoruhusiwa kwenye nyuzi ya mbali zinahusisha kusimamisha na kuanzisha hiyo, kupata na kubadilisha thamani za register zake. Kuitwa kwa kazi za mbali kunaanzishwa kwa kuweka register x0 hadi x7 kwa hoja, kuunda pc ili kuelekeza kwenye kazi inayotakiwa, na kuanzisha nyuzi. Kuhakikisha kuwa nyuzi haiporomoki baada ya kurudi kunahitaji kugundua kurudi.

Stratejia moja inahusisha kujiandikisha kwa mpangaji wa makosa kwa nyuzi ya mbali kwa kutumia thread_set_exception_ports(), kuweka register lr kwenye anwani isiyo sahihi kabla ya wito wa kazi. Hii inasababisha makosa baada ya utekelezaji wa kazi, ikituma ujumbe kwenye bandari ya makosa, ikiruhusu ukaguzi wa hali ya nyuzi ili kurejesha thamani ya kurudi. Vinginevyo, kama ilivyopitishwa kutoka kwa exploit ya triple_fetch ya Ian Beer, lr inawekwa ili kuzunguka bila kikomo. Register za nyuzi kisha zinafuatiliwa kwa muda mrefu hadi pc inapoelekeza kwenye hiyo amri.

2. Mach ports for communication

Awamu inayofuata inahusisha kuanzisha Mach ports ili kuwezesha mawasiliano na nyuzi ya mbali. Bandari hizi ni muhimu katika kuhamasisha haki za kutuma na kupokea zisizo na mipaka kati ya kazi.

Kwa mawasiliano ya pande mbili, haki mbili za kupokea Mach zinaundwa: moja katika kazi ya ndani na nyingine katika kazi ya mbali. Kisha, haki ya kutuma kwa kila bandari inahamishwa kwa kazi ya upande mwingine, ikiruhusu kubadilishana ujumbe.

Kuzingatia bandari ya ndani, haki ya kupokea inashikiliwa na kazi ya ndani. Bandari inaundwa kwa mach_port_allocate(). Changamoto iko katika kuhamasisha haki ya kutuma kwa bandari hii kwenye kazi ya mbali.

Stratejia moja inahusisha kutumia thread_set_special_port() kuweka haki ya kutuma kwa bandari ya ndani katika THREAD_KERNEL_PORT ya nyuzi ya mbali. Kisha, nyuzi ya mbali inaelekezwa kuita mach_thread_self() ili kupata haki ya kutuma.

Kwa bandari ya mbali, mchakato kimsingi unabadilishwa. Nyuzi ya mbali inaelekezwa kuunda bandari ya Mach kupitia mach_reply_port() (kama mach_port_allocate() haiwezi kutumika kutokana na mfumo wake wa kurudi). Baada ya kuundwa kwa bandari, mach_port_insert_right() inaitwa katika nyuzi ya mbali ili kuanzisha haki ya kutuma. Haki hii kisha inahifadhiwa kwenye kernel kwa kutumia thread_set_special_port(). Kurudi kwenye kazi ya ndani, thread_get_special_port() inatumika kwenye nyuzi ya mbali ili kupata haki ya kutuma kwa bandari mpya iliyotolewa katika kazi ya mbali.

Kukamilika kwa hatua hizi kunasababisha kuanzishwa kwa Mach ports, kuweka msingi wa mawasiliano ya pande mbili.

3. Basic Memory Read/Write Primitives

Katika sehemu hii, lengo ni kutumia primitive ya kutekeleza ili kuanzisha primitive za msingi za kusoma na kuandika kumbukumbu. Hatua hizi za awali ni muhimu kwa kupata udhibiti zaidi juu ya mchakato wa mbali, ingawa primitive katika hatua hii hazitakuwa na matumizi mengi. Hivi karibuni, zitaimarishwa kuwa toleo za juu zaidi.

Memory Reading and Writing Using Execute Primitive

Lengo ni kufanya kusoma na kuandika kumbukumbu kwa kutumia kazi maalum. Kwa kusoma kumbukumbu, kazi zinazofanana na muundo ufuatao zinatumika:

c
uint64_t read_func(uint64_t *address) {
return *address;
}

Na kwa kuandika kwenye kumbukumbu, kazi zinazofanana na muundo huu hutumiwa:

c
void write_func(uint64_t *address, uint64_t value) {
*address = value;
}

Hizi kazi zinahusiana na maagizo ya mkusanyiko yaliyotolewa:

_read_func:
ldr x0, [x0]
ret
_write_func:
str x1, [x0]
ret

Kutambua Kazi Zinazofaa

Kuchunguza maktaba za kawaida kumefichua wagombea wanaofaa kwa ajili ya operesheni hizi:

  1. Kusoma Kumbukumbu: Funguo property_getName() kutoka kwa maktaba ya wakati wa Objective-C inatambuliwa kama kazi inayofaa kwa kusoma kumbukumbu. Kazi hiyo imeelezwa hapa chini:
c
const char *property_getName(objc_property_t prop) {
return prop->name;
}

Hii kazi inafanya kazi kama read_func kwa kurudisha uwanja wa kwanza wa objc_property_t.

  1. Kuandika Kumbukumbu: Kupata kazi iliyojengwa awali ya kuandika kumbukumbu ni changamoto zaidi. Hata hivyo, kazi ya _xpc_int64_set_value() kutoka libxpc ni mgombea mzuri ikiwa na disassembly ifuatayo:
c
__xpc_int64_set_value:
str x1, [x0, #0x18]
ret

Ili kufanya kuandika 64-bit katika anwani maalum, wito wa mbali umeundwa kama:

c
_xpc_int64_set_value(address - 0x18, value)

Kwa kutumia hizi primitives zilizowekwa, hatua imewekwa kwa ajili ya kuunda kumbukumbu ya pamoja, ikionyesha maendeleo makubwa katika kudhibiti mchakato wa mbali.

4. Mipangilio ya Kumbukumbu ya Pamoja

Lengo ni kuanzisha kumbukumbu ya pamoja kati ya kazi za ndani na za mbali, kuifanya iwe rahisi kuhamasisha data na kuwezesha wito wa kazi zenye hoja nyingi. Njia hii inahusisha kutumia libxpc na aina ya kitu chake OS_xpc_shmem, ambayo imejengwa juu ya entries za kumbukumbu za Mach.

Muonekano wa Mchakato:

  1. Usambazaji wa Kumbukumbu:
  • Panga kumbukumbu kwa ajili ya kushiriki kwa kutumia mach_vm_allocate().
  • Tumia xpc_shmem_create() kuunda kitu cha OS_xpc_shmem kwa ajili ya eneo la kumbukumbu lililotengwa. Kazi hii itasimamia uundaji wa entry ya kumbukumbu ya Mach na kuhifadhi haki ya kutuma ya Mach kwenye offset 0x18 ya kitu cha OS_xpc_shmem.
  1. Kuunda Kumbukumbu ya Pamoja katika Mchakato wa Mbali:
  • Panga kumbukumbu kwa ajili ya kitu cha OS_xpc_shmem katika mchakato wa mbali kwa wito wa mbali kwa malloc().
  • Nakili maudhui ya kitu cha ndani cha OS_xpc_shmem kwenye mchakato wa mbali. Hata hivyo, nakala hii ya awali itakuwa na majina yasiyo sahihi ya entry za kumbukumbu za Mach kwenye offset 0x18.
  1. Kurekebisha Entry ya Kumbukumbu ya Mach:
  • Tumia njia ya thread_set_special_port() kuingiza haki ya kutuma kwa entry ya kumbukumbu ya Mach kwenye kazi ya mbali.
  • Rekebisha uwanja wa entry ya kumbukumbu ya Mach kwenye offset 0x18 kwa kuandika upya kwa jina la entry ya kumbukumbu ya mbali.
  1. Kumaliza Mipangilio ya Kumbukumbu ya Pamoja:
  • Thibitisha kitu cha mbali cha OS_xpc_shmem.
  • Kuanzisha ramani ya kumbukumbu ya pamoja kwa wito wa mbali kwa xpc_shmem_remote().

Kwa kufuata hatua hizi, kumbukumbu ya pamoja kati ya kazi za ndani na za mbali itakuwa imewekwa kwa ufanisi, ikiruhusu uhamasishaji wa data kwa urahisi na utekelezaji wa kazi zinazohitaji hoja nyingi.

Nambari za Ziada

Kwa usambazaji wa kumbukumbu na uundaji wa kitu cha kumbukumbu ya pamoja:

c
mach_vm_allocate();
xpc_shmem_create();

Ili kuunda na kurekebisha kitu cha kumbukumbu kilichoshirikiwa katika mchakato wa mbali:

c
malloc(); // for allocating memory remotely
thread_set_special_port(); // for inserting send right

Kumbuka kushughulikia maelezo ya Mach ports na majina ya kuingia kwenye kumbukumbu kwa usahihi ili kuhakikisha kuwa usanidi wa kumbukumbu ya pamoja unafanya kazi ipasavyo.

5. Kufikia Udhibiti Kamili

Baada ya kufanikiwa kuanzisha kumbukumbu ya pamoja na kupata uwezo wa kutekeleza bila kikomo, kwa kweli tumepata udhibiti kamili juu ya mchakato wa lengo. Kazi muhimu zinazowezesha udhibiti huu ni:

  1. Operesheni za Kumbukumbu za Kijumla:
  • Fanya usomaji wa kumbukumbu wa kijumla kwa kuita memcpy() ili kunakili data kutoka kwenye eneo la pamoja.
  • Tekeleza uandishi wa kumbukumbu wa kijumla kwa kutumia memcpy() kuhamasisha data kwenye eneo la pamoja.
  1. Kushughulikia Kuitwa kwa Kazi zenye Hoja Nyingi:
  • Kwa kazi zinazohitaji zaidi ya hoja 8, panga hoja za ziada kwenye stack kwa kufuata kanuni ya kuita.
  1. Uhamisho wa Mach Port:
  • Hamisha Mach ports kati ya kazi kupitia ujumbe wa Mach kupitia bandari zilizowekwa awali.
  1. Uhamisho wa File Descriptor:
  • Hamisha file descriptors kati ya michakato kwa kutumia fileports, mbinu iliyosisitizwa na Ian Beer katika triple_fetch.

Udhibiti huu wa kina umejumuishwa ndani ya maktaba ya threadexec, ikitoa utekelezaji wa kina na API rafiki kwa mtumiaji kwa mwingiliano na mchakato wa mwathirika.

Maelezo Muhimu:

  • Hakikisha matumizi sahihi ya memcpy() kwa operesheni za kusoma/kandika kumbukumbu ili kudumisha utulivu wa mfumo na uadilifu wa data.
  • Unapohamisha Mach ports au file descriptors, fuata itifaki sahihi na shughuikia rasilimali kwa uwajibikaji ili kuzuia leaks au ufikiaji usio na makusudi.

Kwa kufuata miongozo hii na kutumia maktaba ya threadexec, mtu anaweza kudhibiti kwa ufanisi na kuingiliana na michakato kwa kiwango kidogo, akipata udhibiti kamili juu ya mchakato wa lengo.

Marejeo

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks