
CVE-2022-0492 Linux कर्नेल कंटेनर एस्केप का विस्तृत तकनीकी विश्लेषण और कार्यशील एक्सप्लॉइट, जो cgroup release_agent के माध्यम से होता है, साथ ही चरण-दर-चरण लैब सेटअप और शमन मार्गदर्शन।
[toc]
भेद्यता आईडी: CVE-2022-0492
भेद्यता उत्पाद: linux kernel - cgroup
प्रभावित संस्करण: ~linux kernel 5.17-rc3
भेद्यता प्रभाव: जब कंटेनर में अतिरिक्त सुरक्षा उपाय सक्षम नहीं होते हैं, तो कंटेनर के अंदर root विशेषाधिकार प्राप्त करके होस्ट में एस्केप किया जा सकता है।
भेद्यता वाले संस्करण के कर्नेल वाले linux में docker का उपयोग करना पर्याप्त है।
#关闭所有安全防护启动docker
docker run --rm -it -h cve --name cve --security-opt="seccomp=unconfined" --security-opt="apparmor=unconfined" ubuntu:20.04 /bin/bash
इस लेख में प्रयोगात्मक वातावरण के रूप में docker का उपयोग किया गया है।
इस भेद्यता का शोषण तरीका पहले से ही पुराना परिचित है, लेकिन भेद्यता का मूल बिंदु cgroup के release_agent को संशोधित करने में अनुमति सत्यापन की कमी है, जिससे एस्केप शोषण की सीमा और कम हो गई है (पहले CAP_SYS_ADMIN अनुमति की आवश्यकता थी, इस भेद्यता को CAP_SYS_ADMIN की आवश्यकता नहीं है)। विशिष्ट शोषण शर्तों में अंतर के लिए नीचे "उपयोग की शर्तें" देखें।
पैच का विश्लेषण करने पर, cgroup_release_agent_write फ़ंक्शन को पैच किया गया और प्रमाणीकरण जोड़ा गया। इसका मतलब है कि cgroup के release_agent को अब बिना अनुमति वाले उपयोगकर्ताओं द्वारा संशोधित नहीं किया जा सकता:

इसलिए यह निर्धारित किया गया है कि यह भेद्यता विफल एक्सेस नियंत्रण (broken access control) है।
cgroup अर्थात Linux Control Group, Linux कर्नेल की एक क्षमता है, जिसका उपयोग प्रक्रिया समूहों के संसाधनों (जैसे CPU, मेमोरी, डिस्क इनपुट/आउटपुट आदि) को सीमित, नियंत्रित और अलग करने के लिए किया जाता है।
cgroup में निम्नलिखित उपप्रणालियाँ हैं:
devices प्रक्रिया-स्तरीय डिवाइस अनुमतियाँcpuset प्रक्रियाओं द्वारा उपयोग किए जा सकने वाले CPU और मेमोरी नोड्स आवंटित करता हैcpu CPU उपयोग दर नियंत्रित करता हैcpuacct CPU उपयोग आँकड़े, जैसे रन टाइम, थ्रॉटल समयfreezer Cgroup में प्रक्रियाओं को रोकता हैnet_cls tc (traffic controller) के साथ मिलकर नेटवर्क बैंडविड्थ सीमित करता हैnet_prio प्रक्रियाओं के नेटवर्क ट्रैफ़िक प्राथमिकता सेट करता हैhuge_tlb HugeTLB के उपयोग को सीमित करता हैperf_event Perf टूल को Cgroup समूहों के आधार पर प्रदर्शन परीक्षण करने की अनुमति देता हैहोस्ट में सभी cgroup /sys/fs/cgroup के अंतर्गत होते हैं, और विभिन्न cgroup उपप्रणालियों को देखा जा सकता है:

docker में संबंधित cgroup उपप्रणाली होस्ट में उस cgroup का चाइल्ड नोड है। docker में memory cgroup देखें:

होस्ट के docker निर्देशिका में संबंधित कंटेनर नाम नोड बिल्कुल समान है:

cgroup का उपयोग फ़ाइल सिस्टम के रूप में किया जाता है। mount के माध्यम से cgroup को एक निर्देशिका में माउंट किया जाता है। cgroup VFS वर्चुअल फ़ाइल सिस्टम के माध्यम से हमारे साथ इंटरैक्ट करता है। cgroup के इंटरफ़ेस फ़ाइलों के रूप में प्रस्तुत होते हैं, और फ़ाइल संचालन विधियों का उपयोग करके cgroup के लिए कुछ पैरामीटर सेट किए जा सकते हैं।
mount -t cgroup -o memory cgroup /tmp/testcgroup

निर्देशिका में उपनिर्देशिका बनाकर cgroup चाइल्ड नोड बनाया जा सकता है: mkdir /tmp/testcgroup/x।
cgroup के प्रत्येक subsystem में notify_on_release पैरामीटर होता है। यह पैरामीटर मान Boolean प्रकार का होता है, 1 या 0। यह क्रमशः रिलीज़ एजेंट निर्देश को सक्षम और अक्षम कर सकता है। यदि notify_on_release सक्षम (1) है, जब cgroup में कोई कार्य नहीं होता है (अर्थात जब cgroup में अंतिम प्रक्रिया बाहर निकलती है, और cgroup की tasks फ़ाइल में PID खाली होता है), तो कर्नेल release_agent पैरामीटर द्वारा निर्दिष्ट फ़ाइल की सामग्री निष्पादित करेगा। notify_on_release फ़ाइल को संशोधित करके notify_on_release का मान बदला जाता है।

भेद्यता release_agent के संशोधन में है। मूल रूप से, जब तक कोई cgroup को संचालित कर सकता था, release_agent को संशोधित किया जा सकता था, और cgroup का उपयोग करने के लिए CAP_SYS_ADMIN की आवश्यकता होती थी। लेकिन बाद में शोधकर्ताओं ने पाया कि unshare कमांड के माध्यम से नया namespace बनाने पर सभी capabilities प्राप्त हो सकती हैं, इसलिए CAP_SYS_ADMIN की सीमा समाप्त हो गई, और भेद्यता के शोषण की सीमा बहुत कम हो गई।
unshare कमांड का कार्य निर्दिष्ट शेयर्ड पैरेंट प्रक्रिया में निर्दिष्ट namespace को रद्द करना है, फिर निर्दिष्ट प्रोग्राम को निष्पादित करना और नव निर्मित namespace में शामिल होना है। हमारे भेद्यता शोषण से संबंधित महत्वपूर्ण बात यह है कि unshare द्वारा नव निर्मित namespace में CAP_SYS_ADMIN सहित सभी capabilities होती हैं।

इस भेद्यता का शोषण पारंपरिक CAP_SYS_ADMIN + cgroup release_agent एस्केप विधि के समान है, लेकिन शोषण की शर्तों में अंतर है।
भेद्यता शोषण की शर्तें और पारंपरिक release_agent एस्केप की शर्तों के बीच अंतर:
पारंपरिक release_agent: कंटेनर के पास CAP_SYS_ADMIN होना चाहिए और apparmor, selinux सक्षम नहीं होना चाहिए।
cve-2022-0492: कंटेनर बिना किसी सुरक्षा के (अधिक विशेष रूप से, seccomp unshare को अक्षम नहीं करता, apparmor cgroup को केवल-पढ़ने के लिए सक्षम नहीं करता, selinux बंद है), और कंटेनर के अंदर root विशेषाधिकार प्राप्त करना। CAP_SYS_ADMIN प्राप्त करने की आवश्यकता नहीं है।
उल्लेखनीय है कि docker का apparmor डिफ़ॉल्ट रूप से cgroup को केवल-पढ़ने के लिए सक्षम करता है, और docker का seccomp डिफ़ॉल्ट रूप से गैर-CAP_SYS_ADMIN अनुमति के तहत unshare को अक्षम करता है। k8s डिफ़ॉल्ट रूप से आमतौर पर बिना सुरक्षा वाले कंटेनर होते हैं। कुल मिलाकर, क्योंकि शोषण अपेक्षाकृत आसान है, आप विशिष्ट परिदृश्यों में इसे आज़मा सकते हैं।
भेद्यता ठीक होने के बाद: पैच के कोड के अनुसार:

release_agent फ़ाइल को संशोधित करने के लिए दो शर्तों को पूरा करना आवश्यक है:
इसलिए भेद्यता ठीक होने के बाद, unshare के माध्यम से प्राप्त CAP_SYS_ADMIN अनुमति अब release_agent को संशोधित नहीं कर सकती, क्योंकि unshare द्वारा प्राप्त नया namespace रूट namespace नहीं है। लेकिन यदि कंटेनर में पहले से ही CAP_SYS_ADMIN अनुमति है, तो इस विधि का उपयोग करके एस्केप जारी रखा जा सकता है।
यदि docker स्टार्टअप में --cap-add=SYS_ADMIN पैरामीटर या --privileged (विशेषाधिकार प्राप्त कंटेनर) है, तो CAP_SYS_ADMIN अनुमति पहले से मौजूद होती है और हमें इसे अतिरिक्त रूप से प्राप्त करने की आवश्यकता नहीं होती है, जैसे निम्नलिखित स्टार्टअप कमांड:
#带有sys_admin 启动docker, 关闭apparmor(否则无法mount)
docker run --rm -it --cap-add=SYS_ADMIN --security-opt="apparmor=unconfined" ubuntu:20.04 /bin/bash
CAP_SYS_ADMIN अनुमति वाले docker सीधे अगले चरण "release_agent संशोधित करें" पर जा सकते हैं। बिना CAP_SYS_ADMIN अनुमति वाले docker को शुरू करने और भेद्यता को दोहराने का कमांड: