macOS Thread Injection via Task port
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)
शुरुआत में, task_threads()
फ़ंक्शन को कार्य पोर्ट पर दूरस्थ कार्य से थ्रेड सूची प्राप्त करने के लिए लागू किया जाता है। एक थ्रेड को हाईजैकिंग के लिए चुना जाता है। यह दृष्टिकोण पारंपरिक कोड इंजेक्शन विधियों से भिन्न है क्योंकि नए दूरस्थ थ्रेड का निर्माण thread_create_running()
द्वारा अवरुद्ध किया गया है।
थ्रेड को नियंत्रित करने के लिए, thread_suspend()
को कॉल किया जाता है, जिससे इसकी निष्पादन रुक जाती है।
दूरस्थ थ्रेड पर केवल रोकना और शुरू करना, पंजीकरण मान प्राप्त करना और संशोधित करना की अनुमति है। दूरस्थ फ़ंक्शन कॉल को रजिस्टर x0
से x7
को आर्गुमेंट्स पर सेट करके, pc
को लक्षित फ़ंक्शन पर कॉन्फ़िगर करके, और थ्रेड को सक्रिय करके शुरू किया जाता है। यह सुनिश्चित करना कि थ्रेड लौटने के बाद क्रैश न हो, लौटने का पता लगाने की आवश्यकता होती है।
एक रणनीति में दूरस्थ थ्रेड के लिए एक्सेप्शन हैंडलर को thread_set_exception_ports()
का उपयोग करके पंजीकृत करना शामिल है, फ़ंक्शन कॉल से पहले lr
रजिस्टर को एक अमान्य पते पर सेट करना। यह फ़ंक्शन निष्पादन के बाद एक अपवाद को ट्रिगर करता है, अपवाद पोर्ट पर एक संदेश भेजता है, थ्रेड की स्थिति की जांच करने की अनुमति देता है ताकि लौटने का मान पुनर्प्राप्त किया जा सके। वैकल्पिक रूप से, इयान बीयर के ट्रिपल_fetch एक्सप्लॉइट से अपनाई गई विधि में, lr
को अनंत लूप में सेट किया जाता है। थ्रेड के रजिस्टर को तब लगातार मॉनिटर किया जाता है जब तक pc
उस निर्देश की ओर इशारा नहीं करता।
अगले चरण में दूरस्थ थ्रेड के साथ संचार को सुविधाजनक बनाने के लिए Mach पोर्ट स्थापित करना शामिल है। ये पोर्ट कार्यों के बीच मनमाने भेजने और प्राप्त करने के अधिकारों को स्थानांतरित करने में महत्वपूर्ण हैं।
द्विदिश संचार के लिए, दो Mach प्राप्त करने के अधिकार बनाए जाते हैं: एक स्थानीय में और दूसरा दूरस्थ कार्य में। इसके बाद, प्रत्येक पोर्ट के लिए एक भेजने का अधिकार समकक्ष कार्य में स्थानांतरित किया जाता है, जिससे संदेशों का आदान-प्रदान संभव होता है।
स्थानीय पोर्ट पर ध्यान केंद्रित करते हुए, प्राप्त करने का अधिकार स्थानीय कार्य द्वारा रखा जाता है। पोर्ट को mach_port_allocate()
के साथ बनाया जाता है। चुनौती इस पोर्ट के लिए एक भेजने के अधिकार को दूरस्थ कार्य में स्थानांतरित करने में है।
एक रणनीति में thread_set_special_port()
का उपयोग करके दूरस्थ थ्रेड के THREAD_KERNEL_PORT
में स्थानीय पोर्ट के लिए एक भेजने का अधिकार रखना शामिल है। फिर, दूरस्थ थ्रेड को mach_thread_self()
को कॉल करने के लिए निर्देशित किया जाता है ताकि भेजने का अधिकार प्राप्त किया जा सके।
दूरस्थ पोर्ट के लिए, प्रक्रिया मूल रूप से उलट होती है। दूरस्थ थ्रेड को mach_reply_port()
के माध्यम से एक Mach पोर्ट उत्पन्न करने के लिए निर्देशित किया जाता है (क्योंकि mach_port_allocate()
इसकी वापसी तंत्र के कारण अनुपयुक्त है)। पोर्ट निर्माण के बाद, mach_port_insert_right()
को दूरस्थ थ्रेड में भेजने के अधिकार को स्थापित करने के लिए लागू किया जाता है। यह अधिकार फिर thread_set_special_port()
का उपयोग करके कर्नेल में रखा जाता है। स्थानीय कार्य में वापस, thread_get_special_port()
का उपयोग दूरस्थ कार्य में नए आवंटित Mach पोर्ट के लिए भेजने के अधिकार को प्राप्त करने के लिए किया जाता है।
इन चरणों को पूरा करने से Mach पोर्ट स्थापित होते हैं, जो द्विदिश संचार के लिए आधार तैयार करते हैं।
इस अनुभाग में, बुनियादी मेमोरी पढ़ने और लिखने की प्राइमिटिव स्थापित करने के लिए निष्पादित प्राइमिटिव का उपयोग करने पर ध्यान केंद्रित किया गया है। ये प्रारंभिक कदम दूरस्थ प्रक्रिया पर अधिक नियंत्रण प्राप्त करने के लिए महत्वपूर्ण हैं, हालांकि इस चरण में प्राइमिटिव का अधिक उपयोग नहीं होगा। जल्द ही, उन्हें अधिक उन्नत संस्करणों में अपग्रेड किया जाएगा।
उद्देश्य विशिष्ट फ़ंक्शंस का उपयोग करके मेमोरी पढ़ने और लिखने का प्रदर्शन करना है। मेमोरी पढ़ने के लिए, निम्नलिखित संरचना के समान फ़ंक्शंस का उपयोग किया जाता है:
और मेमोरी में लिखने के लिए, इस संरचना के समान फ़ंक्शन का उपयोग किया जाता है:
ये फ़ंक्शन दिए गए असेंबली निर्देशों के अनुरूप हैं:
सामान्य पुस्तकालयों का स्कैन इन संचालन के लिए उपयुक्त उम्मीदवारों का खुलासा करता है:
मेमोरी पढ़ना: property_getName()
फ़ंक्शन Objective-C रनटाइम पुस्तकालय से मेमोरी पढ़ने के लिए एक उपयुक्त फ़ंक्शन के रूप में पहचाना गया है। फ़ंक्शन नीचे वर्णित है:
यह फ़ंक्शन प्रभावी रूप से read_func
की तरह कार्य करता है, जो objc_property_t
के पहले फ़ील्ड को लौटाता है।
मेमोरी लिखना: मेमोरी लिखने के लिए एक पूर्व-निर्मित फ़ंक्शन खोजना अधिक चुनौतीपूर्ण है। हालाँकि, libxpc से _xpc_int64_set_value()
फ़ंक्शन एक उपयुक्त उम्मीदवार है, जिसमें निम्नलिखित डिस्सेम्बली है:
एक विशिष्ट पते पर 64-बिट लिखने के लिए, दूरस्थ कॉल को इस प्रकार संरचित किया जाता है:
इन प्राइमिटिव्स की स्थापना के साथ, साझा मेमोरी बनाने के लिए मंच तैयार है, जो दूरस्थ प्रक्रिया को नियंत्रित करने में एक महत्वपूर्ण प्रगति है।
उद्देश्य स्थानीय और दूरस्थ कार्यों के बीच साझा मेमोरी स्थापित करना है, डेटा ट्रांसफर को सरल बनाना और कई तर्कों के साथ कार्यों को कॉल करने की सुविधा प्रदान करना है। यह दृष्टिकोण libxpc
और इसके OS_xpc_shmem
ऑब्जेक्ट प्रकार का उपयोग करता है, जो मच मेमोरी प्रविष्टियों पर आधारित है।
मेमोरी आवंटन:
साझा करने के लिए मेमोरी आवंटित करें mach_vm_allocate()
का उपयोग करके।
आवंटित मेमोरी क्षेत्र के लिए OS_xpc_shmem
ऑब्जेक्ट बनाने के लिए xpc_shmem_create()
का उपयोग करें। यह फ़ंक्शन मच मेमोरी प्रविष्टि के निर्माण का प्रबंधन करेगा और OS_xpc_shmem
ऑब्जेक्ट के ऑफसेट 0x18
पर मच भेजने का अधिकार संग्रहीत करेगा।
दूरस्थ प्रक्रिया में साझा मेमोरी बनाना:
दूरस्थ प्रक्रिया में OS_xpc_shmem
ऑब्जेक्ट के लिए मेमोरी आवंटित करें malloc()
के लिए एक दूरस्थ कॉल के साथ।
स्थानीय OS_xpc_shmem
ऑब्जेक्ट की सामग्री को दूरस्थ प्रक्रिया में कॉपी करें। हालाँकि, यह प्रारंभिक कॉपी ऑफसेट 0x18
पर गलत मच मेमोरी प्रविष्टि नाम होगा।
मच मेमोरी प्रविष्टि को सही करना:
दूरस्थ कार्य में मच मेमोरी प्रविष्टि के लिए एक भेजने का अधिकार डालने के लिए thread_set_special_port()
विधि का उपयोग करें।
दूरस्थ मेमोरी प्रविष्टि के नाम के साथ इसे ओवरराइट करके ऑफसेट 0x18
पर मच मेमोरी प्रविष्टि फ़ील्ड को सही करें।
साझा मेमोरी सेटअप को अंतिम रूप देना:
दूरस्थ OS_xpc_shmem
ऑब्जेक्ट को मान्य करें।
xpc_shmem_remote()
के लिए एक दूरस्थ कॉल के साथ साझा मेमोरी मैपिंग स्थापित करें।
इन चरणों का पालन करके, स्थानीय और दूरस्थ कार्यों के बीच साझा मेमोरी को कुशलतापूर्वक सेट किया जाएगा, जिससे डेटा ट्रांसफर और कई तर्कों की आवश्यकता वाले कार्यों के निष्पादन में आसानी होगी।
मेमोरी आवंटन और साझा मेमोरी ऑब्जेक्ट निर्माण के लिए:
दूरस्थ प्रक्रिया में साझा मेमोरी ऑब्जेक्ट बनाने और सुधारने के लिए:
याद रखें कि साझा मेमोरी सेटअप को सही ढंग से कार्य करने के लिए Mach पोर्ट और मेमोरी एंट्री नामों के विवरण को सही तरीके से संभालें।
साझा मेमोरी स्थापित करने और मनमाने निष्पादन क्षमताओं को प्राप्त करने में सफल होने पर, हमने मूल रूप से लक्षित प्रक्रिया पर पूर्ण नियंत्रण प्राप्त कर लिया है। इस नियंत्रण को सक्षम करने वाली मुख्य कार्यक्षमताएँ हैं:
मनमानी मेमोरी संचालन:
साझा क्षेत्र से डेटा कॉपी करने के लिए memcpy()
को कॉल करके मनमानी मेमोरी पढ़ें।
साझा क्षेत्र में डेटा स्थानांतरित करने के लिए memcpy()
का उपयोग करके मनमानी मेमोरी लिखें।
कई तर्कों के साथ फ़ंक्शन कॉल को संभालना:
उन फ़ंक्शनों के लिए जो 8 से अधिक तर्कों की आवश्यकता होती है, कॉलिंग कन्वेंशन के अनुपालन में अतिरिक्त तर्कों को स्टैक पर व्यवस्थित करें।
Mach पोर्ट स्थानांतरण:
पहले से स्थापित पोर्ट के माध्यम से Mach संदेशों के माध्यम से कार्यों के बीच Mach पोर्ट स्थानांतरित करें।
फाइल डिस्क्रिप्टर स्थानांतरण:
triple_fetch
में Ian Beer द्वारा उजागर की गई तकनीक का उपयोग करके प्रक्रियाओं के बीच फाइल डिस्क्रिप्टर स्थानांतरित करें।
यह व्यापक नियंत्रण threadexec पुस्तकालय के भीतर संकुचित है, जो पीड़ित प्रक्रिया के साथ बातचीत के लिए एक विस्तृत कार्यान्वयन और उपयोगकर्ता के अनुकूल API प्रदान करता है।
सिस्टम स्थिरता और डेटा अखंडता बनाए रखने के लिए मेमोरी पढ़ने/लिखने के संचालन के लिए memcpy()
का सही उपयोग सुनिश्चित करें।
Mach पोर्ट या फाइल डिस्क्रिप्टर स्थानांतरित करते समय, उचित प्रोटोकॉल का पालन करें और रिसोर्सेस को जिम्मेदारी से संभालें ताकि लीक या अनपेक्षित पहुंच से बचा जा सके।
इन दिशानिर्देशों का पालन करके और threadexec
पुस्तकालय का उपयोग करके, कोई भी प्रक्रियाओं का कुशलतापूर्वक प्रबंधन और बातचीत कर सकता है, लक्षित प्रक्रिया पर पूर्ण नियंत्रण प्राप्त कर सकता है।
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)