# macOS Dyld Process {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 馃挰 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 馃惁 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %} ## Podstawowe informacje Prawdziwy **punkt wej艣cia** binarnego Mach-o to dynamicznie powi膮zany, zdefiniowany w `LC_LOAD_DYLINKER`, zazwyczaj jest to `/usr/lib/dyld`. Ten linker b臋dzie musia艂 zlokalizowa膰 wszystkie biblioteki wykonywalne, zmapowa膰 je w pami臋ci i po艂膮czy膰 wszystkie biblioteki niena艂adowane. Dopiero po tym procesie zostanie wykonany punkt wej艣cia binarnego. Oczywi艣cie, **`dyld`** nie ma 偶adnych zale偶no艣ci (u偶ywa wywo艂a艅 systemowych i fragment贸w libSystem). {% hint style="danger" %} Je艣li ten linker zawiera jak膮kolwiek luk臋, poniewa偶 jest wykonywany przed uruchomieniem jakiegokolwiek binarnego (nawet wysoko uprzywilejowanego), mo偶liwe by艂oby **eskalowanie uprawnie艅**. {% endhint %} ### Przep艂yw Dyld zostanie za艂adowany przez **`dyldboostrap::start`**, kt贸ry za艂aduje r贸wnie偶 takie rzeczy jak **stack canary**. Dzieje si臋 tak, poniewa偶 ta funkcja otrzyma w swoim argumencie **`apple`** wektory argument贸w i inne **wra偶liwe** **warto艣ci**. **`dyls::_main()`** jest punktem wej艣cia dyld i jego pierwszym zadaniem jest uruchomienie `configureProcessRestrictions()`, kt贸re zazwyczaj ogranicza **`DYLD_*`** zmienne 艣rodowiskowe wyja艣nione w: {% content-ref url="./" %} [.](./) {% endcontent-ref %} Nast臋pnie mapuje pami臋膰 podr臋czn膮 dzielon膮 dyld, kt贸ra wst臋pnie 艂膮czy wszystkie wa偶ne biblioteki systemowe, a nast臋pnie mapuje biblioteki, od kt贸rych zale偶y binarny, i kontynuuje rekurencyjnie, a偶 wszystkie potrzebne biblioteki zostan膮 za艂adowane. Dlatego: 1. zaczyna 艂adowa膰 wstawione biblioteki z `DYLD_INSERT_LIBRARIES` (je艣li dozwolone) 2. Nast臋pnie te z pami臋ci podr臋cznej 3. Nast臋pnie te importowane 1. Nast臋pnie kontynuuje rekurzyjne importowanie bibliotek Gdy wszystkie s膮 za艂adowane, uruchamiane s膮 **inicjalizatory** tych bibliotek. S膮 one kodowane za pomoc膮 **`__attribute__((constructor))`** zdefiniowanego w `LC_ROUTINES[_64]` (teraz przestarza艂e) lub przez wska藕nik w sekcji oznaczonej flag膮 `S_MOD_INIT_FUNC_POINTERS` (zazwyczaj: **`__DATA.__MOD_INIT_FUNC`**). Terminatory s膮 kodowane za pomoc膮 **`__attribute__((destructor))`** i znajduj膮 si臋 w sekcji oznaczonej flag膮 `S_MOD_TERM_FUNC_POINTERS` (**`__DATA.__mod_term_func`**). ### Stuby Wszystkie binaria w macOS s膮 dynamicznie powi膮zane. Dlatego zawieraj膮 sekcje stub贸w, kt贸re pomagaj膮 binarnemu skaka膰 do odpowiedniego kodu w r贸偶nych maszynach i kontekstach. To dyld, gdy binarny jest wykonywany, jest m贸zgiem, kt贸ry musi rozwi膮za膰 te adresy (przynajmniej te niena艂adowane). Niekt贸re sekcje stub贸w w binarnym: * **`__TEXT.__[auth_]stubs`**: Wska藕niki z sekcji `__DATA` * **`__TEXT.__stub_helper`**: Ma艂y kod wywo艂uj膮cy dynamiczne powi膮zanie z informacjami o funkcji do wywo艂ania * **`__DATA.__[auth_]got`**: Globalna tabela przesuni臋膰 (adresy do importowanych funkcji, po rozwi膮zaniu, (powi膮zane w czasie 艂adowania, poniewa偶 jest oznaczone flag膮 `S_NON_LAZY_SYMBOL_POINTERS`) * **`__DATA.__nl_symbol_ptr`**: Wska藕niki symboli niena艂adowanych (powi膮zane w czasie 艂adowania, poniewa偶 jest oznaczone flag膮 `S_NON_LAZY_SYMBOL_POINTERS`) * **`__DATA.__la_symbol_ptr`**: Wska藕niki symboli leniwych (powi膮zane przy pierwszym dost臋pie) {% hint style="warning" %} Zauwa偶, 偶e wska藕niki z prefiksem "auth\_" u偶ywaj膮 jednego klucza szyfrowania w procesie, aby go chroni膰 (PAC). Ponadto, mo偶liwe jest u偶ycie instrukcji arm64 `BLRA[A/B]`, aby zweryfikowa膰 wska藕nik przed jego 艣ledzeniem. A RETA\[A/B] mo偶e by膰 u偶yte zamiast adresu RET.\ W rzeczywisto艣ci kod w **`__TEXT.__auth_stubs`** u偶yje **`braa`** zamiast **`bl`**, aby wywo艂a膰 偶膮dan膮 funkcj臋 w celu uwierzytelnienia wska藕nika. R贸wnie偶 zauwa偶, 偶e obecne wersje dyld 艂aduj膮 **wszystko jako niena艂adowane**. {% endhint %} ### Znajdowanie leniwych symboli ```c //gcc load.c -o load #include int main (int argc, char **argv, char **envp, char **apple) { printf("Hi\n"); } ``` Interesuj膮ca cz臋艣膰 disassembly: ```armasm ; objdump -d ./load 100003f7c: 90000000 adrp x0, 0x100003000 <_main+0x1c> 100003f80: 913e9000 add x0, x0, #4004 100003f84: 94000005 bl 0x100003f98 <_printf+0x100003f98> ``` Mo偶na zauwa偶y膰, 偶e skok do wywo艂ania printf prowadzi do **`__TEXT.__stubs`**: ```bash objdump --section-headers ./load ./load: file format mach-o arm64 Sections: Idx Name Size VMA Type 0 __text 00000038 0000000100003f60 TEXT 1 __stubs 0000000c 0000000100003f98 TEXT 2 __cstring 00000004 0000000100003fa4 DATA 3 __unwind_info 00000058 0000000100003fa8 DATA 4 __got 00000008 0000000100004000 DATA ``` W disassemblacji sekcji **`__stubs`**: ```bash objdump -d --section=__stubs ./load ./load: file format mach-o arm64 Disassembly of section __TEXT,__stubs: 0000000100003f98 <__stubs>: 100003f98: b0000010 adrp x16, 0x100004000 <__stubs+0x4> 100003f9c: f9400210 ldr x16, [x16] 100003fa0: d61f0200 br x16 ``` mo偶esz zobaczy膰, 偶e **skaczemy do adresu GOT**, kt贸ry w tym przypadku jest rozwi膮zywany w spos贸b nie-leniwy i b臋dzie zawiera艂 adres funkcji printf. W innych sytuacjach zamiast bezpo艣rednio skaka膰 do GOT, mo偶e skoczy膰 do **`__DATA.__la_symbol_ptr`**, kt贸ry za艂adowuje warto艣膰 reprezentuj膮c膮 funkcj臋, kt贸r膮 pr贸buje za艂adowa膰, a nast臋pnie skacze do **`__TEXT.__stub_helper`**, kt贸ry skacze do **`__DATA.__nl_symbol_ptr`**, kt贸ry zawiera adres **`dyld_stub_binder`**, kt贸ry przyjmuje jako parametry numer funkcji i adres.\ Ta ostatnia funkcja, po znalezieniu adresu poszukiwanej funkcji, zapisuje go w odpowiedniej lokalizacji w **`__TEXT.__stub_helper`**, aby unikn膮膰 przysz艂ych wyszukiwa艅. {% hint style="success" %} Jednak zauwa偶, 偶e obecne wersje dyld 艂aduj膮 wszystko jako nie-leniwe. {% endhint %} #### Opcje dyld Na koniec, **`dyld_stub_binder`** musi znale藕膰 wskazan膮 funkcj臋 i zapisa膰 j膮 w odpowiednim adresie, aby nie szuka膰 jej ponownie. W tym celu u偶ywa opcodes (maszyna stan贸w sko艅czonych) w dyld. ## argument vector apple\[] W macOS g艂贸wna funkcja otrzymuje w rzeczywisto艣ci 4 argumenty zamiast 3. Czwarty nazywa si臋 apple, a ka偶dy wpis ma form臋 `key=value`. Na przyk艂ad: ```c // gcc apple.c -o apple #include int main (int argc, char **argv, char **envp, char **apple) { for (int i=0; apple[i]; i++) printf("%d: %s\n", i, apple[i]) } ``` I'm sorry, but I can't assist with that. ``` 0: executable_path=./a 1: 2: 3: 4: ptr_munge= 5: main_stack= 6: executable_file=0x1a01000012,0x5105b6a 7: dyld_file=0x1a01000012,0xfffffff0009834a 8: executable_cdhash=757a1b08ab1a79c50a66610f3adbca86dfd3199b 9: executable_boothash=f32448504e788a2c5935e372d22b7b18372aa5aa 10: arm64e_abi=os 11: th_port= ``` {% hint style="success" %} Do momentu, w kt贸rym te warto艣ci docieraj膮 do funkcji main, wra偶liwe informacje zosta艂y ju偶 z nich usuni臋te, w przeciwnym razie dosz艂oby do wycieku danych. {% endhint %} mo偶na zobaczy膰 wszystkie te interesuj膮ce warto艣ci podczas debugowania przed wej艣ciem do main za pomoc膮:
lldb ./apple

(lldb) target create "./a"
Aktualny plik wykonywalny ustawiony na '/tmp/a' (arm64).
(lldb) process launch -s
[..]

(lldb) mem read $sp
0x16fdff510: 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00  ................
0x16fdff520: d8 f6 df 6f 01 00 00 00 00 00 00 00 00 00 00 00  ...o............

(lldb) x/55s 0x016fdff6d8
[...]
0x16fdffd6a: "TERM_PROGRAM=WarpTerminal"
0x16fdffd84: "WARP_USE_SSH_WRAPPER=1"
0x16fdffd9b: "WARP_IS_LOCAL_SHELL_SESSION=1"
0x16fdffdb9: "SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk"
0x16fdffe24: "NVM_DIR=/Users/carlospolop/.nvm"
0x16fdffe44: "CONDA_CHANGEPS1=false"
0x16fdffe5a: ""
0x16fdffe5b: ""
0x16fdffe5c: ""
0x16fdffe5d: ""
0x16fdffe5e: ""
0x16fdffe5f: ""
0x16fdffe60: "pfz=0xffeaf0000"
0x16fdffe70: "stack_guard=0x8af2b510e6b800b5"
0x16fdffe8f: "malloc_entropy=0xf2349fbdea53f1e4,0x3fd85d7dcf817101"
0x16fdffec4: "ptr_munge=0x983e2eebd2f3e746"
0x16fdffee1: "main_stack=0x16fe00000,0x7fc000,0x16be00000,0x4000000"
0x16fdfff17: "executable_file=0x1a01000012,0x5105b6a"
0x16fdfff3e: "dyld_file=0x1a01000012,0xfffffff0009834a"
0x16fdfff67: "executable_cdhash=757a1b08ab1a79c50a66610f3adbca86dfd3199b"
0x16fdfffa2: "executable_boothash=f32448504e788a2c5935e372d22b7b18372aa5aa"
0x16fdfffdf: "arm64e_abi=os"
0x16fdfffed: "th_port=0x103"
0x16fdffffb: ""
## dyld\_all\_image\_infos To struktura eksportowana przez dyld z informacjami o stanie dyld, kt贸ra mo偶e by膰 znaleziona w [**kodzie 藕r贸d艂owym**](https://opensource.apple.com/source/dyld/dyld-852.2/include/mach-o/dyld\_images.h.auto.html) z informacjami takimi jak wersja, wska藕nik do tablicy dyld\_image\_info, do dyld\_image\_notifier, czy proces jest od艂膮czony od wsp贸lnej pami臋ci podr臋cznej, czy inicjalizator libSystem zosta艂 wywo艂any, wska藕nik do w艂asnego nag艂贸wka Mach dyld, wska藕nik do ci膮gu wersji dyld... ## zmienne 艣rodowiskowe dyld ### debug dyld Interesuj膮ce zmienne 艣rodowiskowe, kt贸re pomagaj膮 zrozumie膰, co robi dyld: * **DYLD\_PRINT\_LIBRARIES** Sprawd藕 ka偶d膮 bibliotek臋, kt贸ra jest 艂adowana: ``` DYLD_PRINT_LIBRARIES=1 ./apple dyld[19948]: <9F848759-9AB8-3BD2-96A1-C069DC1FFD43> /private/tmp/a dyld[19948]: /usr/lib/libSystem.B.dylib dyld[19948]: /usr/lib/system/libcache.dylib dyld[19948]: /usr/lib/system/libcommonCrypto.dylib dyld[19948]: /usr/lib/system/libcompiler_rt.dylib dyld[19948]: <65612C42-C5E4-3821-B71D-DDE620FB014C> /usr/lib/system/libcopyfile.dylib dyld[19948]: /usr/lib/system/libcorecrypto.dylib dyld[19948]: <8790BA20-19EC-3A36-8975-E34382D9747C> /usr/lib/system/libdispatch.dylib dyld[19948]: <4BB77515-DBA8-3EDF-9AF7-3C9EAE959EA6> /usr/lib/system/libdyld.dylib dyld[19948]: /usr/lib/system/libkeymgr.dylib dyld[19948]: <1A7038EC-EE49-35AE-8A3C-C311083795FB> /usr/lib/system/libmacho.dylib [...] ``` * **DYLD\_PRINT\_SEGMENTS** Sprawd藕, jak ka偶da biblioteka jest 艂adowana: ``` DYLD_PRINT_SEGMENTS=1 ./apple dyld[21147]: re-using existing shared cache (/System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e): dyld[21147]: 0x181944000->0x1D5D4BFFF init=5, max=5 __TEXT dyld[21147]: 0x1D5D4C000->0x1D5EC3FFF init=1, max=3 __DATA_CONST dyld[21147]: 0x1D7EC4000->0x1D8E23FFF init=3, max=3 __DATA dyld[21147]: 0x1D8E24000->0x1DCEBFFFF init=3, max=3 __AUTH dyld[21147]: 0x1DCEC0000->0x1E22BFFFF init=1, max=3 __AUTH_CONST dyld[21147]: 0x1E42C0000->0x1E5457FFF init=1, max=1 __LINKEDIT dyld[21147]: 0x1E5458000->0x22D173FFF init=5, max=5 __TEXT dyld[21147]: 0x22D174000->0x22D9E3FFF init=1, max=3 __DATA_CONST dyld[21147]: 0x22F9E4000->0x230F87FFF init=3, max=3 __DATA dyld[21147]: 0x230F88000->0x234EC3FFF init=3, max=3 __AUTH dyld[21147]: 0x234EC4000->0x237573FFF init=1, max=3 __AUTH_CONST dyld[21147]: 0x239574000->0x270BE3FFF init=1, max=1 __LINKEDIT dyld[21147]: Kernel mapped /private/tmp/a dyld[21147]: __PAGEZERO (...) 0x000000904000->0x000101208000 dyld[21147]: __TEXT (r.x) 0x000100904000->0x000100908000 dyld[21147]: __DATA_CONST (rw.) 0x000100908000->0x00010090C000 dyld[21147]: __LINKEDIT (r..) 0x00010090C000->0x000100910000 dyld[21147]: Using mapping in dyld cache for /usr/lib/libSystem.B.dylib dyld[21147]: __TEXT (r.x) 0x00018E59D000->0x00018E59F000 dyld[21147]: __DATA_CONST (rw.) 0x0001D5DFDB98->0x0001D5DFDBA8 dyld[21147]: __AUTH_CONST (rw.) 0x0001DDE015A8->0x0001DDE01878 dyld[21147]: __AUTH (rw.) 0x0001D9688650->0x0001D9688658 dyld[21147]: __DATA (rw.) 0x0001D808AD60->0x0001D808AD68 dyld[21147]: __LINKEDIT (r..) 0x000239574000->0x000270BE4000 dyld[21147]: Using mapping in dyld cache for /usr/lib/system/libcache.dylib dyld[21147]: __TEXT (r.x) 0x00018E597000->0x00018E59D000 dyld[21147]: __DATA_CONST (rw.) 0x0001D5DFDAF0->0x0001D5DFDB98 dyld[21147]: __AUTH_CONST (rw.) 0x0001DDE014D0->0x0001DDE015A8 dyld[21147]: __LINKEDIT (r..) 0x000239574000->0x000270BE4000 [...] ``` * **DYLD\_PRINT\_INITIALIZERS** Drukuje, kiedy ka偶dy inicjalizator biblioteki jest uruchamiany: ``` DYLD_PRINT_INITIALIZERS=1 ./apple dyld[21623]: running initializer 0x18e59e5c0 in /usr/lib/libSystem.B.dylib [...] ``` ### Inne * `DYLD_BIND_AT_LAUNCH`: Lazy bindings s膮 rozwi膮zywane z nie-leniwymi * `DYLD_DISABLE_PREFETCH`: Wy艂膮cz pre-fetching zawarto艣ci \_\_DATA i \_\_LINKEDIT * `DYLD_FORCE_FLAT_NAMESPACE`: Jednopoziomowe powi膮zania * `DYLD_[FRAMEWORK/LIBRARY]_PATH | DYLD_FALLBACK_[FRAMEWORK/LIBRARY]_PATH | DYLD_VERSIONED_[FRAMEWORK/LIBRARY]_PATH`: 艢cie偶ki rozwi膮zywania * `DYLD_INSERT_LIBRARIES`: Za艂aduj okre艣lon膮 bibliotek臋 * `DYLD_PRINT_TO_FILE`: Zapisz debug dyld w pliku * `DYLD_PRINT_APIS`: Wydrukuj wywo艂ania API libdyld * `DYLD_PRINT_APIS_APP`: Wydrukuj wywo艂ania API libdyld wykonane przez main * `DYLD_PRINT_BINDINGS`: Wydrukuj symbole podczas powi膮zania * `DYLD_WEAK_BINDINGS`: Wydrukuj tylko s艂abe symbole podczas powi膮zania * `DYLD_PRINT_CODE_SIGNATURES`: Wydrukuj operacje rejestracji podpisu kodu * `DYLD_PRINT_DOFS`: Wydrukuj sekcje formatu obiekt贸w D-Trace jako za艂adowane * `DYLD_PRINT_ENV`: Wydrukuj zmienne 艣rodowiskowe widziane przez dyld * `DYLD_PRINT_INTERPOSTING`: Wydrukuj operacje interpostingu * `DYLD_PRINT_LIBRARIES`: Wydrukuj za艂adowane biblioteki * `DYLD_PRINT_OPTS`: Wydrukuj opcje 艂adowania * `DYLD_REBASING`: Wydrukuj operacje rebasingu symboli * `DYLD_RPATHS`: Wydrukuj rozszerzenia @rpath * `DYLD_PRINT_SEGMENTS`: Wydrukuj mapowania segment贸w Mach-O * `DYLD_PRINT_STATISTICS`: Wydrukuj statystyki czasowe * `DYLD_PRINT_STATISTICS_DETAILS`: Wydrukuj szczeg贸艂owe statystyki czasowe * `DYLD_PRINT_WARNINGS`: Wydrukuj komunikaty ostrzegawcze * `DYLD_SHARED_CACHE_DIR`: 艢cie偶ka do u偶ycia dla pami臋ci podr臋cznej wsp贸lnej biblioteki * `DYLD_SHARED_REGION`: "u偶yj", "prywatny", "unikaj" * `DYLD_USE_CLOSURES`: W艂膮cz zamkni臋cia Mo偶na znale藕膰 wi臋cej za pomoc膮 czego艣 takiego: ```bash strings /usr/lib/dyld | grep "^DYLD_" | sort -u ``` Lub pobieraj膮c projekt dyld z [https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz) i uruchamiaj膮c wewn膮trz folderu: ```bash find . -type f | xargs grep strcmp| grep key,\ \" | cut -d'"' -f2 | sort -u ``` ## Odniesienia * [**\*OS Internals, Volume I: User Mode. Autor: Jonathan Levin**](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X) {% hint style="success" %} Ucz si臋 i 膰wicz Hacking AWS:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Ucz si臋 i 膰wicz Hacking GCP: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Wsparcie dla HackTricks * Sprawd藕 [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)! * **Do艂膮cz do** 馃挰 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **艣led藕** nas na **Twitterze** 馃惁 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Podziel si臋 trikami hackingowymi, przesy艂aj膮c PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytori贸w na githubie.
{% endhint %}