
स्थानीय Docker लैब जो CVE-2026-39987 को पुनः प्रस्तुत करती है, जो marimo के टर्मिनल WebSocket में एक प्री-ऑथ RCE है। शैक्षिक सुरक्षा अनुसंधान के लिए न्यूनतम-हानि PoC स्क्रिप्ट के साथ कमजोर और पैच किए गए संस्करणों की तुलना करती है।
marimo में CVE-2026-39987 को पुन: उत्पन्न करने और समझने के लिए केवल-लोकल Docker लैब। यह प्रोजेक्ट एक कमजोर marimo सेवा की तुलना एक पैच किए गए marimo सेवा से साथ-साथ करता है, फिर न्यूनतम-हानि प्रूफ स्क्रिप्ट का उपयोग करके अंतर प्रदर्शित करता है।
CVE-2026-39987 marimo, एक रिएक्टिव Python नोटबुक फ्रेमवर्क, में एक गंभीर प्री-ऑथेंटिकेशन रिमोट कोड एक्ज़ीक्यूशन भेद्यता है।
कमजोर व्यवहार टर्मिनल WebSocket एंडपॉइंट में मौजूद है:
/terminal/ws
प्रभावित संस्करणों में, इस एंडपॉइंट तक वैध प्रमाणीकरण के बिना पहुंचा जा सकता है और यह एक इंटरैक्टिव टर्मिनल सत्र बना सकता है। एक अनप्रमाणित हमलावर जो कमजोर marimo एडिट सर्वर तक पहुंच सकता है, वह marimo प्रक्रिया के विशेषाधिकारों के साथ कमांड निष्पादित कर सकता है।
यह लैब एक नियंत्रित स्थानीय Docker वातावरण में भेद्यता को पुन: उत्पन्न करता है:
| सेवा | संस्करण | URL | अपेक्षित व्यवहार |
|---|---|---|---|
vuln | marimo 0.20.4 | http://127.0.0.1:8081 | /terminal/ws अनप्रमाणित WebSocket कनेक्शन स्वीकार करता है |
patched | marimo 0.23.0 | http://127.0.0.1:8082 | /terminal/ws अनप्रमाणित WebSocket कनेक्शन को 403 Forbidden के साथ अस्वीकार करता है |
लक्ष्य एक हथियारबंद एक्सप्लॉइट प्रदान करना नहीं है। लक्ष्य केवल-लोकल, पुनरुत्पादनीय साक्ष्य का उपयोग करके कमजोर और पैच किए गए संस्करणों के बीच अवलोकन योग्य सुरक्षा अंतर दिखाना है।
प्रभावित घटक marimo का टर्मिनल WebSocket एंडपॉइंट है:
/terminal/ws
यह एंडपॉइंट marimo के एडिट वातावरण द्वारा ब्राउज़र-कनेक्टेड WebSocket सत्र के माध्यम से टर्मिनल कार्यक्षमता प्रदान करने के लिए उपयोग किया जाता है।
कमजोर एंडपॉइंट ने संरक्षित marimo एडिट कार्यक्षमता के लिए अपेक्षित समान प्रमाणीकरण जांच लागू किए बिना WebSocket कनेक्शन स्वीकार किए।
महत्वपूर्ण अंतर है:
कमजोर व्यवहार:
अनप्रमाणित क्लाइंट /terminal/ws से कनेक्ट कर सकता है
टर्मिनल सत्र बनाया जाता है
WebSocket के माध्यम से कमांड भेजे जा सकते हैं
पैच किया गया व्यवहार:
अनप्रमाणित क्लाइंट को अस्वीकार कर दिया जाता है
WebSocket हैंडशेक 403 Forbidden के साथ विफल हो जाता है
टर्मिनल सत्र नहीं बनाया जाता है
पैच टर्मिनल सत्र स्थापित होने से पहले टर्मिनल WebSocket प्रवाह में प्रमाणीकरण सत्यापन जोड़ता है।
यदि एक कमजोर marimo एडिट सर्वर एक पहुंच योग्य नेटवर्क पर उजागर होता है, तो एक अनप्रमाणित हमलावर marimo प्रक्रिया चलाने वाले उपयोगकर्ता के रूप में कमांड निष्पादित कर सकता है।
इस लैब में, marimo प्रक्रिया जानबूझकर कम-विशेषाधिकार वाले गैर-रूट उपयोगकर्ता के रूप में चलाई जाती है:
uid=10001(marimo) gid=10001(marimo) groups=10001(marimo)
यह प्रदर्शन को सुरक्षित रखता है जबकि भेद्यता को साबित करता है।
यह लैब तीन चीजें साबित करने के लिए डिज़ाइन किया गया है:
/terminal/ws के लिए अनप्रमाणित WebSocket कनेक्शन स्वीकार करता है।403 Forbidden के साथ अस्वीकार करता है।लैब जानबूझकर विनाशकारी कमांड, पर्सिस्टेंस, रिवर्स शेल, क्रेडेंशियल डंपिंग, या किसी भी इंटरनेट-फेसिंग लक्ष्य से बचता है।
.
├── docker-compose.yml
├── vuln/
│ ├── Dockerfile
│ └── notebook.py
├── patched/
│ ├── Dockerfile
│ └── notebook.py
├── poc/
│ ├── poc.py
│ ├── rce_poc.py
│ └── requirements.txt
├── SAFETY.md
├── README.md
└── .gitignore
होस्ट मशीन
127.0.0.1:8081 ─────► vuln कंटेनर
marimo 0.20.4
/terminal/ws अनप्रमाणित WebSocket स्वीकार करता है
127.0.0.1:8082 ─────► patched कंटेनर
marimo 0.23.0
/terminal/ws अनप्रमाणित WebSocket अस्वीकार करता है
दोनों सेवाएं marimo के आंतरिक पोर्ट 2718 को उजागर करती हैं, लेकिन होस्ट पोर्ट अलग हैं:
vuln -> 127.0.0.1:8081
patched -> 127.0.0.1:8082
सेवाएं केवल 127.0.0.1 से बंधी हैं। वे LAN या इंटरनेट पर उजागर होने के लिए नहीं हैं।
कंटेनरों को जहां संभव हो कई सुरक्षा गार्डरेल के साथ कॉन्फ़िगर किया गया है:
- पोर्ट को केवल 127.0.0.1 से बांधें
- गैर-रूट उपयोगकर्ता के रूप में चलाएं
- Linux क्षमताओं को हटाएं
- no-new-privileges सक्षम करें
- केवल-पठनीय रूट फाइलसिस्टम का उपयोग करें
- केवल सीमित tmpfs लेखन स्थान प्रदान करें
- सेवाओं को एक समर्पित Docker ब्रिज नेटवर्क के अंदर अलग करें
ये नियंत्रण कमजोर सेवा से भेद्यता को नहीं हटाते हैं। वे स्थानीय प्रदर्शन के विस्फोट त्रिज्या को कम करते हैं।
परीक्षण की गई धारणाएं:
- Docker Desktop के साथ Linux x86_64 या macOS
- Docker Compose v2
- Python 3.9+
- केवल-लोकलहोस्ट परीक्षण
आवश्यक उपकरण:
docker --version
docker compose version
python3 --version
प्रोजेक्ट निर्देशिका में क्लोन करें या प्रवेश करें:
cd cve-2026-39987
दोनों सेवाओं का निर्माण और प्रारंभ करें:
docker compose up -d --build
जांचें कि दोनों कंटेनर चल रहे हैं:
docker compose ps
अपेक्षित सेवाएं:
cve-2026-39987-vuln
cve-2026-39987-patched
कमजोर सेवा संस्करण जांचें:
docker compose exec vuln marimo --version
अपेक्षित:
0.20.4
पैच किए गए सेवा संस्करण जांचें:
docker compose exec patched marimo --version
अपेक्षित:
0.23.0
Python वर्चुअल वातावरण बनाएं:
python3 -m venv .venv
source .venv/bin/activate
निर्भरताएं स्थापित करें:
python -m pip install -r poc/requirements.txt
प्राथमिक प्रूफ स्क्रिप्ट है:
poc/poc.py
यह कनेक्ट करने का प्रयास करता है:
/terminal/ws
फिर यह केवल हानिरहित प्रूफ कमांड भेजता है:
id
whoami
hostname
कोई रिवर्स शेल, फ़ाइल लेखन, पर्सिस्टेंस, क्रेडेंशियल एक्सेस, या विनाशकारी कमांड का उपयोग नहीं किया जाता है।
चलाएं:
python poc/poc.py --base-url http://127.0.0.1:8081
अपेक्षित परिणाम:
[*] Target WebSocket: ws://127.0.0.1:8081/terminal/ws
[*] Sending benign proof command only: id; whoami; hostname
[+] websocket connected without credentials
[result] VULNERABLE: unauthenticated command execution observed
[proof]
uid=10001(marimo) gid=10001(marimo) groups=10001(marimo)
marimo
<container-hostname>
यदि स्क्रिप्ट कच्चा टर्मिनल आउटपुट प्रिंट करती है लेकिन इस ब्लॉक को शामिल करती है, तो भेद्यता अभी भी पुष्टि की गई है:
CVE39987_PROOF_START
uid=10001(marimo) gid=10001(marimo) groups=10001(marimo)
marimo
<container-hostname>
CVE39987_PROOF_END
इसका मतलब है कि WebSocket कनेक्शन सफल हुआ और कमांड आउटपुट टर्मिनल सत्र से वापस आया।
चलाएं:
python poc/poc.py --base-url http://127.0.0.1:8082
अपेक्षित परिणाम:
[*] Target WebSocket: ws://127.0.0.1:8082/terminal/ws
[*] Sending benign proof command only: id; whoami; hostname
[-] websocket connection rejected/failed: Handshake status 403 Forbidden
[result] not exploitable by this unauthenticated check
यह दर्शाता है कि पैच किया गया सेवा टर्मिनल सत्र बनाने से पहले अनप्रमाणित पहुंच को अस्वीकार कर देता है।
नीचे दी गई फ़ाइल केवल स्थानीय सीखने के लिए है:
poc/rce_poc.py
यह कमजोर टर्मिनल WebSocket से कनेक्ट होकर और टर्मिनल इंटरैक्शन की अनुमति देकर उसी मुद्दे को अधिक रीयल-टाइम तरीके से प्रदर्शित करता है।
इसका उपयोग केवल स्थानीय Docker लैब के खिलाफ करें।
python poc/rce_poc.py --base-url http://127.0.0.1:8081
अपेक्षित व्यवहार:
[+] Connected successfully (Pre-Auth RCE)
✓ Interactive shell is ready to use!
आज़माने के लिए सुरक्षित कमांड:
id
whoami
hostname
pwd
python -c 'import marimo; print(marimo.__version__)'
exit
python poc/rce_poc.py --base-url http://127.0.0.1:8082
अपेक्षित व्यवहार:
[-] Connection Failed: 403 Forbidden
[!] This is likely the PATCHED version.
The WebSocket endpoint is now protected.
रीयल-टाइम क्लाइंट यह समझने में मदद करने के लिए मौजूद है कि कमजोर WebSocket कैसे व्यवहार करता है। इसका उपयोग इस स्थानीय लैब के बाहर किसी भी सिस्टम के खिलाफ नहीं किया जाना चाहिए।
पोर्टफोलियो प्रकाशन के लिए, अनुशंसित प्राथमिक साक्ष्य अभी भी poc/poc.py है, क्योंकि यह सीमित, दोहराने योग्य और न्यूनतम-हानि है।
मुख्य लैब परिणाम को इस प्रकार सारांशित किया जाना चाहिए:
vuln / marimo 0.20.4:
/terminal/ws के लिए अनप्रमाणित WebSocket हैंडशेक सफल होता है
हानिरहित कमांड आउटपुट अवलोकन योग्य है
patched / marimo 0.23.0:
/terminal/ws के लिए अनप्रमाणित WebSocket हैंडशेक विफल हो जाता है
सर्वर 403 Forbidden लौटाता है
कोई टर्मिनल सत्र नहीं बनाया जाता है
यह CVE पुनरुत्पादन के लिए मुख्य प्रमाण है।
यदि आप व्यवहार को मैन्युअल रूप से निरीक्षण करना चाहते हैं, तो WebSocket-सक्षम क्लाइंट का उपयोग करें और कनेक्ट करें:
ws://127.0.0.1:8081/terminal/ws
ws://127.0.0.1:8082/terminal/ws
अपेक्षित:
8081 -> कनेक्शन स्वीकृत
8082 -> 403 Forbidden
PoC स्क्रिप्ट्स को प्राथमिकता दी जाती है क्योंकि वे स्पष्ट साक्ष्य उत्पन्न करती हैं।
वास्तविक वातावरण में, उपयोगी संकेतक शामिल हैं:
- /terminal/ws के लिए WebSocket अनुरोध
- marimo एडिट सर्वर तक अनप्रमाणित पहुंच प्रयास
- marimo द्वारा उत्पन्न अप्रत्याशित टर्मिनल सत्र
- marimo प्रक्रिया द्वारा लॉन्च किए गए कमांड
- .env, SSH कुंजियों, क्लाउड क्रेडेंशियल्स, या नोटबुक रहस्यों तक पहुंच
- /terminal/ws कनेक्शन के तुरंत बाद आउटबाउंड नेटवर्क ट्रैफ़िक
निरीक्षण के लिए उदाहरण स्थानीय आर्टिफैक्ट:
docker compose logs vuln
docker compose logs patched
docker compose ps
docker compose exec vuln ps aux
कंटेनरों को रोकें और हटाएं:
docker compose down
वॉल्यूम भी हटाएं:
docker compose down -v
यदि चाहें तो स्थानीय Python वर्चुअल वातावरण हटाएं:
rm -rf .venv
यह रिपॉजिटरी केवल स्थानीय सुरक्षा अनुसंधान और पोर्टफोलियो प्रदर्शन के लिए है।
अनुमत:
- लोकलहोस्ट परीक्षण
- केवल-Docker पुनरुत्पादन
- id, whoami, hostname जैसे हानिरहित प्रूफ कमांड
- कमजोर और पैच किए गए व्यवहार की तुलना
- मूल कारण और पहचान विचारों का दस्तावेजीकरण
अनुमति नहीं:
- सार्वजनिक marimo सर्वर के खिलाफ परीक्षण
- उन सिस्टमों का परीक्षण जिनके आप मालिक नहीं हैं या प्रशासित नहीं करते हैं
- रिवर्स शेल
- पर्सिस्टेंस
- क्रेडेंशियल चोरी
- विनाशकारी कमांड
- पार्श्व गति
- बॉटनेट या मैलवेयर व्यवहार
यह प्रोजेक्ट केवल अधिकृत स्थानीय परीक्षण और रक्षात्मक सुरक्षा शिक्षा के लिए है। इन स्क्रिप्ट्स का उपयोग उन सिस्टमों के खिलाफ न करें जिनके आप मालिक नहीं हैं या जिनके परीक्षण की स्पष्ट अनुमति नहीं है।
GitHub सुरक्षा सलाह — GHSA-2679-6mx9-h9xc:
https://github.com/advisories/GHSA-2679-6mx9-h9xc
NVD — CVE-2026-39987:
https://nvd.nist.gov/vuln/detail/CVE-2026-39987
marimo अपस्ट्रीम रिपॉजिटरी:
https://github.com/marimo-team/marimo
पैच कमिट — टर्मिनल WebSocket में प्रमाणीकरण सत्यापन जोड़ें:
https://github.com/marimo-team/marimo/commit/c24d4806398f30be6b12acd6c60d1d7c68cfd12a
पैच PR — marimo PR #9098:
https://github.com/marimo-team/marimo/pull/9098
| फ़ाइल | उद्देश्य |
|---|
docker-compose.yml | कमजोर और पैच किए गए marimo सेवाओं को परिभाषित करता है |
vuln/Dockerfile | कमजोर marimo सेवा का निर्माण करता है |
patched/Dockerfile | पैच किए गए marimo सेवा का निर्माण करता है |
vuln/notebook.py | कमजोर सेवा द्वारा उपयोग की जाने वाली न्यूनतम marimo नोटबुक फ़ाइल |
patched/notebook.py | पैच किए गए सेवा द्वारा उपयोग की जाने वाली न्यूनतम marimo नोटबुक फ़ाइल |
poc/poc.py | न्यूनतम-हानि प्रूफ स्क्रिप्ट जो केवल हानिरहित कमांड चलाती है |
poc/rce_poc.py | स्थानीय लैब में टर्मिनल व्यवहार देखने के लिए रीयल-टाइम लर्निंग क्लाइंट |
poc/requirements.txt | PoC स्क्रिप्ट्स के लिए Python निर्भरताएं |
SAFETY.md | सुरक्षा नियम और दायरे की सीमाएं |