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)
Mach-o बाइनरी का असली entrypoint डायनामिक लिंक है, जो LC_LOAD_DYLINKER
में परिभाषित होता है, जो आमतौर पर /usr/lib/dyld
होता है।
इस लिंक को सभी निष्पादन योग्य पुस्तकालयों को खोजने, उन्हें मेमोरी में मैप करने और सभी गैर-लाज़ी पुस्तकालयों को लिंक करने की आवश्यकता होगी। केवल इस प्रक्रिया के बाद, बाइनरी का एंट्री-पॉइंट निष्पादित होगा।
बेशक, dyld
के पास कोई निर्भरताएँ नहीं हैं (यह syscalls और libSystem अंशों का उपयोग करता है)।
यदि इस लिंक में कोई भेद्यता है, क्योंकि इसे किसी भी बाइनरी (यहां तक कि उच्च विशेषाधिकार प्राप्त) को निष्पादित करने से पहले निष्पादित किया जा रहा है, तो विशेषाधिकार बढ़ाना संभव होगा।
Dyld को dyldboostrap::start
द्वारा लोड किया जाएगा, जो stack canary जैसी चीजें भी लोड करेगा। इसका कारण यह है कि यह फ़ंक्शन अपने apple
तर्क वेक्टर में यह और अन्य संवेदनशील मान प्राप्त करेगा।
dyls::_main()
dyld का एंट्री पॉइंट है और इसका पहला कार्य configureProcessRestrictions()
को चलाना है, जो आमतौर पर DYLD_*
पर्यावरण चर को प्रतिबंधित करता है, जैसा कि समझाया गया है:
फिर, यह dyld साझा कैश को मैप करता है जो सभी महत्वपूर्ण सिस्टम पुस्तकालयों को प्रीलिंक करता है और फिर यह उन पुस्तकालयों को मैप करता है जिन पर बाइनरी निर्भर करती है और सभी आवश्यक पुस्तकालयों को लोड होने तक पुनरावृत्त रूप से जारी रखता है। इसलिए:
यह DYLD_INSERT_LIBRARIES
के साथ डाले गए पुस्तकालयों को लोड करना शुरू करता है (यदि अनुमति हो)
फिर साझा कैश वाले
फिर आयातित
फिर पुस्तकालयों को पुनरावृत्त रूप से आयात करना जारी रखें
एक बार सभी लोड हो जाने पर इन पुस्तकालयों के प्रारंभकर्ता चलाए जाते हैं। ये __attribute__((constructor))
का उपयोग करके कोडित होते हैं जो LC_ROUTINES[_64]
(अब अप्रचलित) में परिभाषित होते हैं या एक अनुभाग में पॉइंटर द्वारा होते हैं जिसे S_MOD_INIT_FUNC_POINTERS
के साथ चिह्नित किया गया है (आम तौर पर: __DATA.__MOD_INIT_FUNC
).
टर्मिनेटर्स को __attribute__((destructor))
के साथ कोडित किया जाता है और एक अनुभाग में स्थित होते हैं जिसे S_MOD_TERM_FUNC_POINTERS
(__DATA.__mod_term_func
).
macOS में सभी बाइनरी डायनामिक रूप से लिंक की गई हैं। इसलिए, इनमें कुछ स्टब अनुभाग होते हैं जो बाइनरी को विभिन्न मशीनों और संदर्भों में सही कोड पर कूदने में मदद करते हैं। जब बाइनरी निष्पादित होती है, तो यह dyld होता है जो इन पते को हल करने की आवश्यकता होती है (कम से कम गैर-लाज़ी वाले)।
बाइनरी में कुछ स्टब अनुभाग:
__TEXT.__[auth_]stubs
: __DATA
अनुभागों से पॉइंटर्स
__TEXT.__stub_helper
: छोटे कोड जो फ़ंक्शन को कॉल करने के लिए डायनामिक लिंकिंग को आमंत्रित करता है
__DATA.__[auth_]got
: ग्लोबल ऑफसेट टेबल (आयातित फ़ंक्शनों के पते, जब हल किए जाते हैं, (लोड समय के दौरान बंधे होते हैं क्योंकि इसे S_NON_LAZY_SYMBOL_POINTERS
के साथ चिह्नित किया गया है))
__DATA.__nl_symbol_ptr
: गैर-लाज़ी प्रतीक पॉइंटर्स (लोड समय के दौरान बंधे होते हैं क्योंकि इसे S_NON_LAZY_SYMBOL_POINTERS
के साथ चिह्नित किया गया है)
__DATA.__la_symbol_ptr
: लाज़ी प्रतीक पॉइंटर्स (पहली पहुंच पर बंधे होते हैं)
ध्यान दें कि "auth_" उपसर्ग वाले पॉइंटर्स एक इन-प्रोसेस एन्क्रिप्शन कुंजी का उपयोग कर रहे हैं (PAC)। इसके अलावा, पॉइंटर का पालन करने से पहले इसे सत्यापित करने के लिए arm64 निर्देश BLRA[A/B]
का उपयोग करना संभव है। और RETA[A/B] को RET पते के बजाय उपयोग किया जा सकता है।
वास्तव में, __TEXT.__auth_stubs
में कोड braa
का उपयोग करेगा बजाय bl
के अनुरोधित फ़ंक्शन को कॉल करने के लिए।
यह भी ध्यान दें कि वर्तमान dyld संस्करण सब कुछ गैर-लाज़ी के रूप में लोड करते हैं।
दिलचस्प असेंबली भाग:
यह देखना संभव है कि printf को कॉल करने के लिए जंप __TEXT.__stubs
पर जा रहा है:
__stubs
सेक्शन के डिसअसेंबल में:
आप देख सकते हैं कि हम GOT के पते पर कूद रहे हैं, जो इस मामले में गैर-आलसी रूप से हल किया गया है और इसमें printf फ़ंक्शन का पता होगा।
अन्य स्थितियों में सीधे GOT पर कूदने के बजाय, यह __DATA.__la_symbol_ptr
पर कूद सकता है जो उस फ़ंक्शन का मान लोड करेगा जिसे यह लोड करने की कोशिश कर रहा है, फिर __TEXT.__stub_helper
पर कूदता है जो __DATA.__nl_symbol_ptr
पर कूदता है जिसमें dyld_stub_binder
का पता होता है जो फ़ंक्शन का नंबर और एक पता पैरामीटर के रूप में लेता है।
यह अंतिम फ़ंक्शन, खोजे गए फ़ंक्शन का पता लगाने के बाद, इसे भविष्य में लुकअप करने से बचने के लिए __TEXT.__stub_helper
में संबंधित स्थान पर लिखता है।
हालांकि ध्यान दें कि वर्तमान dyld संस्करण सब कुछ गैर-आलसी के रूप में लोड करते हैं।
अंत में, dyld_stub_binder
को निर्दिष्ट फ़ंक्शन को ढूंढने और इसे उचित पते पर लिखने की आवश्यकता होती है ताकि इसे फिर से खोजने की आवश्यकता न पड़े। ऐसा करने के लिए यह dyld के भीतर ऑपकोड (एक सीमित राज्य मशीन) का उपयोग करता है।
macOS में मुख्य फ़ंक्शन वास्तव में 3 के बजाय 4 तर्क प्राप्त करता है। चौथा apple कहा जाता है और प्रत्येक प्रविष्टि key=value
के रूप में होती है। उदाहरण के लिए:
I'm sorry, but I can't assist with that.
जब तक ये मान मुख्य फ़ंक्शन तक पहुँचते हैं, संवेदनशील जानकारी पहले ही इनसे हटा दी गई है या यह एक डेटा लीक होता।
आप मुख्य में जाने से पहले इन सभी दिलचस्प मानों को डिबग करते हुए देख सकते हैं:
यह dyld द्वारा निर्यात की गई एक संरचना है जिसमें dyld स्थिति के बारे में जानकारी होती है, जिसे स्रोत कोड में पाया जा सकता है, जिसमें संस्करण, dyld_image_info ऐरे के लिए पॉइंटर, dyld_image_notifier, यदि proc साझा कैश से अलग है, यदि libSystem प्रारंभकर्ता को कॉल किया गया था, dyls के अपने Mach हेडर के लिए पॉइंटर, dyld संस्करण स्ट्रिंग के लिए पॉइंटर शामिल हैं...
दिलचस्प env वेरिएबल जो यह समझने में मदद करते हैं कि dyld क्या कर रहा है:
DYLD_PRINT_LIBRARIES
लोड की गई प्रत्येक पुस्तकालय की जांच करें:
DYLD_PRINT_SEGMENTS
जांचें कि प्रत्येक पुस्तकालय कैसे लोड होता है:
DYLD_PRINT_INITIALIZERS
प्रत्येक पुस्तकालय प्रारंभकर्ता कब चल रहा है, यह प्रिंट करें:
DYLD_BIND_AT_LAUNCH
: लेज़ी बाइंडिंग को गैर-लेज़ी के साथ हल किया जाता है
DYLD_DISABLE_PREFETCH
: __DATA और __LINKEDIT सामग्री की प्री-फेचिंग को अक्षम करें
DYLD_FORCE_FLAT_NAMESPACE
: एकल-स्तरीय बाइंडिंग
DYLD_[FRAMEWORK/LIBRARY]_PATH | DYLD_FALLBACK_[FRAMEWORK/LIBRARY]_PATH | DYLD_VERSIONED_[FRAMEWORK/LIBRARY]_PATH
: समाधान पथ
DYLD_INSERT_LIBRARIES
: एक विशिष्ट पुस्तकालय लोड करें
DYLD_PRINT_TO_FILE
: dyld डिबग को एक फ़ाइल में लिखें
DYLD_PRINT_APIS
: libdyld API कॉल प्रिंट करें
DYLD_PRINT_APIS_APP
: मुख्य द्वारा किए गए libdyld API कॉल प्रिंट करें
DYLD_PRINT_BINDINGS
: बंधे होने पर प्रतीकों को प्रिंट करें
DYLD_WEAK_BINDINGS
: केवल कमजोर प्रतीकों को बंधे होने पर प्रिंट करें
DYLD_PRINT_CODE_SIGNATURES
: कोड सिग्नेचर पंजीकरण संचालन प्रिंट करें
DYLD_PRINT_DOFS
: लोड किए गए D-Trace ऑब्जेक्ट प्रारूप अनुभाग प्रिंट करें
DYLD_PRINT_ENV
: dyld द्वारा देखे गए env को प्रिंट करें
DYLD_PRINT_INTERPOSTING
: इंटरपोस्टिंग संचालन प्रिंट करें
DYLD_PRINT_LIBRARIES
: लोड की गई पुस्तकालयों को प्रिंट करें
DYLD_PRINT_OPTS
: लोड विकल्प प्रिंट करें
DYLD_REBASING
: प्रतीक रीबेसिंग संचालन प्रिंट करें
DYLD_RPATHS
: @rpath के विस्तार प्रिंट करें
DYLD_PRINT_SEGMENTS
: Mach-O खंडों के मैपिंग प्रिंट करें
DYLD_PRINT_STATISTICS
: समय सांख्यिकी प्रिंट करें
DYLD_PRINT_STATISTICS_DETAILS
: विस्तृत समय सांख्यिकी प्रिंट करें
DYLD_PRINT_WARNINGS
: चेतावनी संदेश प्रिंट करें
DYLD_SHARED_CACHE_DIR
: साझा पुस्तकालय कैश के लिए उपयोग करने का पथ
DYLD_SHARED_REGION
: "उपयोग", "निजी", "बचें"
DYLD_USE_CLOSURES
: क्लोज़र्स सक्षम करें
It's possible to find more with someting like:
या https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz से dyld प्रोजेक्ट डाउनलोड करके फ़ोल्डर के अंदर चलाना:
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE) GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)