
CVE-2024-52301 के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, जो Laravel में इंजेक्टेड URL पैरामीटर्स के माध्यम से एनवायरनमेंट मैनिपुलेशन को प्रदर्शित करता है, विस्तृत कोड विश्लेषण और पुनरुत्पादन चरणों के साथ।
यह भेद्यता CVE-2024-50340 भेद्यता पर आधारित है।
register_argc_argv विकल्प को PHP कॉन्फ़िगरेशन फ़ाइल (php.ini) में सक्षम होना चाहिए। यह सेटिंग कमांड-लाइन तर्कों और क्वेरी पैरामीटर को $_SERVER['argv'] में लोड करती है।
https://www.php.net/manual/en/ini.core.php#ini.register-argc-argv
//Illuminate\Foundation\Application
public function detectEnvironment (Closure $callback)
{
$args = $_SERVER['argv'] ?? null;
return $this['env'] = (new EnvironmentDetector)->detect($callback, $args);
}
उद्देश्य: यह विधि $_SERVER['argv'] तक पहुँचकर वातावरण का पता लगाती है, जिसमें कमांड-लाइन तर्क होते हैं, और फिर इसे EnvironmentDetector वर्ग को सौंप देती है।
भेद्यता स्रोत: $_SERVER['argv'] पर निर्भर रहने से, कोई भी इंजेक्टेड URL पैरामीटर (जैसे, ?--env=dev) $_SERVER['argv'] को ["--env=dev"] शामिल करने के लिए हेरफेर कर सकता है। यह सरणी सीधे detect को भेजी जाती है, जिससे संभावित रूप से हमलावर को वातावरण को नियंत्रित करने की अनुमति मिलती है।
//Illuminate\Foundation\EnvironmentDetector
public function detect(Closure $callback, $consoleArgs = null)
{
if ($consoleArgs) {
return $this->detectConsoleEnvironment($callback, $consoleArgs);
}
return $this->detectWebEnvironment($callback);
}
उद्देश्य: detect विधि यह निर्धारित करती है कि $consoleArgs (argv सरणी) प्रदान की गई है या नहीं। यदि मौजूद है, तो यह कंसोल-आधारित पर्यावरण पहचान को संभालने के लिए detectConsoleEnvironment को कॉल करती है; अन्यथा, यह HTTP अनुरोधों के लिए detectWebEnvironment को कॉल करती है।
भेद्यता का मार्ग: यदि $_SERVER['argv'] में --env=dev जैसे इंजेक्टेड मान शामिल हैं, तो यह detectConsoleEnvironment की ओर ले जाता है, जो तर्कों को संसाधित करता है और एप्लिकेशन को एक अलग वातावरण में स्विच कर सकता है।
//Illuminate\Foundation\EnvironmentDetector
protected function detectConsoleEnvironment(Closure $callback, array $args)
{
// First we will check if an environment argument was passed via console arguments
// and if it was that automatically overrides as the environment. Otherwise, we
// will check the environment as a "web" request like a typical HTTP request.
if (! is_null($value = $this->getEnvironmentArgument($args))) {
return $value;
}
return $this->detectWebEnvironment($callback);
}
उद्देश्य: यह विधि जाँचती है कि कंसोल तर्कों में --env तर्क मौजूद है या नहीं।
तंत्र: यह देखने के लिए getEnvironmentArgument को कॉल करता है कि क्या argv तर्कों में से कोई वातावरण निर्दिष्ट करता है। यदि --env प्रदान किया गया है, तो यह विधि निर्दिष्ट वातावरण मान लौटाती है, detectWebEnvironment कॉल को दरकिनार करते हुए।
//Illuminate\Foundation\EnvironmentDetector
protected function getEnvironmentArgument(array $args)
{
foreach ($args as $i => $value) {
if ($value === '--env') {
return $args[$i + 1] ?? null;
}
if (str_starts_with($value, '--env=')) {
return head(array_slice(explode('=', $value), 1));
}
}
}
उद्देश्य: यह विधि --env तर्क खोजने के लिए argv को पार्स करती है। तंत्र:
यदि --env एक स्टैंडअलोन फ्लैग के रूप में पाया जाता है, तो यह अगले तर्क को वातावरण मान के रूप में लौटाता है।
यदि --env= सिंटैक्स का उपयोग किया जाता है (जैसे, --env=dev), तो यह वातावरण (इस मामले में dev) निकालता है और लौटाता है।
पर्यावरण कॉन्फ़िगरेशन:
.env फ़ाइल में APP_ENV=development है, इसलिए डिफ़ॉल्ट रूप से, एप्लिकेशन विकास पर्यावरण पर सेट है।
@production
<p>Production environment</p>
@endproduction
@env ('local')
<p>Local environment</p>
@endenv
डिफ़ॉल्ट एक्सेस (http://localhost):
चूंकि APP_ENV development पर सेट है और कोई --env तर्क इंजेक्ट नहीं किया गया है, न तो @production और न ही @env('local') निर्देश मेल खाता है।
परिणाम: आउटपुट खाली है।
उत्पादन के लिए इंजेक्टेड तर्क (http://localhost?--env=production):
URL में ?--env=production के साथ, $_SERVER['argv'] को ["--env=production"] शामिल करने के लिए हेरफेर किया जाता है।
यह Laravel के पर्यावरण पहचान तंत्र को ट्रिगर करता है, पर्यावरण को उत्पादन पर सेट करता है।
परिणाम: @production निर्देश <p>Production environment</p> आउटपुट करता है।
स्थानीय के लिए इंजेक्टेड तर्क (http://localhost?--env=local):
?--env=local के साथ, $_SERVER['argv'] में ["--env=local"] शामिल है, जो पर्यावरण को स्थानीय में बदल देता है।
परिणाम: @env('local') निर्देश <p>Local environment</p> आउटपुट करता है
यह भेद्यता config फ़ंक्शन के भीतर पर्यावरण को बदलने की अनुमति नहीं देती है। इसके बजाय, यह केवल Application वर्ग के भीतर पर्यावरण सेटिंग को प्रभावित करती है।
इस प्रकार, यद्यपि Blade निर्देश और कोड के अन्य भाग पर्यावरण का पता लगाने के लिए Application वर्ग पर निर्भर करते हैं, config फ़ंक्शन का उपयोग करने वाला कोड इस भेद्यता से प्रभावित नहीं होता है।