1. 先找到真正处理请求的 PHP
核对站点绑定的 PHP、Web 服务器模块或 FPM 池。多版本共存、多个站点、容器和负载均衡节点需要分别盘点。命令行 php -v 只说明当前 CLI 版本,不能代表网站正在使用的版本;不要为此公开暴露 phpinfo 页面。
php -v 输入你拥有或获授权测试的网址,逐项查看 PHP 特征、版本线索和表单请求响应,辅助判断 PHP2Shell 暴露风险与后续修复方向。
2
PHP 核心漏洞
9.2
CVSS v4.0 评分(严重)
4
8.2–8.5 的上游修复分支
漏洞概览
PHP2Shell 是 CVE-2026-109618 与 CVE-2026-109619 两项 PHP 核心内存安全漏洞的统称,均被评为 CVSS v4.0 9.2 分。攻击者无需登录就可能触发远程代码执行,具体影响取决于版本、运行方式和触发路径。
内存耗尽处理中的内存损坏可能导致未经认证的远程代码执行,需要通过PHP升级或厂商补丁修复。
阅读详细说明失效的请求全局状态可能被同一worker中的后续请求复用,造成内存安全问题并导致远程代码执行。
阅读详细说明核对实际Web运行时、完整软件包版本与厂商公告,并在更新后重启相关worker。临时缓解措施不能替代补丁。
阅读详细说明PHP-FPM、Apache mod_php、php-cgi、FrankenPHP 和 LiteSpeed 等提供 Web 请求的 PHP 环境都应纳入清单。PHP 官方认为 mod_php 风险最高,已演示的攻击可在应用代码运行之前触发。即使页面简单、应用代码没有已知漏洞,也不能排除风险。
仅更新 WordPress、Drupal、框架或插件,不等于已更新它们使用的 PHP。需要分别检查网站绑定的 PHP 版本、FPM 池、容器镜像、多个服务节点,以及管理面板或设备中内嵌的 PHP。官方修复版本已于 2026 年 10 月 21 日发布。
检测内容
查看公开响应中的PHP特征。
响应头是线索,不是修复证明。
结合对照请求理解状态码差异。
对照完整包版本与厂商公告。
确认所有Web worker已更新并重启。
先获取 GET 基线,再针对三种方法分别发送普通表单和 multipart 表单。每项单独观察响应,再进行下一项;这些普通请求用于比较行为,不包含远程代码执行或内存耗尽载荷。
| 顺序 | 请求方法 | 发送内容 | 观察重点 |
|---|---|---|---|
| 01 | GET | 不带请求体 | 页面是否可访问、重定向、公开的 PHP 版本标识与响应头。 |
| 02 | POST | application/x-www-form-urlencoded | 一个普通文本字段,作为 POST 对照。 |
| 03 | POST | multipart/form-data | 一个文本字段,与 POST 对照比较;不添加文件部分或上传进度字段。 |
| 04 | PUT | application/x-www-form-urlencoded | 一个普通文本字段,观察该路径对 PUT 的处理。 |
| 05 | PUT | multipart/form-data | 与 PUT 普通表单比较内容类型造成的响应差异。 |
| 06 | PATCH | application/x-www-form-urlencoded | 一个普通文本字段,作为 PATCH 对照。 |
| 07 | PATCH | multipart/form-data | 与 PATCH 对照比较,避免只检查 POST 就推断其他方法的行为。 |
X-Powered-By 或 Server 中的 PHP 标识,以及类似 PHPSESSID 的会话 Cookie,只能作为运行环境线索。它们可能被隐藏、改写或自定义;存在 Cookie 也不能证明请求体已被 PHP 解析。
这类检查只覆盖输入的网址与路径。不同路由、CDN 规则和可直接访问的源站可能表现不同;不要把首页的结果推广到整个网站。只在已获授权、适合接受表单请求的路径上检查。
公开版本号达到对应分支的修复起点,是有价值的线索,但响应头可能被代理改写,仍需在服务器上确认所有实例实际加载了修复代码。
低于上游修复版本应优先核查,但发行版和 LTS 厂商可能已经回补补丁。未确认回补状态时应标为待核实,而不是宣称已验证远程代码执行。
普通表单成功而 multipart 返回 4xx,可能与内容类型限制有关;两者都返回 405,也可能只是该路径不支持此方法。仅凭状态码无法区分 CDN、Web 服务器或应用层拒绝。
隐藏版本、代理缓存、自定义 Cookie、连接失败或超时都会限制判断。此时应记录信息不足或未能评估,不能用绿色安全结论代替缺失的证据。
检测流程
填写你拥有或获授权测试的网站地址,明确要核查的网页路径。
先查看 GET 基线,再依次对比 POST、PUT、PATCH 下普通表单与 multipart 请求的响应。
结合状态码与版本线索理解结果,再对照实际 PHP 环境和厂商公告核实补丁状态。
服务器端排查
外部检测适合发现线索,补丁结论仍需在主机、容器或托管面板中确认。建议按以下顺序记录运行环境、软件包来源、修复版本和更新后的进程状态。
核对站点绑定的 PHP、Web 服务器模块或 FPM 池。多版本共存、多个站点、容器和负载均衡节点需要分别盘点。命令行 php -v 只说明当前 CLI 版本,不能代表网站正在使用的版本;不要为此公开暴露 phpinfo 页面。
php -v 按实际系统和安装包名查询版本,再与该发行版的安全公告对照。例如 Ubuntu 24.04 的 8.3.6-0ubuntu0.24.04.13 已包含修复;只看到 PHP 8.3.6 会丢失回补信息。以下是包查询示例,请选择适合系统的一项并替换实际包名。
dpkg-query -W php8.3-fpm
rpm -q php-fpm 查看 Ubuntu 官方修复包清单 使用对应分支的上游修复版、后续安全版本或厂商已确认的回补包。面板、设备和容器自带的 PHP 需按各自供应商方式更新。PHP 8.1 及更早版本已停止常规上游支持,需确认 LTS 厂商修复或迁移;官方此次另提供了 7.4、8.0、8.1 的最小源码回补。
确认相关 PHP-FPM、Apache 或其他 worker 已重启,容器和多节点部署已替换完成,避免磁盘上的包已更新但旧进程仍在服务。检查异常请求、内存耗尽和 worker 崩溃记录可辅助排查,但没有这些日志不代表未受影响。
脚本串行发送 1 次 GET,以及 POST、PUT、PATCH 各两种表单请求,仅使用普通文本字段,不发送文件或上传进度字段。请只对已获授权、适合接受测试表单的路径运行;普通请求仍可能触发应用业务。
#!/usr/bin/env bash
# PHP2Shell HTTP observations: 7 sequential requests, no exploit payload.
set -u
URL="${1:-https://example.com/}"
case "$URL" in
http://*|https://*) ;;
*) printf 'ERROR=HTTP(S)_URL_REQUIRED\n' >&2; exit 2 ;;
esac
if ! command -v curl >/dev/null 2>&1 || ! command -v awk >/dev/null 2>&1; then
printf 'ERROR=CURL_AND_AWK_REQUIRED\n' >&2
exit 127
fi
probe() {
printf '\n[%s/7] %s %s\n' "$1" "$2" "$3"
local method="$2"
shift 3
curl -q --globoff --proto '=http,https' --silent --show-error \
--connect-timeout 5 --max-time 15 --request "$method" \
--dump-header - --output /dev/null \
--write-out '\nHTTP_CODE=%{http_code} TOTAL_SECONDS=%{time_total}\n' \
"$@" --url "$URL" |
awk '{
sub(/\r$/, "")
line = tolower($0)
if ($0 ~ /^HTTP\// || line ~ /^(server|x-powered-by|content-type):/ || $0 ~ /^HTTP_CODE=/) {
print
} else if (line ~ /^set-cookie:[ \t]*phpsessid[ \t]*=/) {
print "PHPSESSID=present; value hidden"
}
}'
local curl_status="${PIPESTATUS[0]}"
if [ "$curl_status" -ne 0 ]; then
printf 'CURL_EXIT=%s\n' "$curl_status"
FAILED=1
fi
}
FAILED=0
probe 1 GET baseline
probe 2 POST urlencoded --data-raw 'php2shell_check=1'
probe 3 POST multipart --form-string 'php2shell_check=1'
probe 4 PUT urlencoded --data-raw 'php2shell_check=1'
probe 5 PUT multipart --form-string 'php2shell_check=1'
probe 6 PATCH urlencoded --data-raw 'php2shell_check=1'
probe 7 PATCH multipart --form-string 'php2shell_check=1'
exit "$FAILED" 脚本适用于 Linux/macOS 的 Bash,以及 Windows 的 WSL 或 Git Bash。保存为 php2shell-self-check.sh,运行下方命令,并将网址换成已获授权的测试页面;不要将整段 Bash 脚本直接粘贴到 PowerShell。
bash php2shell-self-check.sh https://example.com/test.php 连接超时为 5 秒,每项总超时为 15 秒。脚本忽略个人 curl 配置,保留 TLS 校验,不自动跳转或重试;遇到 3xx 时,先确认最终地址仍在授权范围内,再改用该地址运行。PHPSESSID 仅显示存在标记,Cookie 值和响应正文不会输出。
HTTP_CODE 是响应状态,TOTAL_SECONDS 是总耗时;CURL_EXIT 非零表示该项传输失败,脚本仍继续其余检查。脚本最终返回非零表示参数、依赖或传输问题;HTTP 4xx/5xx 会正常记录,退出码不能用来判断漏洞或补丁状态。
Server 或 X-Powered-By 可能隐藏或过期。请核对网站实际运行的 PHP:各分支最低官方修复版本为 8.2.35、8.3.36、8.4.27、8.5.12;厂商回补需结合完整软件包版本和安全公告确认。
同一方法下,urlencoded 返回 2xx 或 3xx,而 multipart 返回 403 或 406,只能说明响应存在差异。不能据此确认 WAF 已拦截,也不能确认请求在进入 PHP 前就被拒绝。
multipart 返回 2xx 或 3xx,仅说明收到了成功响应或跳转响应;不能证明正文进入 PHP 并被解析,也不能据此判断漏洞是否存在。
全部返回 405 不证明已经修复;未见 PHP 标识不等于未使用 PHP;出现 PHPSESSID 也不能确定 multipart 已被解析,或响应来自哪一层。
PHP 官方明确:只有更新才能完整修复,以下配置仅减少部分已知路径的暴露,不应把未打补丁的环境标为安全。修改前应按应用需求和官方公告评估。
官方修复版本
按分支分别比较版本:8.3 的修复线不能用于判定 8.4,预发布版本或未知分支也不应直接视为已修复。发行版回补和自行构建的补丁,应核对完整包版本、构建记录及厂商公告。
升级前请备份网站、数据库及相关配置,并选择合适的维护时间。
登录宝塔面板,进入「软件商店 → 已安装」,找到当前网站正在使用的 PHP 版本,打开其管理页面。
在对应 PHP 管理页面检查可用更新,按提示升级至上方列出的同分支修复版本,或该分支后续安全版本。
升级后重启对应 PHP 服务,确认所有工作进程已重新加载;核对网站实际运行的 PHP 版本,并检查访问、文件上传和数据库连接等业务。
安装了多个 PHP 版本时,请逐一检查仍在使用的版本。若另行安装新版本,还需确认网站已切换到修复后的 PHP 运行时。
FAQ
理解版本线索、状态码与厂商回补的区别,避免过度解读检测结果。
PHP2Shell 指 CVE-2026-109618 与 CVE-2026-109619 两项 PHP 核心漏洞,可能导致未经认证的远程代码执行。所有使用未修复 PHP 处理 Web 请求的环境都应排查,应用代码本身没有漏洞也不能排除风险。
不能。认证要求、不支持的请求方法、体积限制或代理都可能产生这些状态码。即使 multipart 请求被拒绝,也只能说明当前路径的响应表现,不能证明 PHP 已修复或所有攻击路径都被阻断。
不能据此判断。PHP 版本公开可能已关闭,CDN、反向代理或静态首页也可能掩盖后端技术。没有发现特征应视为信息不足,需要进一步核实服务器实际运行环境。
上游修复版本是 PHP 8.2.35、8.3.36、8.4.27、8.5.12,应使用对应分支的修复版或后续安全版本。旧版可能包含厂商回补,应核对完整包版本与厂商公告。PHP 8.1 及更早版本已停止上游常规维护;更新后还需重启相关 worker。
不同方法可能走不同的路由和过滤规则。PHP 8.4 起提供 request_parse_body(),应用可以用它解析非 POST 方法的 multipart 请求;这不代表所有应用都会自动解析 PUT 或 PATCH。因此只观察 POST 的行为,不能推断其他方法或其他路径已经受到保护。
应记录为无法确认 PHP 与补丁状态。POST 的 200 只能说明该路径作出响应,405 只说明某一层拒绝了方法;静态页面、其他后端和隐藏标识的 PHP 都可能出现这种组合。下一步是在服务器核实实际运行环境,而不是直接判定安全或已验证存在漏洞。
漏洞与修复资料核对日期为 2026-10-22。外部观察存在局限,实际处置请以当前 PHP 和对应厂商公告为准。
逐项检查公开响应,结合证据理解风险,再对照服务器实际环境落实补丁与修复。