macOS Process Abuse
प्रक्रियाओं की मौलिक जानकारी
एक प्रक्रिया एक चल रहे executable का एक उदाहरण है, हालांकि प्रक्रियाएँ कोड नहीं चलाती हैं, ये threads होती हैं। इसलिए प्रक्रियाएँ बस चल रहे threads के लिए डिब्बे होती हैं जो मेमोरी, डिस्क्रिप्टर, पोर्ट्स, अनुमतियाँ प्रदान करती हैं।
पारंपरिक रूप से, प्रक्रियाएँ अन्य प्रक्रियाओं के भीतर शुरू की जाती थीं (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()
बुलाकर समाप्त किया जाता है। यह फ़ंक्शन एक धाग को स्वच्छ रूप से बाहर निकलने देता है, आवश्यक सफाई करता है और धाग को किसी भी joiners को एक वापसी मूल्य भेजने की अनुमति देता है।धाग सफाई:
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) 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 का उपयोग करके पायथन को स्थापित करते हैं, जो एक लिखने योग्य स्थान में पायथन स्थापित करेगा। आप इसे कुछ इस प्रकार से हाइजैक कर सकते हैं:
यह कोड चलाने पर root भी इस कोड को चलाएगा जब python चलाया जाएगा।
पता लगाना
ढाल
ढाल (Github) एक ओपन सोर्स एप्लिकेशन है जो प्रक्रिया इंजेक्शन की पहचान और ब्लॉक कर सकता है:
पर्यावरणीय चर का उपयोग: यह निम्नलिखित पर्यावरणीय चरों की मौजूदगी का मॉनिटर करेगा:
DYLD_INSERT_LIBRARIES
,CFNETWORK_LIBRARY_PATH
,RAWCAMERA_BUNDLE_PATH
औरELECTRON_RUN_AS_NODE
task_for_pid
कॉल का उपयोग: एक प्रक्रिया को दूसरे की कार्य पोर्ट प्राप्त करना चाहती है जिससे प्रक्रिया में कोड इंजेक्ट किया जा सके।Electron एप्लिकेशन पैरामीटर: कोई
--inspect
,--inspect-brk
और--remote-debugging-port
कमांड लाइन तर्क का उपयोग कर सकता है एक Electron एप्लिकेशन को डीबगिंग मोड में शुरू करने के लिए, और इसे इंजेक्ट कर सकता है।सिमलिंक्स या हार्डलिंक्स का उपयोग: सामान्यत: सबसे आम दुरुपयोग है कि हमारे उपयोगकर्ता विशेषाधिकारों के साथ एक लिंक रखें, और उसे उच्च विशेषाधिकार स्थान पर पॉइंट करें। हार्डलिंक और सिमलिंक्स के लिए पहचान बहुत सरल है। यदि लिंक बनाने वाली प्रक्रिया का विभिन्न विशेषाधिकार स्तर है तो हम एक अलर्ट बनाते हैं। दुर्भाग्यवश: सिमलिंक्स के मामले में ब्लॉकिंग संभव नहीं है, क्योंकि हमें लिंक के गंतव्य के बारे में जानकारी पहले से नहीं है। यह Apple के EndpointSecuriy framework की एक सीमा है।
अन्य प्रक्रियाओं द्वारा की गई कॉल
इस ब्लॉग पोस्ट में आप देख सकते हैं कि कैसे फ़ंक्शन task_name_for_pid
का उपयोग करके एक प्रक्रिया में कोड इंजेक्ट करने वाली अन्य प्रक्रियाओं के बारे में जानकारी प्राप्त की जा सकती है और फिर उस अन्य प्रक्रिया के बारे में जानकारी प्राप्त की जा सकती है।
ध्यान दें कि उस फ़ंक्शन को कॉल करने के लिए आपको प्रक्रिया चलाने वाले व्यक्ति के एक ही uid होना चाहिए या root (और यह प्रक्रिया के बारे में जानकारी देता है, कोड इंजेक्ट करने का एक तरीका नहीं)।
संदर्भ
Last updated