是,PHP 8.1.28 在 Windows 上启用 php-cgi 且使用简体中文(936)、繁体中文(950)或日文(932)代码页时,因Windows Best-Fit字符转换特性被绕过CVE-2012-1823防护,可触发参数注入导致远程代码执行。

PHP 8.1.28 在 Windows 上启用 php-cgi 就可能中招
PHP 8.1.28 明确落在 CVE-2024-4577 的影响范围内(8.1 ),只要运行在 Windows、且满足以下任意一项,漏洞就具备可利用基础:
- 使用 Apache +
php-cgi.exe模式(例如通过Action或SetHandler application/x-httpd-php-cgi配置) - 直接将
php-cgi.exe或php.exe暴露在 Web 可访问路径下(如/cgi-bin/php-cgi.exe或ScriptAlias /php-cgi/ "C:/xampp/php/") - 系统区域设置为简体中文(代码页 936)、繁体中文(950)或日文(932)——这是触发 Best-Fit 编码转换的关键前提
%AD 字符绕过 php-cgi 参数过滤的原理
漏洞本质不是 PHP 主动解析错误,而是 Windows API 在把命令行参数从当前代码页转成 UTF-16 时,把 %AD(即字节 0xAD)映射成了 ASCII 短横线 -。而 PHP 的 CGI 模块在解析参数前,只检查了 ASCII 范围内的 -,没拦住高位字节经 Best-Fit 转换后的结果。
所以攻击者用 %ADd+allow_url_include%3d1,实际被 Windows 转成 -d allow_url_include=1,成功注入 PHP 运行时配置。
-
%AD不是 URL 编码的“合法字符”,但 Windows 的MultiByteToWideChar默认启用 Best-Fit,会强行把它映射成- - PHP 原本的过滤逻辑(如
is_valid_arg)只检查0x00–0x7F,对0x80+字节不设防 - 这个绕过和
CVE-2012-1823的防护机制冲突,导致双重防护形同虚设
真实请求中必须同时满足的三个硬性条件
缺一不可,否则即使版本符合也打不通:
立即学习“PHP免费学习笔记(深入)”;
- HTTP 方法必须是
POST(GET 请求无法携带原始 body,而漏洞依赖php://input) - URL 中需包含 CGI 参数注入链,典型形式:
/php-cgi/php-cgi.exe?%ADd+cgi.force_redirect%3d0+%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input - 请求头必须带
Content-Type: application/x-www-form-urlencoded,且 body 是纯 PHP 代码(如<?php phpinfo(); ?>),不能套 form 表单或加其他字段
为什么 XAMPP 默认安装就危险
因为 XAMPP 8.1.25(含 PHP 8.1.25)及多数旧版默认开启 ScriptAlias /php-cgi/,且 Windows 中文系统自带代码页 936,无需额外配置就满足全部利用条件。
更麻烦的是:Apache 日志里根本不会记录 %AD —— 它在进入 Apache 前就被 Windows 内核转义了,所以攻击流量在 access.log 中显示为普通短横线,很难靠日志回溯。
别指望 WAF 或 ModSecurity 自动拦截:它看到的是 -d,不是 %ADd,而 -d 本身是合法 CGI 参数。真正可靠的只有两件事:升级到 8.1.29+,或者彻底禁用 php-cgi 暴露。



















