DDexec / EverythingExec
संदर्भ
Linux में किसी प्रोग्राम को चलाने के लिए यह एक फ़ाइल के रूप में मौजूद होना चाहिए, इसे किसी भी तरीके से फ़ाइल सिस्टम हाइरार्की के माध्यम से पहुंचना चाहिए (यह बस execve()
कैसे काम करता है). यह फ़ाइल डिस्क पर हो सकती है या रैम में (tmpfs, memfd) लेकिन आपको एक फ़ाइलपथ की आवश्यकता है। यह बहुत आसान बना दिया है कि लिनक्स सिस्टम पर क्या चलाया जाता है, यह खतरों और हमले के उपकरणों को पहचानना आसान बनाता है या उन्हें किसी भी चीज़ को चलाने की कोशिश करने से रोकने के लिए (जैसे अनधिकृत उपयोगकर्ताओं को कहीं भी निषेधित नहीं करने देना)।
लेकिन यह तकनीक इस सभी को बदलने के लिए यहाँ है। यदि आप जिस प्रक्रिया को चाहते हैं उसे शुरू नहीं कर सकते हैं... तो आप एक पहले से मौजूद प्रक्रिया को हाइजैक कर सकते हैं।
यह तकनीक आपको सामान्य सुरक्षा तकनीकों जैसे कि केवल पढ़ने योग्य, noexec, फ़ाइल-नाम सफेद सूची, हैश सफेद सूची... को छूने की अनुमति देती है।
Dependencies
अंतिम स्क्रिप्ट निम्नलिखित उपकरणों पर निर्भर करता है काम करने के लिए, वे आपके द्वारा हमला किए जा रहे सिस्टम में पहुंचने की आवश्यकता है (डिफ़ॉल्ट रूप से आप उन्हें हर जगह पाएंगे):
तकनीक
यदि आप किसी प्रक्रिया की मेमोरी को विचारशील रूप से संशोधित कर सकते हैं तो आप इसे अधिकार में ले सकते हैं। इसका उपयोग किसी पहले से मौजूद प्रक्रिया को हाइजैक करने और उसे दूसरे कार्यक्रम से बदलने के लिए किया जा सकता है। हम इसे या तो ptrace()
सिस्टेम कॉल का उपयोग करके (जिसके लिए आपको सिस्टम पर सिस्टेम कॉल को निष्पादित करने की क्षमता होनी चाहिए या सिस्टम पर gdb उपलब्ध होना चाहिए) या, और भी दिलचस्पी से, /proc/$pid/mem
में लिखकर प्राप्त कर सकते हैं।
फ़ाइल /proc/$pid/mem
एक प्रक्रिया के पूरे पता अंतरिक्ष का एक-से-एक मैपिंग है (जैसे 0x0000000000000000
से 0x7ffffffffffff000
तक x86-64 में)। इसका अर्थ है कि इस फ़ाइल से किसी ऑफसेट x
पर पढ़ना या लिखना उसी तरह है जैसे कि वर्चुअल पते x
पर सामग्री को पढ़ना या संशोधित करना।
अब, हमें चार मूल समस्याओं का सामना करना होगा:
सामान्य रूप से, केवल रूट और फ़ाइल के कार्यक्रम मालिक इसे संशोधित कर सकते हैं।
ASLR।
यदि हम किसी प्रोग्राम के पते में मैप नहीं किए गए पते पर पढ़ने या लिखने की कोशिश करते हैं तो हमें एक I/O त्रुटि मिलेगी।
इन समस्याओं के समाधान हैं जो, यद्यपि वे पूर्ण नहीं हैं, अच्छे हैं:
अधिकांश शैल अनुवादकों को बच्चा प्रक्रियाओं द्वारा विरासत में लिए जाएंगे फ़ाइल डेस्क्रिप्टर्स का निर्माण करने की अनुमति देते हैं। हम एक फ़ाइल डेस्क्रिप्टर बना सकते हैं जो लिखने की अनुमति वाली शैल की
mem
फ़ाइल की ओर पॉइंट करता है... तो उन बच्चा प्रक्रियाएँ जो उस fd का उपयोग करती हैं वे शैल की मेमोरी को संशोधित कर सकेंगी।ASLR एक समस्या ही नहीं है, हम शैल की
maps
फ़ाइल या प्रोसेस के पता अंतरिक्ष के बारे में जानकारी प्राप्त करने के लिए procfs से किसी भी अन्य को जांच सकते हैं।इसलिए हमें फ़ाइल पर
lseek()
करने की आवश्यकता है। शैल से यह नहीं किया जा सकता अगर केवल दुर्भाग्यपूर्णdd
का उपयोग किया जाता है।
अधिक विस्तार में
चरण साधारण हैं और इन्हें समझने के लिए किसी भी प्रकार की विशेषज्ञता की आवश्यकता नहीं है:
हमें वह बाइनरी जिसे हम चलाना चाहते हैं और लोडर का विश्लेषण करना होगा ताकि हम जान सकें कि वे कौन-कौन सी मैपिंग चाहते हैं। फिर एक "शैल"कोड बनाएं जो, सामान्य रूप से,
execve()
को हर कॉल पर कर्नल द्वारा किए जाने वाले विशेष कदमों को करेगा:उक्त मैपिंग बनाएं।
उनमें बाइनरी डालें।
अनुमतियाँ सेट करें।
अंत में प्रोग्राम के लिए ताकत देने वाले तर्कों के साथ स्टैक को प्रारंभ करें और सहायक वेक्टर (लोडर द्वारा आवश्यक) रखें।
लोडर में जाएं और उसे बाकी का काम करने दें (प्रोग्राम द्वारा आवश्यक पुस्तकालयों को लोड करना)।
syscall
फ़ाइल से प्रक्रिया जिस पते पर वापस आएगी उसे प्राप्त करें जिसे वह वर्तमान में निष्पादित कर रही है।उस स्थान को अधिकारी बनाएं, जो कार्यक्रम द्वारा निष्पादित होगा, हमारे शैलकोड से (द्वारा
mem
हम अनलिखनीय पृष्ठों को संशोधित कर सकते हैं)।प्रोसेस के stdin में उस प्रोग्राम को पास करें जिसे हम चलाना चाहते हैं (उस "शैल"कोड द्वारा
read()
किया जाएगा)।इस बिंदु पर लोडर को हमारे प्रोग्राम के लिए आवश्यक पुस्तकालयों को लोड करने और उसमें जाने के लिए है।
टूल की जाँच करें https://github.com/arget13/DDexec
EverythingExec
dd
के लिए केवल उद्देश्य के लिए उपयोग किए जाने वाले lseek()
के लिए वर्तमान में डिफ़ॉल्ट कार्यक्रम हैं, उसके लिए tail
जैसे कई विकल्प हैं जो mem
फ़ाइल के माध्यम से lseek()
करने के लिए उपयोग किए जाते हैं। उक्त विकल्प हैं:
चर SEEKER
सेट करके आप उपयोग किए जाने वाले सीकर को बदल सकते हैं, उदा.:
यदि आप स्क्रिप्ट में अन्य एक मान्य सीकर खोजते हैं जो कि अंमल में नहीं है, तो आप SEEKER_ARGS
वेरिएबल को सेट करके इस्तेमाल कर सकते हैं:
संदर्भ
Last updated