macOS Dyld Process
Osnovne informacije
Pravi ulaz binarnog Mach-o fajla je dinamički linkovan, definisan u LC_LOAD_DYLINKER
, obično je /usr/lib/dyld
.
Ovaj linker će morati da locira sve izvršne biblioteke, mapira ih u memoriju i poveže sve ne-lenje biblioteke. Tek nakon ovog procesa, izvršiće se ulazna tačka binarnog fajla.
Naravno, dyld
nema nikakve zavisnosti (koristi sistemske pozive i delove libSystem-a).
Ako ovaj linker sadrži bilo kakvu ranjivost, budući da se izvršava pre izvršavanja bilo kog binarnog fajla (čak i visoko privilegovanih), bilo bi moguće eskalirati privilegije.
Tok
Dyld će biti učitan preko dyldboostrap::start
, koji će takođe učitati stvari poput stack canary-ja. To je zato što će ova funkcija primiti u svom apple
argumentu ovu i druge osetljive vrednosti.
dyls::_main()
je ulazna tačka dyld-a i njegov prvi zadatak je da pokrene configureProcessRestrictions()
, što obično ograničava DYLD_*
okružne promenljive objašnjene u:
Zatim mapira dyld deljeni keš koji unapred povezuje sve važne sistem biblioteke, a zatim mapira biblioteke od kojih binarni fajl zavisi i nastavlja rekurzivno dok se ne učitaju sve potrebne biblioteke. Stoga:
počinje sa učitavanjem ubačenih biblioteka sa
DYLD_INSERT_LIBRARIES
(ako je dozvoljeno)Zatim deljeni keširani
Zatim uvežene
Zatim nastavlja rekurzivno uvoziti biblioteke
Kada su sve učitane, pokreću se inicijalizatori ovih biblioteka. Oni su kodirani koristeći __attribute__((constructor))
definisane u LC_ROUTINES[_64]
(sada zastarelo) ili preko pokazivača u odeljku označenom sa S_MOD_INIT_FUNC_POINTERS
(obično: __DATA.__MOD_INIT_FUNC
).
Terminatori su kodirani sa __attribute__((destructor))
i nalaze se u odeljku označenom sa S_MOD_TERM_FUNC_POINTERS
(__DATA.__mod_term_func
).
Stubovi
Svi binarni fajlovi na macOS-u su dinamički linkovani. Stoga, sadrže neke odeljke stubova koji pomažu binarnom fajlu da skoči na odgovarajući kod u različitim mašinama i kontekstima. Dyld je taj koji mora da reši ove adrese kada se binarni fajl izvrši (barem one koje nisu lenje).
Neki odeljci stubova u binarnom fajlu:
__TEXT.__[auth_]stubs
: Pokazivači iz__DATA
odeljaka__TEXT.__stub_helper
: Mali kod koji poziva dinamičko linkovanje sa informacijama o funkciji koju treba pozvati__DATA.__[auth_]got
: Globalna tabela offseta (adrese uvezenih funkcija, kada se reše, (vezuju se tokom vremena učitavanja jer je označena zastavicomS_NON_LAZY_SYMBOL_POINTERS
)__DATA.__nl_symbol_ptr
: Pokazivači na ne-lenje simbole (vezuju se tokom vremena učitavanja jer je označena zastavicomS_NON_LAZY_SYMBOL_POINTERS
)__DATA.__la_symbol_ptr
: Pokazivači na lenje simbole (vezuju se prilikom prvog pristupa)
Imajte na umu da pokazivači sa prefiksom "auth_" koriste jedan ključ za enkripciju u procesu kako bi ih zaštitili (PAC). Takođe, moguće je koristiti arm64 instrukciju BLRA[A/B]
da proveri pokazivač pre nego što ga prati. I RETA[A/B] se može koristiti umesto adrese RET.
Zapravo, kod u __TEXT.__auth_stubs
će koristiti braa
umesto bl
da pozove traženu funkciju kako bi autentifikovao pokazivač.
Takođe imajte na umu da trenutne verzije dyld-a učitavaju sve kao ne-lenje.
Pronalaženje lenjih simbola
Interesantan deo disasemblera:
Moguće je videti da skok ka pozivu printf ide ka __TEXT.__stubs
:
Prilikom rastavljanja __stubs
odeljka:
Možete videti da skočimo na adresu GOT-a, koja u ovom slučaju nije lenja i sadržaće adresu funkcije printf.
U drugim situacijama umesto direktnog skakanja na GOT, može se skočiti na __DATA.__la_symbol_ptr
koji će učitati vrednost koja predstavlja funkciju koju pokušava da učita, zatim skočiti na __TEXT.__stub_helper
koji skače na __DATA.__nl_symbol_ptr
koji sadrži adresu dyld_stub_binder
koji kao parametre uzima broj funkcije i adresu.
Ova poslednja funkcija, nakon što pronađe adresu tražene funkcije, upisuje je na odgovarajuće mesto u __TEXT.__stub_helper
kako bi izbegla pretragu u budućnosti.
Međutim, primetite da trenutne verzije dyld-a sve učitavaju kao ne-lenje.
Dyld opcode
Konačno, dyld_stub_binder
mora pronaći naznačenu funkciju i upisati je na odgovarajuću adresu kako je ne bi ponovo tražio. Da bi to postigao, koristi opcode-ove (konačni automat) unutar dyld-a.
apple[] argument vektor
U macOS-u, glavna funkcija zapravo prima 4 argumenta umesto 3. Četvrti se zove apple i svaki unos je u obliku ključ=vrednost
. Na primer:
macOS Dyld Process
macOS Biblioteka ubrizgavanje
Biblioteka ubrizgavanje je tehnika koja omogućava napadaču da ubaci zlonamernu biblioteku u proces kako bi dobio kontrolu nad izvršavanjem. Ova tehnika se često koristi za postizanje privilegija eskalacije ili za skrivanje zlonamernih aktivnosti. Dyld (dinamički linker) je odgovoran za učitavanje i povezivanje dinamičkih biblioteka u macOS operativnom sistemu. Napadač može iskoristiti ranjivosti u dyld procesu kako bi ubacio zlonamernu biblioteku i preuzeo kontrolu nad sistemom.
Kada ove vrednosti stignu do glavne funkcije, osetljive informacije već su uklonjene iz njih ili bi došlo do curenja podataka.
Moguće je videti sve ove interesantne vrednosti prilikom debagovanja pre ulaska u glavnu funkciju sa:
dyld_all_image_infos
Ovo je struktura izvezena od strane dyld-a sa informacijama o stanju dyld-a koje se može pronaći u izvornom kodu sa informacijama poput verzije, pokazivača na niz dyld_image_info, na dyld_image_notifier, da li je proces odvojen od deljenog keša, da li je inicijalizator libSystem-a pozvan, pokazivač na Mach zaglavlje dyld-a, pokazivač na verziju dyld-a...
dyld env promenljive
debug dyld
Interesantne env promenljive koje pomažu u razumevanju šta dyld radi:
DYLD_PRINT_LIBRARIES
Proverite svaku biblioteku koja je učitana:
DYLD_PRINT_SEGMENTS
Proverite kako je svaka biblioteka učitana:
DYLD_PRINT_INITIALIZERS
Štampajte kada se pokreće svaki inicijalizator biblioteke:
Ostali
DYLD_BIND_AT_LAUNCH
: Lenje veze se rešavaju sa ne-lenjim vezamaDYLD_DISABLE_PREFETCH
: Onemogućava preuzimanje __DATA i __LINKEDIT sadržajaDYLD_FORCE_FLAT_NAMESPACE
: Veze na jednom nivouDYLD_[FRAMEWORK/LIBRARY]_PATH | DYLD_FALLBACK_[FRAMEWORK/LIBRARY]_PATH | DYLD_VERSIONED_[FRAMEWORK/LIBRARY]_PATH
: Putanje za rešavanjeDYLD_INSERT_LIBRARIES
: Učitava određenu bibliotekuDYLD_PRINT_TO_FILE
: Piše dyld debug u fajlDYLD_PRINT_APIS
: Ispisuje pozive libdyld API-jaDYLD_PRINT_APIS_APP
: Ispisuje pozive libdyld API-ja napravljene od strane glavne aplikacijeDYLD_PRINT_BINDINGS
: Ispisuje simbole kada su vezaniDYLD_WEAK_BINDINGS
: Ispisuje samo slabe simbole kada su vezaniDYLD_PRINT_CODE_SIGNATURES
: Ispisuje operacije registracije potpisa kodaDYLD_PRINT_DOFS
: Ispisuje sekcije formata objekta D-Trace-a koje su učitaneDYLD_PRINT_ENV
: Ispisuje okruženje viđeno od strane dyld-aDYLD_PRINT_INTERPOSTING
: Ispisuje operacije interpostovanjaDYLD_PRINT_LIBRARIES
: Ispisuje učitane bibliotekeDYLD_PRINT_OPTS
: Ispisuje opcije učitavanjaDYLD_REBASING
: Ispisuje operacije relokacije simbolaDYLD_RPATHS
: Ispisuje proširenja @rpathDYLD_PRINT_SEGMENTS
: Ispisuje mapiranja Mach-O segmenataDYLD_PRINT_STATISTICS
: Ispisuje statistiku vremenaDYLD_PRINT_STATISTICS_DETAILS
: Ispisuje detaljnu statistiku vremenaDYLD_PRINT_WARNINGS
: Ispisuje upozorenjaDYLD_SHARED_CACHE_DIR
: Putanja za korišćenje keša deljenih bibliotekaDYLD_SHARED_REGION
: "use", "private", "avoid"DYLD_USE_CLOSURES
: Omogućava zatvaranja
Moguće je pronaći više sa nečim poput:
Ili preuzimanje dyld projekta sa https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz i pokretanje unutar foldera:
Reference
Last updated