macOS Process Abuse
प्रक्रियाओं की मौलिक जानकारी
एक प्रक्रिया एक चल रहे executable की एक उदाहरण है, हालांकि प्रक्रियाएँ कोड नहीं चलाती हैं, ये थ्रेड्स होती हैं। इसलिए प्रक्रियाएँ बस चल रहे थ्रेड्स के लिए एक डिब्बा होती हैं जो मेमोरी, डिस्क्रिप्टर, पोर्ट्स, अनुमतियाँ प्रदान करता है।
पारंपरिक रूप से, प्रक्रियाएँ अन्य प्रक्रियाओं के भीतर शुरू की जाती थीं (PID 1 को छोड़कर) fork
को कॉल करके जो वर्तमान प्रक्रिया की एक सटीक प्रतिलिपि बनाता था और फिर बच्चा प्रक्रिया आम तौर पर execve
को कॉल करके नया executable लोड करती और चलाती थी। फिर, vfork
को शीघ्र करने के लिए पेश किया गया था बिना किसी मेमोरी की कॉपी किए।
फिर posix_spawn
को पेश किया गया जो एक कॉल में vfork
और execve
को मिलाता था और फ्लैग्स स्वीकार करता था:
POSIX_SPAWN_RESETIDS
: प्रभावी आईडी को वास्तविक आईडी पर रीसेट करेंPOSIX_SPAWN_SETPGROUP
: प्रक्रिया समूह संबंध सेट करेंPOSUX_SPAWN_SETSIGDEF
: सिग्नल डिफ़ॉल्ट व्यवहार सेट करेंPOSIX_SPAWN_SETSIGMASK
: सिग्नल मास्क सेट करेंPOSIX_SPAWN_SETEXEC
: एक ही प्रक्रिया में एक्जीक्यूट (अधिक विकल्पों के साथexecve
की तरह)POSIX_SPAWN_START_SUSPENDED
: सस्पेंडेड शुरू करें_POSIX_SPAWN_DISABLE_ASLR
: ASLR के बिना शुरू करें_POSIX_SPAWN_NANO_ALLOCATOR:
libmalloc का नैनो आवंटकरण का उपयोग करें_POSIX_SPAWN_ALLOW_DATA_EXEC:
डेटा सेगमेंट परrwx
की अनुमति देंPOSIX_SPAWN_CLOEXEC_DEFAULT
: एक्जेक्यूट(2) पर सभी फ़ाइल विवरण डिस्कनेक्ट करें डिफ़ॉल्ट रूप से_POSIX_SPAWN_HIGH_BITS_ASLR:
ASLR स्लाइड के उच्च बिट को यादृच्छिक बनाएं
इसके अतिरिक्त, posix_spawn
एक posix_spawnattr
का एक बहुज्ञ स्पष्ट करने की अनुमति देता है जो उत्पन्न प्रक्रिया के कुछ पहलुओं को नियंत्रित करता है, और डिस्क्रिप्टर की स्थिति को संशोधित करने के लिए posix_spawn_file_actions
।
जब एक प्रक्रिया मर जाती है तो यह माता प्रक्रिया को रिटर्न कोड भेजती है (अगर माता मर गई, तो नया माता PID 1 है) सिग्नल SIGCHLD
के साथ। माता को इस मान को प्राप्त करने की आवश्यकता होती है wait4()
या waitid()
को कॉल करके और जब तक यह होता है तब तक बच्चा एक ज़ोम्बी स्थिति में रहता है जिसमें वह अभी भी सूचीबद्ध है लेकिन संसाधनों का उपभोग नहीं करती।
PIDs
PIDs, प्रक्रिया पहचानकर्ता, एक अद्वितीय प्रक्रिया की पहचान करता है। XNU में PIDs 64 बिट के होते हैं जो एकाधिकारिक रूप से बढ़ते हैं और कभी नहीं लपेटते हैं (दुरुपयोग से बचने के लिए)।
प्रक्रिया समूह, सत्र और कोलेशन
प्रक्रियाएँ को समूहों में डाला जा सकता है ताकि उन्हें संभालना आसान हो। उदाहरण के लिए, शैल स्क्रिप्ट में आदेश एक ही प्रक्रिया समूह में होंगे ताकि किल का उपयोग करके उन्हें संकेतित किया जा सके।
यह संभव है कि प्रक्रियाएँ सत्रों में समूहित की जाएं। जब एक प्रक्रिया एक सत्र शुरू करती है (setsid(2)
), तो बच्चे प्रक्रियाएँ सत्र के अंदर सेट की जाती हैं, जब तक वे अपना खुद का सत्र शुरू न करें।
कोलेशन एक और तरीका है जिसमें प्रक्रियाएँ ग्रुप की जाती हैं Darwin में। कोलेशन में शामिल होने वाली प्रक्रिया को यह सुविधा प्राप्त होती है कि वह पूल संसाधनों तक पहुंच सके, एक लेजर साझा कर सके या जेट्सम का सामना कर सके। कोलेशनों के विभिन्न भूमिकाएँ होती हैं: नेता, XPC सेवा, एक्सटेंशन।
परिचय और व्यक्तित्व
प्रत्येक प्रक्रिया में परिचय होता है जो सिस्टम में उसकी प्रिविलेजेज की पहचान करता है। प्रत्येक प्रक्रिया का एक मुख्य uid
और एक मुख्य gid
होगा (हालांकि कई समूहों में शामिल हो सकता है)।
यदि बाइनरी में setuid/setgid
बिट है तो उपयोगकर्ता और समूह आईडी बदलना संभव है।
नए uids/gids सेट करने के लिए कई फ़ंक्शन हैं।
सिस्टम कॉल persona
एक वैकल्पिक सेट का परिचय प्रदान करता है। एक परिचय को अपनाने से उसका uid, gid और समूह सदस्यता एक साथ माना जाता है। स्रोत कोड में स्ट्रक्टर ढूंढना संभव है:
धागों की मौलिक जानकारी
POSIX धागे (pthreads): macOS POSIX धागों (
pthreads
) का समर्थन करता है, जो C/C++ के लिए एक मानक थ्रेडिंग API का हिस्सा है। macOS में pthreads का अंकुरण/usr/lib/system/libsystem_pthread.dylib
में पाया जाता है, जो सार्वजनिक रूप से उपलब्धlibpthread
परियोजना से आता है। यह पुस्तकालय धागे बनाने और प्रबंधित करने के आवश्यक कार्य सुपूर्त करती है।धागे बनाना:
pthread_create()
फ़ंक्शन का उपयोग नए धागे बनाने के लिए किया जाता है। आंतरिक रूप से, यह फ़ंक्शनbsdthread_create()
को बुलाता है, जो XNU कर्नेल के लिए विशेष है (macOS के कर्नेल पर आधारित)। यह सिस्टम कॉलpthread_attr
(गुण) से प्राप्त विभिन्न झंडे लेता है जो धाग के व्यवहार को निर्दिष्ट करते हैं, समेत अनुसूचना नीतियाँ और स्टैक का आकार।
डिफ़ॉल्ट स्टैक का आकार: नए धागों के लिए डिफ़ॉल्ट स्टैक का आकार 512 KB है, जो सामान्य कार्रवाई के लिए पर्याप्त है लेकिन यदि अधिक या कम स्थान की आवश्यकता हो तो धाग गुणों के माध्यम से समायोजित किया जा सकता है।
धाग प्रारंभीकरण:
__pthread_init()
फ़ंक्शन धाग सेटअप के दौरान महत्वपूर्ण है,env[]
तर्क का उपयोग करते हुए पर्यावरण चर वेरिएबल्स को विश्लेषित करने के लिए उपयोग करता है जो स्टैक के स्थान और आकार के बारे में विवरण शामिल कर सकते हैं।
macOS में धाग समाप्ति
धागों को बंद करना: धागों को सामान्यत:
pthread_exit()
को बुलाकर समाप्त किया जाता है। यह फ़ंक्शन एक धाग को साफ़ रूप से बाहर निकलने देता है, आवश्यक सफ़ाई करता है और धाग को किसी भी ज्वाइनर को एक वापसी मूल्य भेजने की अनुमति देता है।धाग सफ़ाई:
pthread_exit()
को बुलाने पर,pthread_terminate()
फ़ंक्शन को आमंत्रित किया जाता है, जो सभी संबंधित धाग संरचनाओं को हटाने का संबोधन करता है। यह Mach धाग पोर्ट (Mach XNU कर्नेल में संचार उपप्रणाली है) को विनियमित करता है औरbsdthread_terminate
को बुलाता है, एक सिस्टम कॉल जो धाग से संबंधित कर्नेल स्तरीय संरचनाओं को हटाता है।
समक्रमण यांत्रिकियाँ
साझी संसाधनों तक पहुँच को प्रबंधित करने और रेस शर्तों से बचने के लिए, macOS कई समक्रमण आधार प्रदान करता है। ये बहु-धागीय परिवेशों में महत्वपूर्ण हैं ताकि डेटा सत्यापन और सिस्टम स्थिरता सुनिश्चित की जा सके:
म्यूटेक्स:
सामान्य म्यूटेक्स (हस्ताक्षर: 0x4D555458): 60 बाइट का मानक म्यूटेक्स (56 बाइट म्यूटेक्स और 4 बाइट हस्ताक्षर)।
फास्ट म्यूटेक्स (हस्ताक्षर: 0x4d55545A): सामान्य म्यूटेक्स के समान है लेकिन तेज ऑपरेशन के लिए अनुकूलित, भी 60 बाइट का आकार है।
स्थिति चरण:
किसी विशेष स्थिति के होने का इंतजार करने के लिए उपयोग किया जाता है, 44 बाइट का आकार है (40 बाइट प्लस 4 बाइट हस्ताक्षर)।
स्थिति चरण गुण (हस्ताक्षर: 0x434e4441): स्थिति चरणों के लिए विन्यास गुण, 12 बाइट का आकार है।
एक बार चरण (हस्ताक्षर: 0x4f4e4345):
यह सुनिश्चित करता है कि प्रारंभीकरण कोड केवल एक बार ही चलाया जाता है। इसका आकार 12 बाइट है।
पठन-लेखन तालिका:
एक समय में कई पाठक या एक लेखक को एक साथ अनुमति देता है, साझी डेटा तक पहुँच के लिए कुशल उपयोग करने के लिए।
पठन-लेखन तालिका (हस्ताक्षर: 0x52574c4b): 196 बाइट का आकार है।
पठन-लेखन तालिका गुण (हस्ताक्षर: 0x52574c41): पठन-लेखन तालिका के लिए गुण, 20 बाइट का आकार है।
उन वस्तुओं के अंतिम 4 बाइट ओवरफ्लो का पता लगाने के लिए उपयोग किए जाते हैं।
धाग स्थानिक चरित्र (TLV)
धाग स्थानिक चरित्र (TLV) Mach-O फ़ाइलों के संदर्भ में (macOS में एक्जीक्यूटेबल्स के लिए प्रारूप) बहु-धागीय एप्लिकेशन में प्रत्येक धाग के लिए विशेष चरित्र घोषित करने के लिए उपयोग किए जाते हैं। इससे यह सुनिश्चित होता है कि प्रत्येक धाग के पास एक अलग वस्तुस्थिति है, एक चरित्र के अलग उदाहरण को बनाए रखने के लिए, म्यूटेक्स जैसे समक्रमण यंत्रिकियों की तरह स्पष्ट समक्रमण यंत्रिकियों की आवश्यकता नहीं होती है।
C और संबंधित भाषाओं में, आप __thread
कीवर्ड का उपयोग करके एक धाग स्थानिक चरित्र घोषित कर सकते हैं। यहाँ आपके उदाहरण में यह कैसे काम करता है:
यह स्निपेट tlv_var
को एक थ्रेड-स्थानीय चर के रूप में परिभाषित करता है। इस कोड को चलाने वाले प्रत्येक थ्रेड के पास अपना खुद का tlv_var
होगा, और एक थ्रेड द्वारा tlv_var
में किए गए परिवर्तन दूसरे थ्रेड में tlv_var
को प्रभावित नहीं करेंगे।
Mach-O बाइनरी में, थ्रेड स्थानीय चरों से संबंधित डेटा को विशेष खंडों में व्यवस्थित किया जाता है:
__DATA.__thread_vars
: इस खंड में थ्रेड-स्थानीय चरों के बारे में मेटाडेटा होता है, जैसे उनके प्रकार और प्रारंभीकरण स्थिति।__DATA.__thread_bss
: यह खंड उन थ्रेड-स्थानीय चरों के लिए उपयोग किया जाता है जिन्हें स्पष्ट रूप से प्रारंभित नहीं किया गया है। यह एक भाग है जो शून्य-प्रारंभित डेटा के लिए समर्पित किया गया है।
Mach-O एक विशेष API भी प्रदान करता है जिसे tlv_atexit
कहा जाता है थ्रेड-स्थानीय चरों को प्रबंधित करने के लिए जब एक थ्रेड समाप्त होता है। यह API आपको डिस्ट्रक्टरों को रजिस्टर करने की अनुमति देता है—विशेष फ़ंक्शन जो एक थ्रेड समाप्त होने पर थ्रेड-स्थानीय डेटा को साफ करने में मदद करते हैं।
Python Injection
यदि पर्यावरण चर PYTHONINSPECT
सेट किया गया है, तो पायथन प्रक्रिया एक पायथन cli में चलेगी जब वह समाप्त हो जाएगी। एक इंटरैक्टिव सत्र की शुरुआत में किसी पायथन स्क्रिप्ट को निष्पादित करने के लिए PYTHONSTARTUP
का उपयोग भी संभव है।
हालांकि, ध्यान दें कि PYTHONINSPECT
इंटरैक्टिव सत्र बनाते समय PYTHONSTARTUP
स्क्रिप्ट को निष्पादित नहीं करेगा।
PYTHONPATH
और PYTHONHOME
जैसे अन्य एनवी चर भी एक पायथन कमांड को विचारशील कोड निष्पादित करने के लिए उपयोगी हो सकते हैं।
ध्यान दें कि pyinstaller
के साथ कंपाइल किए गए एक्जीक्यूटेबल्स इन पर्यावरण चरों का उपयोग नहीं करेंगे, भले ही वे एक एम्बेडेड पायथन का उपयोग करके चल रहे हों।
समग्र रूप से मैंने पायथन को विचारशील कोड निष्पादित करने के लिए पर्यावरण चरों का दुरुपयोग करने का कोई तरीका नहीं ढूंढा।\ हालांकि, अधिकांश लोग **Hombrew** का उपयोग करके पायथन को स्थापित करते हैं, जो एक **लिखने योग्य स्थान** में पायथन स्थापित करेगा। आप इसे कुछ इस प्रकार से हाइजैक कर सकते हैं: ```bash mv /opt/homebrew/bin/python3 /opt/homebrew/bin/python3.old cat > /opt/homebrew/bin/python3 <
ढाल
ढाल (गिटहब) एक ओपन सोर्स एप्लिकेशन है जो प्रक्रिया इंजेक्शन की पहचान और ब्लॉक कर सकता है:
पर्यावरणीय चर का उपयोग: यह निम्नलिखित पर्यावरणीय चरों की मौजूदगी का मॉनिटर करेगा:
DYLD_INSERT_LIBRARIES
,CFNETWORK_LIBRARY_PATH
,RAWCAMERA_BUNDLE_PATH
औरELECTRON_RUN_AS_NODE
task_for_pid
कॉल का उपयोग: एक प्रक्रिया जब किसी अन्य प्रक्रिया के कार्य पोर्ट को प्राप्त करना चाहती है जिससे प्रक्रिया में कोड इंजेक्ट किया जा सकता है।इलेक्ट्रॉन ऐप्स पैरामीटर: कोई
--inspect
,--inspect-brk
और--remote-debugging-port
कमांड लाइन आर्ग्यूमेंट का उपयोग करके एक इलेक्ट्रॉन ऐप को डीबगिंग मोड में शुरू कर सकता है, और इसे इंजेक्ट कर सकता है।सिमलिंक्स या हार्डलिंक्स का उपयोग: सामान्यत: सबसे आम दुरुपयोग हमारे उपयोगकर्ता विशेषाधिकारों के साथ एक लिंक रखना है, और उच्च विशेषाधिकार स्थान की ओर इसे दिखाना। हार्डलिंक और सिमलिंक्स के लिए डिटेक्शन बहुत सरल है। अगर लिंक बनाने वाली प्रक्रिया का विभिन्न विशेषाधिकार स्तर लक्ष्य फ़ाइल से अलग है, तो हम एक अलर्ट बनाते हैं। दुर्भाग्यवश: सिमलिंक्स के मामले में ब्लॉकिंग संभव नहीं है, क्योंकि हमें लिंक के गंतव्य के बारे में जानकारी नहीं है पहले से। यह Apple के एंडपॉइंटसेक्यूरिटी फ़्रेमवर्क की एक सीमा है।
अन्य प्रक्रियाओं द्वारा की गई कॉल्स
इस ब्लॉग पोस्ट में आप देख सकते हैं कि कैसे फ़ंक्शन task_name_for_pid
का उपयोग करके एक प्रक्रिया में कोड इंजेक्शन करने वाली अन्य प्रक्रियाओं के बारे में जानकारी प्राप्त की जा सकती है और फिर उस अन्य प्रक्रिया के बारे में जानकारी प्राप्त की जा सकती है।
ध्यान दें कि उस फ़ंक्शन को कॉल करने के लिए आपको प्रक्रिया चलाने वाले व्यक्ति के एक ही uid होना चाहिए या रूट (और यह प्रक्रिया के बारे में जानकारी देता है, कोड इंजेक्शन का एक तरीका नहीं।)
संदर्भ
Last updated