
MISC96 में हमारे लेख से संबंधित स्रोत कोड और कॉन्फ़िगरेशन फ़ाइलें
यह रिपॉजिटरी MISC पत्रिका #96 में प्रकाशित लेख का एक अतिरिक्त हिस्सा है।
हमने SMEP / SMAP और KASLR सक्षम के साथ अपनी वर्चुअल मशीन पर विश्वसनीय तरीके से अपने विशेषाधिकारों को बढ़ाने में सफलता प्राप्त की। हालाँकि, यह ध्यान दिया जाना चाहिए कि सिस्टम अस्थिर स्थिति में छोड़ दिया जाता है और oops होने की बहुत संभावना है।
configs/ फ़ोल्डर में, आपको Linux कर्नेल और Busybox के लिए कॉन्फ़िगरेशन फ़ाइलें मिलेंगी, जिनमें से प्रत्येक डिफ़ॉल्ट फ़ाइलों से थोड़ी अलग है।
binaries/ फ़ोल्डर में वे सभी पहले से निर्मित बाइनरी शामिल हैं जिनकी आपको हमारे परीक्षण वातावरण को पुनः बनाने के लिए आवश्यकता होगी, जैसे कि QEMU के साथ उपयोग के लिए तैयार एक संपूर्ण rootfs।
linux-stable एक git सबमॉड्यूल है जो Linux कर्नेल के एक कमजोर संशोधन की ओर इशारा करता है। इसे प्राप्त करने के लिए git submodule update --recursive का उपयोग करें (यदि आपके सिस्टम पर कम से कम 1GB खाली जगह है...)। busybox के लिए भी यही बात लागू होती है।
हमारा वातावरण एक QEMU x86 वर्चुअल मशीन पर आधारित है जिसमें 9P के माध्यम से होस्ट के साथ साझा किया गया एक फ़ोल्डर है। कर्नेल का एक कमजोर संस्करण (ff33952e4d23) Busybox के स्टैटिकली-लिंक्ड बिल्ड के साथ संकलित किया गया है।
हमारा कॉन्फ़िगरेशन काफी सरल है, क्योंकि हमें किसी भी प्रकार के असामान्य आर्किटेक्चर या हार्डवेयर का समर्थन करने की आवश्यकता नहीं है। इसे make defconfig चलाकर उत्पन्न किया गया था और QEMU के नेटवर्किंग और फ़ोल्डर साझाकरण का समर्थन करने के लिए कुछ सुविधाएँ सक्षम की गई थीं:
CONFIG_BLK_MQ_VIRTIO=y
CONFIG_MEMORY_BALLOON=y
CONFIG_BALLOON_COMPACTION=y
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_NET_9P_DEBUG=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_BLK_SCSI=y
CONFIG_VIRTIO_NET=y
CONFIG_HVC_DRIVER=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_PCI_LEGACY=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
CONFIG_9P_FS=y
CONFIG_9P_FS_POSIX_ACL=y
CONFIG_9P_FS_SECURITY=y
GDB स्क्रिप्ट और डिबगिंग प्रतीक भी पहले PoCs के विकास को आसान बनाने के लिए जोड़े गए थे:
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_GDB_SCRIPTS=y
कृपया ध्यान दें कि इस संस्करण में, KASLR x86 पर डिफ़ॉल्ट रूप से सक्षम है। चूँकि कर्नेल प्रत्येक रीबूट के बाद अलग-अलग पतों पर मैप किया जाता है, GDB प्रतीक फ़ाइल को उससे मेल नहीं खिला पाएगा। फिर आपके पास दो विकल्प हैं: KASLR के बिना परीक्षण करना या GDB में प्रतीक लोड करते समय कर्नेल का आधार पता symbol-file को देना।
इसे संकलित करने के बाद, आपको linux-stable/arch/x86/boot/bzImage में bzImage मिलेगा।
यह फ़ाइल binaries/bzImage में मौजूद है और हमारी कॉन्फ़िगरेशन फ़ाइल confifs/kernel.config में है। इसका उपयोग करने के लिए, आपको बस इसे linux-stable में .config के रूप में कॉपी करना होगा।
हमने Busybox का अंतिम स्थिर संस्करण, 1.28, उपयोग किया। केवल एक सेटिंग बदलनी है: CONFIG_STATIC, इसे y पर सेट करें। इसे संकलित करने में कोई समस्या नहीं आनी चाहिए।
हमारी कॉन्फ़िगरेशन फ़ाइल configs/busybox.config में उपलब्ध है और एक स्टैटिक रूप से संकलित बाइनरी binaries/busybox में। Linux की तरह ही, इसे Busybox के स्रोत फ़ोल्डर में .config के रूप में कॉपी करें।
Busybox पहले से ही एक init प्रक्रिया लागू करता है जो /etc/init.d/rcS को निष्पादित करने का प्रयास करेगी। आमतौर पर, यह आपके वितरण द्वारा प्रदान की जाती है (संभवतः एक अलग नाम के साथ) लेकिन हमें इसे यहाँ स्वयं करना होगा! यह स्क्रिप्ट कई अनिवार्य सिस्टम फ़ोल्डरों (proc, sys, dev) को बनाएगी और माउंट करेगी, होस्ट के साथ साझा किया गया हमारा फ़ोल्डर, और हमें एक विशेषाधिकार रहित शेल में डाल देगी:
for i in $(seq 1 9); do mknod /dev/tty$i c 4 1; done
mknod -m 0666 /dev/null c 1 3
mknod -m 0660 /dev/ttyS0 c 4 64
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs none /dev
mkdir -p /mnt/share
mount -t 9p -o trans=virtio share /mnt/share/ -oversion=9p2000.L,posixacl,sync
chmod 777 /mnt/share/
export ENV=/etc/profile
setsid cttyhack setuidgid 1000 sh
umount /proc
umount /sys
umount /dev
poweroff -f
/etc/profile फ़ाइल अनिवार्य नहीं है लेकिन हमारे परीक्षणों के दौरान काफी उपयोगी है, खासकर जब शोषण विश्वसनीय नहीं था और root विशेषाधिकार प्राप्त करने में कई प्रयास लगे।
शोषण लिखने के पीछे की प्रक्रिया MISC 96 में काफी अच्छी तरह से प्रलेखित है: हम मेमोरी की जांच करने के लिए unsafe_put_user का उपयोग करते हैं जब तक कि हमें heap का आधार पता नहीं मिल जाता। फिर, clone के हजारों कॉल हमें मेमोरी में कई cred संरचनाओं को स्प्रे करने देते हैं। हमारे परीक्षणों के दौरान, मेमोरी में उनकी स्थिति fork का उपयोग करने की तुलना में कहीं अधिक "स्थिर" थी, क्योंकि यह नए कार्य के लिए कम संरचनाएँ आवंटित करता है।
चाइल्ड से बाहर निकलने पर एक दोषपूर्ण पेजिंग अनुरोध के कारण कर्नेल oops होगा, इसे सही ढंग से संभालने की आवश्यकता है।
यदि आप इस शोषण की विश्वसनीयता में सुधार करना चाहते हैं या दस्तावेज़ जोड़ना चाहते हैं, तो योगदान का स्वागत है! हो सकता है कि हमने कुछ अवधारणाओं पर गलतियाँ या अशुद्धियाँ भी की हों, यदि आपको लगता है कि कुछ गलत है तो issue खोलने में संकोच न करें।
Linux कर्नेल
शोषण