
Linux ELF x32/x64 ASLR DEP/NX बायपास एक्सप्लॉइट स्टैक-स्प्रेइंग के साथ
Linux ELF x32/x64 ASLR DEP/NX बाईपास एक्सप्लॉइट जिसमें स्टैक-स्प्रेइंग है

गुण:
निर्भरताएँ:
सीमाएँ:
आपने हीप स्प्रेइंग हमले के बारे में सुना होगा? खैर, स्टैक स्प्रेइंग समान है, हालाँकि, इसे अधिकांश मामलों के लिए अव्यावहारिक माना जाता था, विशेष रूप से x86-64 पर ASLR के लिए।
मेरा काम इसके विपरीत साबित करेगा।
32-बिट के लिए, सैद्धांतिक रूप से 2^32 (4 294 967 296) पते हैं, फिर भी, कर्नेल वर्चुअलाइज्ड मेमोरी में निष्पादन के लिए केवल लगभग आधे बिट्स (2^(32/2) = 65 536) को नियंत्रित करने की अनुमति देगा, जिसका अर्थ है कि यदि हम स्टैक में 50,000 से अधिक वर्णों को नियंत्रित करते हैं, तो हम लगभग निश्चित रूप से अपने शेलकोड की ओर इशारा कर सकते हैं, चाहे पता कुछ भी हो, कर्नेल पुनर्निर्देशन और पुनर्अनुवाद के लिए धन्यवाद। मेरे परीक्षणों के अनुसार, यहाँ तक कि 100 या 10 वर्ण भी पर्याप्त हैं यदि कॉल किए गए फ़ंक्शन में अन्य वेरिएबल निर्माण शामिल नहीं हैं, जो ROP-शैली के हमले की अनुमति देगा।
यह शेल वेरिएबल्स का उपयोग करके प्राप्त किया जा सकता है, जो वास्तव में किसी विशिष्ट लंबाई तक सीमित नहीं हैं, लेकिन व्यावहारिक सीमा लगभग एक लाख है, अन्यथा यह TTY को संतृप्त कर देगा।
इसलिए, किसी भी शेलकोड के साथ सफलतापूर्वक शोषण करने के लिए, हमें शेलकोड के बाद एक NOP स्लेज को एक शेल वेरिएबल में रखना होगा और बस एक यादृच्छिक पते के साथ बाइनरी का शोषण करना होगा। ध्यान दें कि NOP स्लेज आवश्यक नहीं है, यह केवल शोषण को सार्वभौमिक बनाने के लिए है।
64-बिट सिस्टम में स्थिति अलग है, लेकिन मेरी खोज के अनुसार इतनी अधिक नहीं।
बेशक, आपको सभी 2^64 संभावनाओं को कवर करने की आवश्यकता नहीं होगी, वास्तव में, कर्नेल केवल 48 बिट्स की अनुमति देता है, साथ ही उनमें से एक भाग पूर्वानुमानित और स्थिर है, जो हमें लगभग 2^(4x8+5) (137 438 953 472) संभावनाओं के साथ छोड़ देता है।
मैंने शेल वेरिएबल्स की आकार सीमा का उल्लेख किया है, लेकिन एक गणना सीमा भी है, जो लगभग 10 प्रतीत होती है, इस प्रकार हमें 1,000,000 वर्णों के शेलकोड को स्टोक करने की अनुमति मिलती है, जिससे हमारे पास केवल कुछ दस हज़ार संभावनाएं बचती हैं जिनका तेज़ी से और स्वचालित रूप से परीक्षण किया जा सकता है। हालाँकि, इस बार, चीजों को तेज़ करने के लिए आपको ब्रूटफोर्स करना होगा और NOP-स्लेज का उपयोग करना होगा।
ऐसा कहने के बाद, 32 और 64-बिट दोनों पर ASLR को कुछ ही मिनटों में और शेल की कुछ पंक्तियों के साथ आसानी से बायपास किया जा सकता है...
दूसरी ओर, DEP/NX, x32 पर return-to-libc तकनीक का उपयोग करके विभिन्न OS के सांख्यिकीय अध्ययनों, विशेष रूप से उनकी ASLR सीमाओं और कार्यान्वयनों के साथ जोड़कर बायपास किया जा सकता है, जो 2 कारणों से एक सफल शोषण की ओर ले जा सकता है। पहला कारण यह है कि ASLR अपनी पसंद में इतना यादृच्छिक नहीं है और इसमें कुछ स्थिरांक और कम एन्ट्रॉपी है (लिबC पते का अनुमान लगाना आसान है और प्रत्येक OS के अपने स्थिरांक होते हैं)। दूसरा कारण लिबC के लिए शेल तर्क को पर्यावरण में स्प्रे करना है (इसे ढूंढना और लिबC को पास करना आसान है)।
निष्कर्ष के तौर पर, 32-बिट्स पर DEP/NX ASLR के कारण कमजोर हो जाता है।
एक अधिक विस्तृत विवरण Hakin9-12-14 अंक में पाया जा सकता है।
यदि आपने अपने जीवन में कम से कम एक बफर ओवरफ्लो का शोषण किया है, तो आप इसे छोड़ सकते हैं, लेकिन बस मामले में:
apt install gcc libc6-dev-i386 || kill -9 $$
chmod u+x ASLRay.sh
sudo gcc -z execstack test.c -o test
sudo gcc -m32 -z execstack test.c -o test32
sudo chmod +s test test32
source ASLRay.sh test32 1024
source ASLRay.sh test 1024
source ASLRay.sh test 1024 \x31\x80...your_shellcode_here
sudo gcc -m32 test.c -o test32x
sudo chmod +s test test32
source ASLRay.sh test32x 1024
यह साबित करने के लिए कि Debian x32 के लिए NOP-स्लेज आवश्यक नहीं है:
!!! चेतावनी !!! यह आपकी /etc/passwd को संशोधित करेगा और /etc/shadow की अनुमतियाँ बदल देगा, VM निष्पादन की सलाह दी जाती है
chmod u+x PoC.sh
source PoC.sh
grep ALI /etc/passwd
यदि यह अभी भी काम नहीं करता है, तो शुरुआत में कुछ NOP (\x90) जोड़ें।
यह साबित करने के लिए कि Debian x32 के लिए पर्यावरणीय चर भी आवश्यक नहीं है:
chmod u+x PoC2.sh
source PoC2.sh
इस प्रकार आप बस अपने शेलकोड को एक वेरिएबल में रख सकते हैं और ASLR के साथ शेल के लिए रजिस्टरों को यादृच्छिक पते दे सकते हैं, ऐसा इसलिए है क्योंकि विशिष्ट संदर्भ जहाँ फ़ंक्शन में केवल एक वेरिएबल है जिसे फिर से लिखा जाएगा, इसलिए स्टैक को EIP पर केवल हमारे शेलकोड के साथ पॉप किया जाएगा, जो ROP हमले की तरह अधिक है।
Arch/Ubuntu के लिए आपको स्टैक स्मैशिंग प्रोटेक्शन को भी अक्षम करना होगा और ब्रूट-फोर्स में अधिक समय लग सकता है (निष्पादन में देरी, संभवतः brk(NULL/0) syscall या/और कैनरी के कारण):
sudo gcc -z execstack -fno-stack-protector test.c -o test
sudo gcc -m32 -z execstack -fno-stack-protector test.c -o test32
sudo gcc -m32 -fno-stack-protector test.c -o test32x
Debian 10 में, यह समस्या आंशिक रूप से ठीक कर दी गई थी, विशेष रूप से AppArmor के कारण।
हमेशा एकल सुरक्षा के बजाय कई सुरक्षाओं पर भरोसा करें।
हमें नए सिस्टम सुरक्षा तंत्रों की आवश्यकता है।
"जहाँ से हम खड़े हैं, बारिश यादृच्छिक लगती है। यदि हम कहीं और खड़े हो सकते, तो हम उसमें क्रम देख पाते।"
टोनी हिलरमैन, कोयोट वेट्स