
CVE-2025-49132 के लिए प्रूफ-ऑफ-कॉन्सेप्ट शोषण, जो Pterodactyl Panel <= 1.11.10 में locale पैरामीटर इंजेक्शन के माध्यम से अप्रमाणित दूरस्थ कोड निष्पादन को सक्षम करता है। इसमें जाँच और शोषण मोड शामिल हैं।
CVE-2025-49132 के लिए प्रूफ-ऑफ-कॉन्सेप्ट, Pterodactyl Panel <= 1.11.10 में रिमोट कोड एक्सेक्यूशन हेतु
यह PoC निम्नलिखित स्रोतों से संदर्भ लेता है:
# जांचें कि क्या वेब एप्लिकेशन असुरक्षित है
python3 poc.py -u <url> -m check
# कुछ मजेदार करें
python3 poc.py -u <url> -m exploit -p <path_to_pear_dir> -t <path_to_write_to>
LocaleController.php के git diff का विश्लेषण करने पर (v1.11.10 और v1.11.11 के बीच, लिंक), हम देख सकते हैं कि कंट्रोलर locale और namespace पैरामीटर्स को बिना किसी सत्यापन या स्वच्छता (validation/sanitization) के स्वीकार करता है।
यह समझने के लिए कि यह खतरनाक क्यों है, हम panel/routes/base.php में कॉन्फ़िगर किए गए रूटिंग को देखेंगे। रूट स्पष्ट रूप से प्रमाणीकरण-संबंधित मिडलवेयर को हटा देता है, जिससे अप्रमाणित उपयोगकर्ता /locales/locale.json को कॉल कर सकते हैं और आवश्यक क्वेरी पैरामीटर्स जैसे locale और namespace प्रदान कर सकते हैं। इसका मतलब है कि ये पैरामीटर अब उपयोगकर्ता द्वारा नियंत्रित हैं।
Route::get('/locales/locale.json', Base\LocaleController::class)
// इस एंडपॉइंट के लिए प्रमाणीकरण मिडलवेयर हटाएं
->withoutMiddleware(['auth', RequireTwoFactorAuthentication::class]);
अब LocalController.php पर वापस आते हैं, निम्नलिखित कोड की पंक्ति RCE का जादू प्रदान करती है।
$this->loader->load($locale, str_replace('.', '/', $namespace))
load फ़ंक्शन Laravel के अनुवाद ढाँचे से आता है (यहाँ):
public function load($locale, $group, $namespace = null) # 1
{
if ($group === '*' && $namespace === '*') { # 2
return $this->loadJsonPaths($locale);
}
if (is_null($namespace) || $namespace === '*') { # 3
return $this->loadPaths($this->paths, $locale, $group); # 4
}
return $this->loadNamespaced($locale, $group, $namespace);
}
load फ़ंक्शन 3 तर्क लेता है। पहली बार में भ्रमित करने वाला, वास्तव में str_replace('.', '/', $namespace) का मान दूसरे तर्क $group को दिया जाता है।$namespace कभी * नहीं होगा क्योंकि यह हमेशा NULL रहेगा। इसी तरह $group कभी * नहीं होगा क्योंकि हम यहाँ जो पास किया जाता है उसे नियंत्रित कर सकते हैं।$namespace null है, शाखा ली जाएगी जिसके परिणामस्वरूप #4 में loadPaths का निष्पादन होगा।उपरोक्त को समझने के बाद, हम loadPaths के विश्लेषण पर आगे बढ़ते हैं, जहाँ वास्तविक जादू होता है:
protected function loadPaths(array $paths, $locale, $group)
{
return (new Collection($paths))
->reduce(function ($output, $path) use ($locale, $group) {
if ($this->files->exists($full = "{$path}/{$locale}/{$group}.php")) { # 1
$output = array_replace_recursive($output, $this->files->getRequire($full)); # 2
}
return $output;
}, []);
}
.php जोड़कर बनाता है।getRequire() के माध्यम से लोड किया जाता है, जो PHP फ़ाइल को निष्पादित करता है और उसकी सरणी लौटाता है।चूँकि हम namespace URL पैरामीटर को नियंत्रित करते हैं, हम प्रभावित कर सकते हैं कि एप्लिकेशन किस फ़ाइल को लोड करने का प्रयास करता है। एक मान प्रदान करके जो .php स्क्रिप्ट से मैप होता है, हम सर्वर को उस स्क्रिप्ट को निष्पादित करवा सकते हैं। उदाहरण के लिए, phpinfo.php लोड करने के लिए, हम पैरामीटर को इस प्रकार सेट कर सकते हैं: namespace=phpinfo
PoC pearcmd.php के माध्यम से मनमाना फ़ाइल लिखने का प्रयास करता है। इस विधि का उपयोग कई समान PoCs और सुरक्षा अनुसंधानों में किया गया है:
ध्यान दें कि pearcmd.php विभिन्न निर्देशिकाओं में स्थित हो सकता है, जैसे:
/usr/share/php/pearcmd.php/usr/share/php/PEAR/pearcmd.php/usr/lib/php/pearcmd.phpऔर कई अन्य।
लिखी जाने वाली फ़ाइल में सामान्य दुर्भावनापूर्ण PHP कोड होगा।
केवल अधिकृत परीक्षण के लिए। उन सिस्टम पर उपयोग न करें जिनके आप मालिक नहीं हैं या जिनके परीक्षण की आपको स्पष्ट अनुमति नहीं है।
सभी लागू कानूनों का पालन करने के लिए आप जिम्मेदार हैं; लेखक दुरुपयोग के लिए कोई देयता नहीं मानते।
Python की requests लाइब्रेरी थोड़ी बहुत मददगार है क्योंकि यह प्रदान किए गए URL में वर्णों को एन्कोड करती है। इस समस्या को हल करने में काफी समय बिताया और अंततः सीधे curl का उपयोग करना पड़ा। सराहना होगी यदि कोई इस समस्या में सहायता प्रदान कर सके।