
Proof-of-Concept-Exploit für CVE-2024-52301, der Umgebungsmanipulation in Laravel über injizierte URL-Parameter demonstriert, mit detaillierter Codeanalyse und Reproduktionsschritten.
Diese Schwachstelle basiert auf der CVE-2024-50340-Schwachstelle
Die register_argc_argv-Option muss in der PHP-Konfigurationsdatei (php.ini) aktiviert sein. Diese Einstellung lädt Befehlszeilenargumente und Abfrageparameter in $_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);
}
Zweck: Diese Methode erkennt die Umgebung, indem sie auf $_SERVER['argv'] zugreift, das die Befehlszeilenargumente enthält, und delegiert dann an die Klasse EnvironmentDetector.
Quelle der Schwachstelle: Durch die Abhängigkeit von $_SERVER['argv'] könnten injizierte URL-Parameter (z. B. ?--env=dev) $_SERVER['argv'] manipulieren, sodass es ["--env=dev"] enthält. Dieses Array wird direkt an detect übergeben, was es einem Angreifer ermöglicht, die Umgebung zu kontrollieren.
//Illuminate\Foundation\EnvironmentDetector
public function detect(Closure $callback, $consoleArgs = null)
{
if ($consoleArgs) {
return $this->detectConsoleEnvironment($callback, $consoleArgs);
}
return $this->detectWebEnvironment($callback);
}
Zweck: Die detect-Methode prüft, ob $consoleArgs (das argv-Array) bereitgestellt wird. Falls vorhanden, ruft sie detectConsoleEnvironment auf, um die konsolenbasierte Umgebungserkennung durchzuführen; andernfalls ruft sie detectWebEnvironment für HTTP-Anfragen auf.
Weg zur Schwachstelle: Wenn $_SERVER['argv'] injizierte Werte wie --env=dev enthält, führt dies zu detectConsoleEnvironment, das die Argumente verarbeitet und die Anwendung in eine andere Umgebung versetzen könnte.
//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);
}
Zweck: Diese Methode prüft, ob das --env-Argument unter den Konsolenargumenten vorhanden ist.
Mechanismus: Sie ruft getEnvironmentArgument auf, um zu sehen, ob eines der argv-Argumente eine Umgebung angibt. Wenn --env bereitgestellt wird, gibt diese Methode den angegebenen Umgebungswert zurück, wodurch der Aufruf von detectWebEnvironment umgangen wird.
//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));
}
}
}
Zweck: Diese Methode parst argv, um das --env-Argument zu finden. Mechanismus:
Wenn --env als eigenständiges Flag gefunden wird, gibt es das nächste Argument als Umgebungswert zurück.
Wenn die Syntax --env= verwendet wird (z. B. --env=dev), extrahiert und gibt es die Umgebung zurück (in diesem Fall dev).
Umgebungskonfiguration:
Die .env-Datei enthält APP_ENV=development, daher ist die Anwendung standardmäßig auf die Entwicklungsumgebung eingestellt.
@production
<p>Production environment</p>
@endproduction
@env ('local')
<p>Local environment</p>
@endenv
Standardzugriff (http://localhost):
Da APP_ENV auf development gesetzt ist und kein --env-Argument injiziert wird, trifft weder die @production- noch die @env('local')-Direktive zu.
Ergebnis: Die Ausgabe ist leer.
Injiziertes Argument für Production (http://localhost?--env=production):
Mit ?--env=production in der URL wird $_SERVER['argv'] manipuliert, sodass es ["--env=production"] enthält.
Dies löst Laravels Umgebungserkennungsmechanismus aus und setzt die Umgebung auf production.
Ergebnis: Die @production-Direktive gibt <p>Production environment</p> aus.
Injiziertes Argument für Local (http://localhost?--env=local):
Mit ?--env=local enthält $_SERVER['argv'] ["--env=local"], wodurch die Umgebung auf local geändert wird.
Ergebnis: Die @env('local')-Direktive gibt <p>Local environment</p> aus
Diese Schwachstelle erlaubt es nicht, die Umgebung innerhalb der config-Funktion zu ändern. Stattdessen betrifft sie nur die Umgebungseinstellung innerhalb der Application-Klasse.
Daher sind Blade-Direktiven und andere Teile des Codes, die auf die Application-Klasse zur Umgebungserkennung angewiesen sind, betroffen, aber der Code, der die config-Funktion verwendet, ist von dieser Schwachstelle nicht betroffen.