Advisory: CVE-2024-4577 By Orange Tsai (DEVCORE Threat Research)
⚡ Verified PoC Code

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 %AD in 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:

c
// 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:

http
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=1 INI 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

1
Apply Official PHP Patches:

Upgrade to PHP 8.3.8, PHP 8.2.20, or PHP 8.1.29.

2
Apache Rewrite Rule Workaround:

If upgrading is delayed, add a mod_rewrite rule to block requests containing the soft-hyphen byte:

apache
RewriteEngine On

RewriteCond %{QUERY_STRING} ^(%ad|%AD) [NC]

RewriteRule .* - [F,L]
3
Migrate from CGI: Migrate production Windows deployments to FastCGI (mod_fcgid) or PHP-FPM where arguments are not passed via process command lines.