# DDexec / EverythingExec {{#include ../../../banners/hacktricks-training.md}} ## संदर्भ Linux में किसी प्रोग्राम को चलाने के लिए, यह एक फ़ाइल के रूप में मौजूद होना चाहिए, इसे फ़ाइल प्रणाली पदानुक्रम के माध्यम से किसी न किसी तरह से सुलभ होना चाहिए (यह बस `execve()` कैसे काम करता है)। यह फ़ाइल डिस्क पर या RAM (tmpfs, memfd) में हो सकती है लेकिन आपको एक फ़ाइल पथ की आवश्यकता है। इसने Linux सिस्टम पर जो चलाया जा रहा है उसे नियंत्रित करना बहुत आसान बना दिया है, यह खतरों और हमलावरों के उपकरणों का पता लगाना आसान बनाता है या उन्हें अपने किसी भी कार्य को निष्पादित करने से रोकता है (_e. g._ बिना विशेषाधिकार वाले उपयोगकर्ताओं को कहीं भी निष्पादन योग्य फ़ाइलें रखने की अनुमति नहीं देना)। लेकिन यह तकनीक सभी चीजों को बदलने के लिए यहाँ है। यदि आप वह प्रक्रिया शुरू नहीं कर सकते जिसे आप चाहते हैं... **तो आप पहले से मौजूद एक को हाईजैक कर लेते हैं**। यह तकनीक आपको **सामान्य सुरक्षा तकनीकों जैसे कि पढ़ने के लिए केवल, noexec, फ़ाइल नाम श्वेतसूची, हैश श्वेतसूची... को बायपास करने की अनुमति देती है**। ## निर्भरताएँ अंतिम स्क्रिप्ट को काम करने के लिए निम्नलिखित उपकरणों पर निर्भर करती है, उन्हें उस सिस्टम में सुलभ होना चाहिए जिसे आप लक्षित कर रहे हैं (डिफ़ॉल्ट रूप से, आप इन्हें हर जगह पाएंगे): ``` dd bash | zsh | ash (busybox) head tail cut grep od readlink wc tr base64 ``` ## तकनीक यदि आप किसी प्रक्रिया की मेमोरी को मनमाने तरीके से संशोधित करने में सक्षम हैं, तो आप इसे अपने नियंत्रण में ले सकते हैं। इसका उपयोग पहले से मौजूद प्रक्रिया को हाईजैक करने और इसे किसी अन्य प्रोग्राम से बदलने के लिए किया जा सकता है। हम इसे या तो `ptrace()` syscall का उपयोग करके प्राप्त कर सकते हैं (जिसके लिए आपको syscalls को निष्पादित करने की क्षमता होनी चाहिए या सिस्टम पर gdb उपलब्ध होना चाहिए) या, अधिक दिलचस्प तरीके से, `/proc/$pid/mem` में लिखकर। फाइल `/proc/$pid/mem` एक प्रक्रिया के पूरे पते के स्थान का एक-से-एक मैपिंग है (_जैसे_ `0x0000000000000000` से `0x7ffffffffffff000` तक x86-64 में)। इसका मतलब है कि इस फाइल से किसी ऑफसेट `x` पर पढ़ना या लिखना वर्चुअल पते `x` पर सामग्री को पढ़ने या संशोधित करने के समान है। अब, हमारे सामने चार बुनियादी समस्याएँ हैं: - सामान्यतः, केवल रूट और फाइल के प्रोग्राम मालिक इसे संशोधित कर सकते हैं। - ASLR। - यदि हम किसी पते पर पढ़ने या लिखने की कोशिश करते हैं जो प्रोग्राम के पते के स्थान में मैप नहीं किया गया है, तो हमें I/O त्रुटि मिलेगी। इन समस्याओं के समाधान हैं जो, हालांकि वे परिपूर्ण नहीं हैं, अच्छे हैं: - अधिकांश शेल इंटरप्रेटर फ़ाइल डिस्क्रिप्टर्स बनाने की अनुमति देते हैं जो फिर चाइल्ड प्रक्रियाओं द्वारा विरासत में लिए जाएंगे। हम एक fd बना सकते हैं जो लिखने की अनुमति के साथ शेल के `mem` फ़ाइल की ओर इशारा करता है... इसलिए चाइल्ड प्रक्रियाएँ जो उस fd का उपयोग करती हैं, शेल की मेमोरी को संशोधित कर सकेंगी। - ASLR भी एक समस्या नहीं है, हम शेल की `maps` फ़ाइल या procfs से किसी अन्य फ़ाइल की जांच कर सकते हैं ताकि प्रक्रिया के पते के स्थान के बारे में जानकारी प्राप्त कर सकें। - इसलिए हमें फ़ाइल पर `lseek()` करना होगा। शेल से यह तब तक नहीं किया जा सकता जब तक कि कुख्यात `dd` का उपयोग न किया जाए। ### अधिक विस्तार में चरण अपेक्षाकृत आसान हैं और इन्हें समझने के लिए किसी प्रकार की विशेषज्ञता की आवश्यकता नहीं है: - उस बाइनरी का विश्लेषण करें जिसे हम चलाना चाहते हैं और लोडर को यह पता लगाने के लिए कि उन्हें कौन से मैपिंग की आवश्यकता है। फिर एक "शेल" कोड तैयार करें जो, सामान्य तौर पर, उन चरणों को करेगा जो कर्नेल प्रत्येक `execve()` कॉल पर करता है: - उक्त मैपिंग बनाएं। - बाइनरी को उनमें पढ़ें। - अनुमतियाँ सेट करें। - अंततः प्रोग्राम के लिए तर्कों के साथ स्टैक को प्रारंभ करें और सहायक वेक्टर (लोडर द्वारा आवश्यक) को रखें। - लोडर में कूदें और इसे बाकी का काम करने दें (प्रोग्राम द्वारा आवश्यक पुस्तकालय लोड करें)। - `syscall` फ़ाइल से उस पते को प्राप्त करें जिस पर प्रक्रिया उस syscall के बाद लौटेगी जिसे वह निष्पादित कर रही है। - उस स्थान को ओवरराइट करें, जो निष्पादन योग्य होगा, हमारे शेलकोड के साथ (हम `mem` के माध्यम से लिखने योग्य पृष्ठों को संशोधित कर सकते हैं)। - जिस प्रोग्राम को हम चलाना चाहते हैं उसे प्रक्रिया के stdin पर पास करें (उसे उक्त "शेल" कोड द्वारा `read()` किया जाएगा)। - इस बिंदु पर लोडर पर निर्भर है कि वह हमारे प्रोग्राम के लिए आवश्यक पुस्तकालय लोड करे और उसमें कूदे। **उपकरण की जांच करें** [**https://github.com/arget13/DDexec**](https://github.com/arget13/DDexec) ## EverythingExec `dd` के कई विकल्प हैं, जिनमें से एक, `tail`, वर्तमान में `mem` फ़ाइल के माध्यम से `lseek()` करने के लिए डिफ़ॉल्ट प्रोग्राम है (जिसका एकमात्र उद्देश्य `dd` का उपयोग करना था)। उक्त विकल्प हैं: ```bash tail hexdump cmp xxd ``` `SEEKER` वेरिएबल सेट करके आप उपयोग किए जाने वाले सीकर को बदल सकते हैं, _जैसे_: ```bash SEEKER=cmp bash ddexec.sh ls -l <<< $(base64 -w0 /bin/ls) ``` यदि आप स्क्रिप्ट में लागू नहीं किए गए किसी अन्य मान्य seeker को पाते हैं, तो आप इसे `SEEKER_ARGS` वेरिएबल सेट करके अभी भी उपयोग कर सकते हैं: ```bash SEEKER=xxd SEEKER_ARGS='-s $offset' zsh ddexec.sh ls -l <<< $(base64 -w0 /bin/ls) ``` इसको ब्लॉक करें, EDRs। ## संदर्भ - [https://github.com/arget13/DDexec](https://github.com/arget13/DDexec) {{#include ../../../banners/hacktricks-training.md}}