macOS Thread Injection via Task port

htARTE (HackTricks AWS Red Team Expert) से जीरो से हीरो तक AWS हैकिंग सीखें!

HackTricks का समर्थन करने के अन्य तरीके:

कोड

1. थ्रेड हाइजैकिंग

पहले, दूरस्थ कार्य से थ्रेड सूची प्राप्त करने के लिए टास्क पोर्ट पर task_threads() फ़ंक्शन को आमंत्रित किया जाता है। थ्रेड को हाइजैक करने के लिए चयनित किया जाता है। यह दृष्टिकोण पारंपरिक कोड इंजेक्शन विधियों से भिन्न है क्योंकि नए मिटिगेशन द्वारा thread_create_running() को अवरुद्ध करने के कारण एक नया दूरस्थ थ्रेड बनाना निषिद्ध है।

थ्रेड को नियंत्रित करने के लिए, thread_suspend() को कॉल किया जाता है, जिससे इसका निष्पादन रोक दिया जाता है।

दूरस्थ थ्रेड पर केवल रोकना और शुरू करने, उसके रजिस्टर मानों को प्राप्त और संशोधित करने की अनुमति है। दूरस्थ कार्य को आरंभ करने के लिए रजिस्टर x0 से x7 को आर्ग्यूमेंट्स पर सेट करके, pc को लक्षित फ़ंक्शन पर सेट करके, और थ्रेड को सक्रिय करके दूरस्थ फ़ंक्शन कॉल आरंभ किए जाते हैं। वापसी के बाद थ्रेड क्रैश न होने की सुनिश्चित करने के लिए वापसी को पहचानना आवश्यक है।

एक रणनीति में दूरस्थ थ्रेड के लिए एक अपवाद हैंडलर रजिस्टर करना thread_set_exception_ports() जिससे फ़ंक्शन कॉल से पहले lr रजिस्टर को एक अवैध पते पर सेट किया जाता है। इससे एक अपवाद फ़ंक्शन निष्पादन के बाद एक अपवाद पोर्ट को मैसेज भेजता है, जिससे थ्रेड की स्थिति की जांच की जा सकती है और वापसी मूल्य को पुनः प्राप्त किया जा सकता है। या फिर, इयान बीर के ट्रिपल_फेच धोखाधड़ी से अपनाया गया, lr को अनंतता से लूप करने के लिए सेट किया जाता है। फिर थ्रेड के रजिस्टरों को निरंतर निगरानी किया जाता है जब तक pc उस निर्देश को निशानित करता है

2. संचार के लिए मैक पोर्ट्स

अगले चरण में, दूरस्थ थ्रेड के साथ संचार सुविधा स्थापित करने के लिए मैक पोर्ट्स स्थापित करना शामिल है। ये पोर्ट्स कार्यों के बीच विभिन्न भेजने और प्राप्त करने के लिए महत्वपूर्ण हैं।

द्विदिशीय संचार के लिए, दो मैक प्राप्ति अधिकार बनाए जाते हैं: एक स्थानीय और दूरस्थ कार्य में। इसके बाद, प्रत्येक पोर्ट के लिए एक भेजने का अधिकार विपरीत कार्य में स्थानांतरित किया जाता है, संदेश विनिमय को सक्षम करते हैं।

स्थानीय पोर्ट पर ध्यान केंद्रित है, स्थानीय कार्य द्वारा प्राप्ति अधिकार को धारण किया जाता है। पोर्ट mach_port_allocate() के साथ बनाया जाता है। चुनौती इसमें है कि इस पोर्ट में एक भेजने का अधिकार दूरस्थ कार्य में स्थानांतरित करना है।

एक रणनीति शामिल है thread_set_special_port() का उपयोग करना, लोकल पोर्ट में एक भेजने का अधिकार रखने के लिए दूरस्थ थ्रेड के THREAD_KERNEL_PORT में। फिर, दूरस्थ थ्रेड को निर्देशित किया जाता है कि mach_thread_self() कॉल करें ताकि वह भेजने का अधिकार प्राप्त कर सके।

दूरस्थ पोर्ट के लिए, प्रक्रिया मूल रूप से उलट जाती है। दूरस्थ थ्रेड को निर्देशित किया जाता है कि mach_reply_port() के माध्यम से एक मैक पोर्ट उत्पन्न करें (क्योंकि mach_port_allocate() अपने वापसी तंत्र के कारण अनुचित है)। पोर्ट निर्माण के बाद, दूरस्थ थ्रेड में mach_port_insert_right() को आमंत्रित किया जाता है ताकि एक भेजने का अधिकार स्थापित हो सके। यह अधिकार फिर thread_set_special_port() का उपयोग करके कर्नल में छिपाया जाता है। स्थानीय कार्य में, दूरस्थ थ्रेड पर thread_get_special_port() का उपयोग किया जाता है ताकि दूरस्थ कार्य में नए निर्धारित मैक पोर्ट के लिए भेजने का अधिकार प्राप्त किया जा सके।

इन कदमों के पूरा होने से मैक पोर्ट्स की स्थापना होती है, जो द्विदिशीय संचार के लिए आधार रखती है।

3. मूल मेमोरी पठन/लेखन आधार

इस खंड में, कार्यान्वयन प्राथमिक मेमोरी पठन और लेखन आधार स्थापित करने के लिए एक्जीक्यूट प्राथमिक का उपयोग करने पर ध्यान केंद्रित है। ये प्रारंभिक कदम दूरस्थ प्रक्रिया पर अधिक नियंत्रण प्राप्त करने के लिए महत्वपूर्ण हैं, हालांकि इस स्थिति में प्राथमिक आधार बहुत सारे उद्देश्यों की सेवा नहीं करेंगे। जल्द ही, वे अधिक उन्नत संस्करणों में अपग्रेड किए जाएंगे।

एक्जीक्यूट प्राथमिक का उपयोग करके मेमोरी पठन और लेखन

लक्ष्य है कि विशेष कार्यों का उपयोग करके मेमोरी पठन और लेखन किया जाए। मेमोरी पठन के लिए, निम्नलिखित संरचना की तुलना करने वाले फ़ंक्शन का उपयोग किया जाता है:

uint64_t read_func(uint64_t *address) {
return *address;
}

और मेमोरी में लेखन के लिए, इस संरचना के समान कार्यों का उपयोग किया जाता है:

void write_func(uint64_t *address, uint64_t value) {
*address = value;
}

ये फ़ंक्शन दिए गए असेम्बली इंस्ट्रक्शंस के समान हैं:

_read_func:
ldr x0, [x0]
ret
_write_func:
str x1, [x0]
ret

उपयुक्त फ़ंक्शनों की पहचान

सामान्य पुस्तकालयों की जांच ने इन कार्रवाइयों के लिए उपयुक्त उम्मीदवारों को प्रकट किया:

  1. मेमोरी पढ़ना: Objective-C रनटाइम पुस्तकालय से property_getName() फ़ंक्शन को मेमोरी पढ़ने के लिए एक उपयुक्त फ़ंक्शन के रूप में पहचाना गया है। नीचे फ़ंक्शन का विवरण दिया गया है:

const char *property_getName(objc_property_t prop) {
return prop->name;
}

यह फ़ंक्शन पहले क्षेत्र को वापस करके objc_property_t का पहला फ़ील्ड लौटाते हुए कार्य करता है।

  1. मेमोरी लिखना: मेमोरी लिखने के लिए एक पूर्व-निर्मित फ़ंक्शन खोजना अधिक चुनौतीपूर्ण है। हालांकि, libxpc से _xpc_int64_set_value() फ़ंक्शन एक उपयुक्त उम्मीदवार है जिसका निम्नलिखित disassembly है:

__xpc_int64_set_value:
str x1, [x0, #0x18]
ret

एक विशिष्ट पते पर 64-बिट लेख करने के लिए, रिमोट कॉल का संरचना इस प्रकार है:

_xpc_int64_set_value(address - 0x18, value)

4. साझा स्मृति सेटअप

उद्देश्य स्थानीय और दूरस्थ कार्यों के बीच साझा स्मृति स्थापित करना है, डेटा स्थानांतरण को सरल बनाना और एकाधिक तर्कों के साथ फ़ंक्शन को बुलाना सुविधाजनक बनाना। इस दृष्टिकोण में libxpc और इसके OS_xpc_shmem ऑब्जेक्ट प्रकार का सहारा लेना शामिल है, जो माक मेमोरी एंट्रीज़ पर आधारित है।

प्रक्रिया अवलोकन:

  1. स्मृति आवंटन:

  • mach_vm_allocate() का उपयोग करके साझा करने के लिए स्मृति आवंटित करें।

  • आवंटित स्मृति क्षेत्र के लिए एक OS_xpc_shmem ऑब्ज

mach_vm_allocate();
xpc_shmem_create();

दूरस्थ प्रक्रिया में साझा स्मृति वस्तु बनाने और सुधारित करने के लिए:

malloc(); // for allocating memory remotely
thread_set_special_port(); // for inserting send right

5. पूर्ण नियंत्रण प्राप्त करना

साझा मेमोरी स्थापित करने और विचारशील क्रियान्वयन क्षमताओं को प्राप्त करने पर सफलतापूर्वक, हमने मुख्य रूप से लक्ष्य प्रक्रिया पर पूर्ण नियंत्रण प्राप्त कर लिया है। इस नियंत्रण को संभालने वाले महत्वपूर्ण कार्यक्षमताएँ हैं:

  1. विचारशील मेमोरी परिचालन:

  • साझा क्षेत्र से डेटा कॉपी करने के लिए memcpy() को आह्वान करके विचारशील मेमोरी पढ़ें।

  • साझा क्षेत्र में डेटा स्थानांतरित करने के लिए memcpy() का उपयोग करके विचारशील मेमोरी लिखें।

  1. एकाधिक तर्कों के साथ कार्य को संभालना:

  • 8 से अधिक तर्कों की आवश्यकता होने पर, कॉलिंग कन्वेंशन के अनुसार अतिरिक्त तर्कों को स्टैक पर व्यवस्थित करें।

  1. Mach पोर्ट स्थानांतरण:

  • पहले स्थापित पोर्ट के माध्यम से Mach संदेशों के माध्यम से कार्यों के बीच Mach पोर्ट स्थानांतरित करें।

  1. फ़ाइल डिस्क्रिप्टर स्थानांतरण:

  • triple_fetch में उजागर किए गए तकनीक फाइलपोर्ट्स का उपयोग करके प्रक्रियाओं के बीच फ़ाइल डिस्क्रिप्टर स्थानांतरण करें।

यह व्यापक नियंत्रण threadexec पुस्तकालय में समाहित है, जो उपकरण प्रक्रिया के साथ विवेकपूर्ण स्तर पर नियंत्रण प्राप्त करने के लिए एक विस्तृत कार्यान्वयन और उपयोगकर्ता-मित्र API प्रदान करता है।

महत्वपूर्ण विचार:

  • सिस्टम स्थिरता और डेटा अखंडता बनाए रखने के लिए मेमोरी पढ़ने/लिखने के लिए memcpy() का उचित उपयोग सुनिश्चित करें।

  • Mach पोर्ट या फ़ाइल डिस्क्रिप्टर स्थानांतरण करते समय, उचित प्रोटोकॉल का पालन करें और संसाधनों को जिम्मेदारीपूर्वक संभालने के लिए संसाधनों को लीक या अनहेतु पहुंच से बचाने के लिए।

इन दिशानिर्देशों का पालन करके और threadexec पुस्तकालय का उपयोग करके, व्यक्ति लक्षित प्रक्रिया पर पूर्ण नियंत्रण प्राप्त करने के लिए प्रक्रियाओं का प्रबंधन और अंतर्क्रिया कर सकता है।

संदर्भ

Last updated