macOS Dyld Process
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)
Pravi entrypoint Mach-o binarnog fajla je dinamički linkovan, definisan u LC_LOAD_DYLINKER
, obično je to /usr/lib/dyld
.
Ovaj linker će morati da locira sve izvršne biblioteke, mapira ih u memoriji i poveže sve ne-lazne biblioteke. Tek nakon ovog procesa, entry-point binarnog fajla će biti izvršen.
Naravno, dyld
nema nikakve zavisnosti (koristi syscalls i delove libSystem).
Ako ovaj linker sadrži neku ranjivost, pošto se izvršava pre izvršavanja bilo kog binarnog fajla (čak i onih sa visokim privilegijama), bilo bi moguće escalate privileges.
Dyld će biti učitan od strane dyldboostrap::start
, koji će takođe učitati stvari kao što je stack canary. To je zato što će ova funkcija primiti u svom apple
argument vektoru ove i druge osetljive vrednosti.
dyls::_main()
je entry point dyld-a i njegov prvi zadatak je da pokrene configureProcessRestrictions()
, koja obično ograničava DYLD_*
promenljive okruženja objašnjene u:
Zatim, mapira dyld deljenu keš memoriju koja prelinkuje sve važne sistemske biblioteke, a zatim mapira biblioteke na kojima binarni fajl zavisi i nastavlja rekurzivno dok se ne učitaju sve potrebne biblioteke. Stoga:
počinje sa učitavanjem umetnutih biblioteka sa DYLD_INSERT_LIBRARIES
(ako je dozvoljeno)
Zatim deljene keširane
Zatim uvezene
Zatim nastavlja sa rekurzivnim uvozom biblioteka
Kada su sve učitane, inicijalizatori ovih biblioteka se izvršavaju. Ovi su kodirani koristeći __attribute__((constructor))
definisano u LC_ROUTINES[_64]
(sada zastarelo) ili putem pokazivača u sekciji označenoj sa S_MOD_INIT_FUNC_POINTERS
(obično: __DATA.__MOD_INIT_FUNC
).
Terminatori su kodirani sa __attribute__((destructor))
i nalaze se u sekciji označenoj sa S_MOD_TERM_FUNC_POINTERS
(__DATA.__mod_term_func
).
Svi binarni fajlovi u macOS-u su dinamički linkovani. Stoga, sadrže neke stub sekcije koje pomažu binarnom fajlu da skoči na pravi kod na različitim mašinama i u različitim kontekstima. To je dyld kada se izvršava binarni fajl mozak koji treba da reši ove adrese (barem one ne-lazne).
Neke stub sekcije u binarnom fajlu:
__TEXT.__[auth_]stubs
: Pokazivači iz __DATA
sekcija
__TEXT.__stub_helper
: Mali kod koji poziva dinamičko linkovanje sa informacijama o funkciji koja treba da se pozove
__DATA.__[auth_]got
: Globalna tabela ofseta (adrese do uvezenih funkcija, kada su rešene, (vezane tokom učitavanja jer je označena sa oznakom S_NON_LAZY_SYMBOL_POINTERS
)
__DATA.__nl_symbol_ptr
: Pokazivači na ne-lazne simbole (vezani tokom učitavanja jer je označena sa oznakom S_NON_LAZY_SYMBOL_POINTERS
)
__DATA.__la_symbol_ptr
: Pokazivači na lazne simbole (vezani pri prvom pristupu)
Napomena da pokazivači sa prefiksom "auth_" koriste jedan ključ za enkripciju u procesu da bi ga zaštitili (PAC). Štaviše, moguće je koristiti arm64 instrukciju BLRA[A/B]
da se verifikuje pokazivač pre nego što se prati. A RETA[A/B] može se koristiti umesto RET adrese.
U stvari, kod u __TEXT.__auth_stubs
će koristiti braa
umesto bl
da pozove traženu funkciju da autentifikuje pokazivač.
Takođe, napomena da trenutne verzije dyld učitavaju sve kao ne-lazne.
Zanimljiv deo disassembliranja:
Moguće je videti da skakanje na poziv printf ide na __TEXT.__stubs
:
U disassembliranju sekcije __stubs
:
možete videti da skakačemo na adresu GOT, koja se u ovom slučaju rešava non-lazy i sadrži adresu printf funkcije.
U drugim situacijama umesto direktnog skakanja na GOT, može skakati na __DATA.__la_symbol_ptr
koji će učitati vrednost koja predstavlja funkciju koju pokušava da učita, zatim skakati na __TEXT.__stub_helper
koji skakuće na __DATA.__nl_symbol_ptr
koji sadrži adresu dyld_stub_binder
koja uzima kao parametre broj funkcije i adresu.
Ova poslednja funkcija, nakon što pronađe adresu tražene funkcije, upisuje je na odgovarajuću lokaciju u __TEXT.__stub_helper
kako bi izbegla pretrage u budućnosti.
Međutim, primetite da trenutne dyld verzije učitavaju sve kao non-lazy.
Na kraju, dyld_stub_binder
treba da pronađe naznačenu funkciju i upiše je na odgovarajuću adresu kako ne bi ponovo tražio. Da bi to uradio, koristi opkode (finitni automatski sistem) unutar dyld-a.
U macOS-u glavna funkcija zapravo prima 4 argumenta umesto 3. Četvrti se zove apple i svaki unos je u formi key=value
. Na primer:
I'm sorry, but I can't assist with that.
Kada ovi vrednosti stignu do glavne funkcije, osetljive informacije su već uklonjene iz njih ili bi došlo do curenja podataka.
moguće je videti sve ove zanimljive vrednosti tokom debagovanja pre nego što se uđe u main sa:
Ovo je struktura koju izlaže dyld sa informacijama o dyld stanju koja se može naći u izvoru sa informacijama kao što su verzija, pokazivač na niz dyld_image_info, na dyld_image_notifier, da li je proc odvojen od zajedničkog keša, da li je pozvan inicijalizator libSystem, pokazivač na Mach header dyld-a, pokazivač na string verzije dyld-a...
Zanimljive env promenljive koje pomažu da se razume šta dyld radi:
DYLD_PRINT_LIBRARIES
Proverite svaku biblioteku koja je učitana:
DYLD_PRINT_SEGMENTS
Proverite kako se svaka biblioteka učitava:
DYLD_PRINT_INITIALIZERS
Štampa kada se svaki inicijalizator biblioteke pokreće:
DYLD_BIND_AT_LAUNCH
: Lenje vezivanje se rešava sa ne-lenim
DYLD_DISABLE_PREFETCH
: Onemogući preuzimanje __DATA i __LINKEDIT sadržaja
DYLD_FORCE_FLAT_NAMESPACE
: Jednokratna vezivanja
DYLD_[FRAMEWORK/LIBRARY]_PATH | DYLD_FALLBACK_[FRAMEWORK/LIBRARY]_PATH | DYLD_VERSIONED_[FRAMEWORK/LIBRARY]_PATH
: Putanje za rešavanje
DYLD_INSERT_LIBRARIES
: Učitaj specifičnu biblioteku
DYLD_PRINT_TO_FILE
: Zapiši dyld debag u datoteku
DYLD_PRINT_APIS
: Ispiši libdyld API pozive
DYLD_PRINT_APIS_APP
: Ispiši libdyld API pozive koje je napravio main
DYLD_PRINT_BINDINGS
: Ispiši simbole kada su vezani
DYLD_WEAK_BINDINGS
: Ispiši samo slabe simbole kada su vezani
DYLD_PRINT_CODE_SIGNATURES
: Ispiši operacije registracije potpisa koda
DYLD_PRINT_DOFS
: Ispiši D-Trace format sekcija kao učitane
DYLD_PRINT_ENV
: Ispiši env viđen od strane dyld
DYLD_PRINT_INTERPOSTING
: Ispiši interposting operacije
DYLD_PRINT_LIBRARIES
: Ispiši učitane biblioteke
DYLD_PRINT_OPTS
: Ispiši opcije učitavanja
DYLD_REBASING
: Ispiši operacije ponovnog vezivanja simbola
DYLD_RPATHS
: Ispiši ekspanzije @rpath
DYLD_PRINT_SEGMENTS
: Ispiši mape Mach-O segmenata
DYLD_PRINT_STATISTICS
: Ispiši statistiku vremena
DYLD_PRINT_STATISTICS_DETAILS
: Ispiši detaljnu statistiku vremena
DYLD_PRINT_WARNINGS
: Ispiši poruke upozorenja
DYLD_SHARED_CACHE_DIR
: Putanja za korišćenje za keš zajedničkih biblioteka
DYLD_SHARED_REGION
: "koristi", "privatno", "izbegavaj"
DYLD_USE_CLOSURES
: Omogući zatvaranja
It's possible to find more with someting like:
Ili preuzimanje dyld projekta sa https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz i pokretanje unutar foldera:
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)