Summary
NOTE: There are undergoing reports regarding the command injection when executing the batch file, and several programming languages are coordinating the disclosure date. If you decide to not consider this as a vulnerability, please do not disclose this behavior until the end of February. If the coordinated disclosure is needed, please let me know.
Due to the improper handling of command line arguments on Windows, maliciously crafted arguments can inject arbitrary commands even if the bypass_shell
option is enabled.
Details
proc_open
executes external commands passed via its arguments. The documentation of this function states the following:
As of PHP 7.4.0, the command may be passed as an array of command parameters. In this case, the process will be opened directly (without going through a shell) and PHP will take care of any necessary argument escaping.
bypass_shell (windows only): bypass cmd.exe shell when set to true
However, when executing .bat
or .cmd
files, CreateProcess
implicitly spawns cmd.exe
, resulting in command line arguments being parsed in cmd.exe
despite the documentation explicitly stating it doesn't spawn the shell.
While proc_open
tries to escape the arguments, command prompts will not recognize \
as the escape character. So, the following command line argument will spawn calc.exe
:
PoC
- Save the following file as
test.bat
.
- Save the following file as
test.php
<?php
$descriptorspec = [STDIN, STDOUT, STDOUT];
$proc = proc_open(["test.bat", "\"¬epad.exe"], $descriptorspec, $pipes);
proc_close($proc);
- Run it with PHP and confirm that
notepad.exe
is executed.
Alternatively, you can use the following PHP file to confirm that the bypass_shell
option doesn't prevent this behavior.
<?php
$descriptorspec = [STDIN, STDOUT, STDOUT];
$proc = proc_open(["test.bat", "\"¬epad.exe"], $descriptorspec, $pipes, null, null, array("bypass_shell" => true));
proc_close($proc);
Impact
This vulnerability allows malicious command line arguments to execute arbitrary commands if it's passed to .bat
or .cmd
through proc_open
.
Since command line arguments are not expected to be parsed via the shell, it allows unexpected code execution.
Summary
NOTE: There are undergoing reports regarding the command injection when executing the batch file, and several programming languages are coordinating the disclosure date. If you decide to not consider this as a vulnerability, please do not disclose this behavior until the end of February. If the coordinated disclosure is needed, please let me know.
Due to the improper handling of command line arguments on Windows, maliciously crafted arguments can inject arbitrary commands even if the
bypass_shell
option is enabled.Details
proc_open
executes external commands passed via its arguments. The documentation of this function states the following:However, when executing
.bat
or.cmd
files,CreateProcess
implicitly spawnscmd.exe
, resulting in command line arguments being parsed incmd.exe
despite the documentation explicitly stating it doesn't spawn the shell.While
proc_open
tries to escape the arguments, command prompts will not recognize\
as the escape character. So, the following command line argument will spawncalc.exe
:PoC
test.bat
.echo hello
test.php
notepad.exe
is executed.Alternatively, you can use the following PHP file to confirm that the
bypass_shell
option doesn't prevent this behavior.Impact
This vulnerability allows malicious command line arguments to execute arbitrary commands if it's passed to
.bat
or.cmd
throughproc_open
.Since command line arguments are not expected to be parsed via the shell, it allows unexpected code execution.