
Linux LPE - विश्वसनीय Jail/Container Escape
CentOS / RHEL 10 के लिए एक विश्वसनीय विशेषाधिकार-रहित कंटेनर / जेल एस्केप प्रमाण-अवधारणा।
यह __ip6_append_data() में एक अब ठीक किए गए IPv6 विखंडन बग का उपयोग करता है (ऊपरधारा द्वारा 38becddc में बंद, कोई CVE नहीं), एक इन-स्लैब रैखिक ओवरफ्लो जो पैकेट के अपने हेड ऑब्जेक्ट के पूंछ पर skb_shared_info में होता है। यह README केवल शोषण श्रृंखला का दस्तावेजीकरण करता है। यह ट्रिगर को कवर नहीं करता है।
6.12.0-242.el10)।यह एक प्रमाण-अवधारणा है, जानबूझकर एक टर्नकी हथियार नहीं। विश्वसनीयता मचान जानबूझकर छोड़ दिया गया है: कोई प्रति-सीपीयू PCP ग्रूमिंग नहीं, कोई क्रॉस-कैश SLUB कवच नहीं, और skb हेड को एक साझा, बहुत शांत नहीं कैश में रखा गया है। जो शिप होता है वह श्रृंखला को साबित करने के लिए पर्याप्त बार फायर करता है, और इससे अधिक नहीं। यह केवल CentOS / RHEL 10 तक सीमित है।
CONFIG_INIT_ON_ALLOC_DEFAULT_ON बंद, RHEL / CentOS डिफ़ॉल्ट। यह PoC अप्रारंभीकृत स्लैब बाइट्स में एक बासी पॉइंटर लगाता है; init_on_alloc=1 के साथ वह स्लॉट शून्य हो जाता है और यह विशेष तकनीक केवल कर्नेल को क्रैश करती है (एक NULL डीरेफ़)। यह तकनीक की एक सीमा है, बग की नहीं: एक पूर्ण शोषण जो उन कर्नेल को भी कवर करता है, एक अलग तकनीक के साथ, एक बार सुधार और CVE सार्वजनिक होने के बाद आएगा।/sys/kernel/btf/vmlinux मौजूद और विश्व-पठनीय (RHEL / CentOS पर स्टॉक)।| वितरण | कर्नेल | परिणाम |
|---|---|---|
| CentOS Stream 10 | 6.12.0-242.el10 | रूट, कंटेनर एस्केप |
| RHEL 10 | 6.12.0-228.el10 | httpd_t कॉन्टेक्स्ट एस्केप |
इन-स्लैब ओवरफ्लो से स्व-यूएएफ। बग skb_shared_info में एकल nr_frags बाइट पर नियंत्रण देता है। मुक्त पथ (skb_release_data()) frags[0 .. nr_frags) को चलता है और प्रत्येक प्रविष्टि पर put_page() करता है, और frags[] कभी प्रारंभ नहीं होता है। हम नियंत्रित कैश पुन: उपयोग के माध्यम से उस स्लैब स्लॉट में पाइप बफर पेज के लिए एक struct page * पहले से लगाते हैं, फिर nr_frags को 1 पर सेट करते हैं, ताकि टियरडाउन एक पेज पर एक संदर्भ छोड़ दे जो हमारे पास अभी भी है। रैखिक ओवरफ्लो एक पेज उपयोग-के-बाद-मुक्त बन जाता है। ओवरफ्लो कभी frags[0] को नहीं छूता, इसलिए इसे स्प्रे के विरुद्ध समयबद्ध करने की आवश्यकता नहीं है, जो इसे क्षमाशील बनाता है।
पेज यूएएफ से डर्टी-पेजटेबल। मुक्त पाइप पेज को एक ताजा अनाम मैपिंग को फॉल्ट करके अंतिम-स्तरीय पृष्ठ तालिका के रूप में पुनः प्राप्त किया जाता है। एक भौतिक पेज अब एक लाइव लीफ पृष्ठ तालिका और वह पेज दोनों है जिसे पाइप अभी भी पढ़ता और लिखता है। पाइप पर आठ बाइट्स लिखने से एक जाली PTE स्थापित होता है; पाइप पढ़ने से तालिका वापस पढ़ी जाती है। यह एक सीमित मनमाना भौतिक पढ़ना/लिखना है, प्रति तालिका लगभग 460 PTE विंडो के क्रम में।
KASLR को पराजित करें। भौतिक पढ़ने के साथ हम निश्चित निम्न-मेमोरी SMP ट्रैम्पोलिन पृष्ठ तालिका को स्कैन करते हैं, जिसे KASLR कभी स्थानांतरित नहीं करता; इसका कर्नेल आधा प्रविष्टि , कर्नेल के भौतिक आधार पर इंगित करता है। वहाँ से (अपनी स्व-संदर्भित प्रविष्टि 511 द्वारा पहचानने योग्य) एक सार्वभौमिक वर्चुअल से भौतिक अनुवादक है, जो कर्नेल वर्चुअल बेस को पुनर्प्राप्त करता है और हमारे पता स्थान को भौतिक मेमोरी से जोड़ता है।
level4_kernel_pgtinit_top_pgtसीमित से अनंत पढ़ना/लिखना। हम लीफ तालिका में एक PTE बनाते हैं जो तालिका के अपने भौतिक पते पर इंगित करता है। मेल खाने वाली वर्चुअल विंडो तब पृष्ठ तालिका को ही उपनाम देती है, इसलिए PTEs सादा मेमोरी बन जाते हैं: असीमित, रैंडम एक्सेस कर्नेल पढ़ना/लिखना, लूप में कोई पाइप नहीं। रिंग 3 TLB सुसंगतता को एक अतिरिक्त बड़े mprotect() के साथ पूर्ण mm फ्लश को मजबूर करके संभाला जाता है।
ऑफसेट हल करें और क्रेडेंशियल लें। स्ट्रक्ट सदस्य ऑफसेट रनटाइम पर /sys/kernel/btf/vmlinux से पढ़े जाते हैं, बेक्ड इन नहीं। हम अपना स्वयं का task_struct vmemmap struct page वॉक और mm_struct.owner के माध्यम से ढूंढते हैं, क्रेडेंशियल आईडी को शून्य करते हैं, और cred और real_cred पर सभी क्षमता सेट भरते हैं। प्रतीक पते एक आंतरिक रिज़ॉल्वर से आते हैं जो हमारे मनमाने पढ़ने के माध्यम से कर्नेल के स्वयं के kallsyms तालिकाओं को पार्स करता है; केवल यदि वह विफल होता है तो हम cred.user_ns को init_user_ns पर इंगित करने (ताकि CAP_SYSLOG प्रारंभिक नामस्थान में धारण करता है) और /proc/kallsyms से वास्तविक पते पढ़ने पर वापस आते हैं।
SELinux को लागू किए बिना अक्षम करें। हम avc_denied() के प्रस्तावना को xor eax, eax ; ret स्टब (IBT के तहत endbr64 पर कदम रखते हुए) से ओवरराइट करते हैं। अब हर इनकार प्रक्रिया-व्यापी स्वीकृत लौटाता है, जबकि getenforce अभी भी Enforcing की रिपोर्ट करता है। यह एस्केप के लिए एक शर्त भी है: कोर-डंप हैंडलर का क्रॉस डोमेन पुन: निष्पादन अन्यथा अस्वीकार कर दिया जाएगा।
core_pattern के माध्यम से एस्केप। हम वैश्विक core_pattern को /proc/<PID>/root (क्रैश होने वाले कार्य के कंटेनर chroot) के माध्यम से अपने स्वयं के बाइनरी पर इंगित | उपसर्ग वाले हैंडलर के साथ ओवरराइट करते हैं, फिर एक चाइल्ड को क्रैश करते हैं। कर्नेल हैंडलर को usermodehelper के रूप में चलाता है, प्रारंभिक नामस्थानों में रूट, और हम कंटेनर के अंदर बाध्य एक Unix सॉकेट पर एक इंटरैक्टिव रूट शेल को रिले करते हैं। हैंडलर init नामस्थानों के अंदर पैदा होता है, इसलिए इन-प्लेस नामस्थान सर्जरी की आवश्यकता नहीं है, और न ही इसके PID-नामस्थान खतरों में से कोई।