发布于1小时前1小时 背景CVE-2024-4577 是 Windows 环境下 PHP-CGI 的参数注入漏洞,主要影响以 CGI 模式运行 PHP 的部署。其根因与 Windows 部分代码页的 Best-Fit 字符转换有关:请求中的软连字符字节可能在转换后变成普通连字符,使 PHP-CGI 将原本不应被识别的输入解析为命令行参数。该问题不是普通 PHP 业务代码漏洞。只有 Windows、PHP-CGI 暴露方式、系统代码页及 Web 服务器映射等条件同时满足时,才可能形成远程代码执行。验证必须在已授权环境进行,并优先使用固定字符串响应,避免执行系统命令或写入文件。影响条件检查项风险条件排查方式操作系统Windows查看主机资产或执行 systeminfoPHP 运行模式CGI/FastCGI,且 php-cgi.exe 可被调用检查 IIS、Apache 配置及进程命令行PHP 版本低于官方修复版本执行 php-cgi.exe -v代码页繁体中文、简体中文、日文等受影响代码页风险较高执行 chcp,并结合区域设置确认入口暴露存在 CGI 映射或可访问的 php-cgi.exe 路径检查 ScriptAlias、Action、Handler Mapping首批修复版本包括 PHP 8.1.29、8.2.20、8.3.8。更老且已结束维护的 PHP 分支不应只做局部缓解,建议直接迁移到当前受支持版本,并以 PHP 官方安全公告中的最新版本为准。问题定位先确认运行模式,不要仅依据响应头中的 PHP 版本作判断。IIS FastCGI、Apache mod_fcgid、Apache Action 映射的配置位置不同,应同时检查服务配置和实际进程。REM 查看 PHP-CGI 版本与系统代码页 C:\php\php-cgi.exe -v chcp REM 查找正在运行的 CGI 进程及命令行 wmic process where "name='php-cgi.exe'" get ProcessId,ParentProcessId,CommandLine REM Apache 配置中检索 CGI 映射 findstr /S /I /N "ScriptAlias Action SetHandler php-cgi.exe mod_fcgid" C:\Apache24\conf\*.conf REM IIS 导出处理程序映射 %windir%\system32\inetsrv\appcmd.exe list config /section:system.webServer/handlers重点关注 Apache 中将 .php 交给 php-cgi.exe 的 Action、ScriptAlias 或 ExecCGI 配置,以及 IIS Handler Mapping 中指向 php-cgi.exe 的映射。如果 php-cgi.exe 所在目录被当作普通静态目录发布,也应视为高风险配置错误。技术分析PHP-CGI 会处理命令行形式的配置参数。正常情况下,PHP 对以连字符开头的查询字符串有防护;但在受影响的 Windows 代码页中,特定字节经过 Best-Fit 转换后可能变成连字符,从而绕过检查。攻击者随后可能注入 allow_url_include、auto_prepend_file 等运行时配置,使请求体在目标 PHP 进程启动阶段被解释。漏洞是否可利用取决于 Web 服务器如何拼接 CGI 参数、请求路径是否到达 PHP-CGI,以及转换发生时使用的代码页。因此,仅扫描版本会产生误报;仅验证某个固定路径又可能漏报。准确结论应由版本、配置和受控动态验证三部分共同支撑。授权验证步骤以下请求仅输出固定标记,不执行系统命令、不落盘。应先在隔离测试环境复现,再对生产目标进行最小化验证。将 URL 替换为实际已确认的 PHP-CGI 映射入口;不同部署不一定存在示例路径。curl -i --path-as-is -X POST ^ " ^ -H "Content-Type: application/x-www-form-urlencoded" ^ --data-binary "<?php header('Content-Type: text/plain'); echo 'CVE-2024-4577-CHECK'; exit; ?>"判断标准如下:响应正文出现唯一标记 CVE-2024-4577-CHECK,说明请求体被 PHP 解释,动态验证成立。返回 404 只能说明该路径不存在,不能据此判定不受影响。返回 403 可能是 WAF 或 Web 服务器规则拦截,仍需核对 PHP 版本和 CGI 映射。返回 PHP 源码、下载响应或 500 错误时,应结合错误日志判断处理链路,避免重复发送探测请求。不要将验证载荷替换为 system、shell_exec、下载器或持久化代码。固定标记已经足以证明参数注入与代码解释能力。日志留痕与取证优先保全原始访问日志,不要先做字符串替换或日志清洗。检索时同时关注原始编码、大小写变化及解码后的参数名。典型线索包括 %AD、allow_url_include、auto_prepend_file、php://input,以及直接访问 php-cgi.exe 的请求。REM Apache 日志快速检索 findstr /S /I /N /C:"%AD" /C:"allow_url_include" /C:"auto_prepend_file" /C:"php-cgi.exe" C:\Apache24\logs\*.log REM IIS 日志检索 findstr /S /I /N /C:"%AD" /C:"allow_url_include" /C:"auto_prepend_file" /C:"php-cgi.exe" C:\inetpub\logs\LogFiles\*.log REM PowerShell 检查近期新增或修改的 PHP 文件 Get-ChildItem C:\inetpub\wwwroot -Recurse -File -Include *.php | Where-Object LastWriteTime -gt (Get-Date).AddDays(-7) | Select-Object FullName,Length,CreationTime,LastWriteTime REM 检查 php-cgi.exe 是否派生异常子进程 Get-CimInstance Win32_Process | Where-Object {$_.Name -match 'cmd.exe|powershell.exe|certutil.exe|bitsadmin.exe'} | Select-Object Name,ProcessId,ParentProcessId,CommandLineIIS 的 cs-uri-query 字段可能记录查询字符串,但不同日志配置可能截断、解码或遗漏内容。还应关联 WAF、反向代理、EDR 和 Windows 进程审计日志。若已启用安全日志中的进程创建事件,可重点检查事件 ID 4688;Sysmon 环境则检查事件 ID 1,并确认父进程是否为 php-cgi.exe、httpd.exe 或 w3wp.exe。发现可疑请求后,应围绕同一源地址、相邻时间窗口和相同 User-Agent 扩展查询,同时检查 Web 根目录、临时目录、计划任务、服务项及账户变更。单纯删除可疑 PHP 文件不足以完成处置。修复与缓解建议升级到 PHP 官方当前受支持的安全版本。至少跨过 8.1.29、8.2.20、8.3.8 对应修复线,升级后重新执行版本与配置核验。不再维护的 PHP 5.x、7.x 和旧 8.x 分支应迁移,不建议继续依赖 WAF 规则维持运行。移除外部可访问的 php-cgi.exe 路径,不要将 PHP 安装目录发布为 Web 目录。复核 Apache ScriptAlias、Action、AddHandler、SetHandler、ExecCGI,以及 IIS Handler Mapping,仅保留业务必需映射。如业务允许,改用更清晰的 FastCGI 部署边界,并限制 Web 服务账户权限,禁止其写入程序目录和系统目录。在反向代理或 WAF 中拦截针对 CGI 参数的异常编码可作为临时措施,但不能替代升级。规则应同时覆盖原始 URI 和规范化 URI,并验证不会被多次解码绕过。修复后重启相关 PHP-CGI、Apache 或 IIS 进程,避免旧进程继续加载旧二进制,并再次执行固定标记验证。修复确认修复验收至少包含四项:PHP 二进制版本已更新;CGI 映射符合最小暴露原则;原验证请求不再返回固定标记;日志与 EDR 中未出现 php-cgi.exe 派生脚本解释器或系统工具的异常链路。若历史日志已经出现成功利用特征,应按入侵事件处理,而不是在升级后直接关闭工单。总结CVE-2024-4577 的排查不能停留在版本扫描。可靠流程是先确认 Windows 与 PHP-CGI 部署条件,再检查处理程序映射和代码页,最后使用无副作用标记完成授权验证。处置时既要升级 PHP,也要收敛 CGI 暴露面,并通过访问日志、进程审计和文件时间线判断漏洞是否已被利用。 服务器、云资产与权限边界梳理示意 漏洞成因、验证条件与修复闭环示意
35分钟前35分钟 这个漏洞的排查重点不应只放在“能否复现”,还要同时确认部署方式、原始请求参数和 php-cgi.exe 的后续进程行为。CVE-2024-4577 主要影响 Windows 下以 CGI 模式运行 PHP 的场景,尤其与 Windows 字符集的 best-fit 转换有关;仅凭服务器安装了 PHP,不能直接判断存在风险。 1. 先确认是否处于受影响链路 检查 PHP 版本和 SAPI: php -v php -i | findstr /I "Server API" where php where php-cgi 重点查 Web 服务配置中是否把请求交给 php-cgi.exe,例如 Apache 的 Action、ScriptAlias、SetHandler,或者 IIS 的 Handler Mapping: findstr /S /I /N "php-cgi.exe ScriptAlias Action SetHandler" C:\Apache24\conf\*.conf C:\Apache24\conf\extra\*.conf %windir%\system32\inetsrv\appcmd list config /section:system.webServer/handlers 如果使用的是 PHP-FPM、Apache module,或者 PHP 根本不在 Windows 上运行,通常不属于该漏洞的直接利用路径,但仍应核实反向代理后端的实际部署。 2. 版本修复 应至少升级到已修复版本:PHP 8.1.29、8.2.20、8.3.8;更老且已停止维护的分支不要继续通过规则“续命”,建议直接迁移到当前受支持版本。升级后注意确认 Web 服务实际加载的是新目录中的二进制,而不是只更新了命令行环境变量: where php (Get-Command php).Source (Get-Item "C:\path\to\php-cgi.exe").VersionInfo | Format-List FileVersion,ProductVersion 修改后重启对应服务,再通过 Web 页面输出的 PHP_VERSION 和 PHP_SAPI 复核,避免 CLI 与 Web 使用不同版本。 3. 日志取证建议 访问日志中建议同时搜索编码后的软连字符字节、PHP 命令行参数特征,以及重复编码形式。不要只搜索明文 -d,因为代理、WAF 和 Web 服务记录 URL 的解码阶段可能不同。 PowerShell 可先做一轮粗筛: $patterns = '%AD','%ad','%25AD','%25ad','-d','auto_prepend_file', 'allow_url_include','php://input','php://filter' Get-ChildItem C:\inetpub\logs\LogFiles,C:\Apache24\logs -Recurse -File -ErrorAction SilentlyContinue | Select-String -SimpleMatch -Pattern $patterns | Select-Object Path,LineNumber,Line IIS W3C 日志重点看 date、time、c-ip、cs-uri-stem、cs-uri-query、sc-status、sc-bytes 和 time-taken。如果日志字段没有记录查询字符串,需结合反向代理、WAF、负载均衡器或流量留存补齐证据。Apache 则确认 LogFormat 中使用了 %r 或 %q,否则可能无法还原参数。 命中可疑请求后,不要仅以 HTTP 200 判断利用成功。更关键的是检查同一时间窗口内是否出现由 php-cgi.exe 派生的命令解释器、下载工具或脚本宿主: $start = (Get-Date).AddDays(-7) Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4688; StartTime=$start} | Where-Object { $_.Message -match 'php-cgi\.exe|cmd\.exe|powershell\.exe|pwsh\.exe|certutil\.exe|bitsadmin\.exe|mshta\.exe|rundll32\.exe' } | Select-Object TimeCreated,Id,Message 如果部署了 Sysmon,优先查 Event ID 1,并关联 ParentImage 为 php-cgi.exe 的事件: Get-WinEvent -FilterHashtable @{ LogName='Microsoft-Windows-Sysmon/Operational' Id=1 StartTime=(Get-Date).AddDays(-7) } | Where-Object { $_.Message -match 'ParentImage:.*\\php-cgi\.exe' } | Select-Object TimeCreated,Message 还应检查 PowerShell 4104、计划任务、服务创建及常见落地目录: Get-WinEvent -FilterHashtable @{ LogName='Microsoft-Windows-PowerShell/Operational' Id=4104 StartTime=(Get-Date).AddDays(-7) } -ErrorAction SilentlyContinue schtasks /query /fo LIST /v sc.exe query type= service state= all Get-ChildItem C:\Windows\Temp,$env:TEMP,C:\inetpub\wwwroot -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } | Sort-Object LastWriteTime -Descending | Select-Object LastWriteTime,Length,FullName 如果已经发现异常子进程或文件落地,应按失陷主机处理:先隔离网络,保存 IIS/Apache、Security、Sysmon、PowerShell 日志和可疑文件哈希,再进行清理。只删除 WebShell 或升级 PHP,不能排除凭据、计划任务和服务已被持久化。 4. 临时缓解不能代替升级 在无法立即升级时,可以暂时下线 CGI 映射,限制外部访问,或在最前端按原始请求目标拦截相关编码和异常参数。但需要注意:不同组件对 URL 的解码次数不同,单纯针对已解码参数写规则可能被双重编码绕过。因此规则应部署在最靠前、能够检查 raw URI 的位置,并同时记录命中日志。 长期方案仍是升级 PHP,并尽量避免在 Windows 上使用传统 CGI 映射。修复完成后建议保留一段时间的检测规则,重点告警“外部请求命中 PHP CGI 参数特征”以及“Web/PHP 进程派生命令解释器”这两类事件,后者对判断是否已执行成功更有价值。
创建帐户或登录后发表意见