
CVE-2024-50340에 대한 개념 증명 익스플로잇으로, 조작된 URL 쿼리 매개변수를 통해 Symfony ArgvInput 환경 변수 주입을 시연하여 APP_ENV 및 APP_DEBUG 조작을 가능하게 합니다.
register_argc_argv 옵션이 PHP 구성 파일(php.ini)에서 활성화되어 있어야 합니다. 이 설정은 명령줄 인수와 쿼리 매개변수를 $_SERVER['argv']에 로드합니다.
https://www.php.net/manual/en/ini.core.php#ini.register-argc-argv
이 Symfony 코드는 입력 인수(ArgvInput)를 사용하여 특정 환경 변수, 특히 APP_ENV와 APP_DEBUG의 값을 결정합니다. Symfony 코드의 관련 부분은 다음과 같습니다:
//Symfony\Component\Runtime\SymfonyRuntime
$input = new ArgvInput();
if (isset($this->options['env'])) {
return $this->input = $input;
}
if (null !== $env = $input->getParameterOption(['--env', '-e'], null, true)) {
putenv($this->options['env_var_name'].'='.$_SERVER[$this->options['env_var_name']] = $_ENV[$this->options['env_var_name']] = $env);
}
if ($input->hasParameterOption('--no-debug', true)) {
putenv($this->options['debug_var_name'].'='.$_SERVER[$this->options['debug_var_name']] = $_ENV[$this->options['debug_var_name']] = '0');
}
위 코드는 ArgvInput을 통해 제공된 인수를 처리합니다. argv에 --env 매개변수가 지정되면 그에 따라 APP_ENV 환경 변수가 업데이트됩니다. 마찬가지로 --no-debug가 있으면 APP_DEBUG를 0으로 설정합니다.
ArgvInput 클래스는 명령줄, 쿼리 매개변수 또는 기본적으로 $_SERVER['argv']에 있는 argv 매개변수를 초기화합니다. array_shift($argv); 함수는 $argv 배열에서 첫 번째 요소(일반적으로 애플리케이션 이름)를 제거하고 나머지 인수를 $this->tokens에 저장합니다.
//Symfony\Component\Console\Input\ArgvInput
public function __construct(?array $argv = null, ?InputDefinition $definition = null)
{
$argv ??= $_SERVER['argv'] ?? [];
// strip the application name
array_shift($argv);
$this->tokens = $argv;
parent::__construct($definition);
}
다음 URL을 사용하여 http://localhost/?+--env=dev 를 통해 $_SERVER['argv']에 --env=dev 인수를 주입할 수 있습니다. 이를 통해 애플리케이션 구성을 직접 수정하지 않고도 APP_ENV 값을 dev로 변경할 수 있습니다.
$_SERVER['argv']는 다음과 같이 보일 수 있습니다:$_SERVER['argv'] = ["+--env=dev"];
$argv는 다음과 같아집니다:$argv = ["--env=dev"];
--env=dev를 유효한 매개변수로 인식하고 getParameterOption 메서드를 통해 APP_ENV를 그에 따라 업데이트합니다.