一个用于检测 PHP 应用程序中 CVE-2026-109618 和 CVE-2026-109619 的命令行工具。
该扫描器会发送一个最小的 multipart 控制请求,随后最多发送三个精心构造的 multipart 探测请求。这些探测请求使用嵌套 62 层深的 PHP 数组键,大小从 1 MiB 递增到 20 MiB,与 Assetnote 内部扫描器所使用的检测逻辑一致。
当探测请求产生 PHP 内存耗尽错误、差异化的空 HTTP 500 响应、PHP-FPM worker 故障,或所公布的 PHP 版本已知未打补丁时,目标会被报告为存在漏洞。初始的 5xx 响应、常见的请求拒绝状态码,以及不含 PHP 致命错误特征的非空 HTTP 500 响应,均不会被视作崩溃信号。
扫描器默认测试 /index.php。URL 中提供的路径会被保留,--path 或 --path-file 可用于测试自定义路径。phpMyAdmin 目标会自动在 /show_config_errors.php 处重新测试。不跟随重定向。
默认的 --sapi auto 模式会同时应用 mod_php 和 PHP-FPM 的判定规则,与 Assetnote 的 postmodules 的组合行为一致。使用 --sapi mod_php 或 --sapi fpm 可将检测限制为已知的 SAPI。
每个被测试的路径可能会收到一个 42 字节的控制请求和三个探测请求,总计约 29 MiB。一旦判定结果确定,探测即停止,重复的输入 URL 只会被扫描一次。
pip install -r requirements.txt
扫描单个主机:
python3 scanner.py -u https://example.com
扫描主机列表:
python3 scanner.py -l hosts.txt
使用多线程扫描并保存结果:
python3 scanner.py -l hosts.txt -t 20 -o results.json
使用自定义请求头进行扫描:
python3 scanner.py -u https://example.com -H "Authorization: Bearer token" -H "Cookie: session=abc"
扫描自定义路径:
python3 scanner.py -u https://example.com --path /phpinfo.php
python3 scanner.py -u https://example.com --path /index.php --path /admin.php
python3 scanner.py -u https://example.com --path-file paths.txt
仅使用 PHP-FPM 判定规则:
python3 scanner.py -u https://example.com --sapi fpm
-u, --url Single URL to check
-l, --list File containing hosts (one per line)
-t, --threads Number of concurrent threads (default: 10)
--timeout Request timeout in seconds (default: 60)
-o, --output Output file for results (JSON)
--all-results Save all results, not just vulnerable hosts
-k, --insecure Disable TLS certificate verification
-H, --header Custom header (can be used multiple times)
-v, --verbose Show verdict reasons and response snippets
-q, --quiet Only output vulnerable hosts
--no-color Disable colored output
--sapi Verdict rules: auto, mod_php, or fpm (default: auto)
--path Custom path to test (can be used multiple times)
--path-file File containing paths to test (one per line)
php2shell 的最初、原始发现归功于 Calif 团队。你可以在此阅读他们的文章:https://calif.io/php2shell/。
该扫描器由 Assetnote 安全研究团队构建,使用了为 Searchlight 的 Exposure 平台 构建的逻辑。
结果会打印到终端。使用 -o 时,存在漏洞的主机会被保存到 JSON 文件中,其中包含判定原因以及经过脱敏的 HTTP 请求/响应证据。
在特定的 PHP 配置下,当扫描器的 multipart 探测超出 PHP 的 memory_limit 时,扫描器可能会报告误报。此时已修补版本和存在漏洞的版本可能返回相同的空 HTTP 500 响应。
此问题已在已修补的 PHP 8.4.27 上复现,memory_limit 值为 2M 到 32M;并在 PHP 8.3.36 上以 128M 复现,此时 max_multipart_body_parts 设置为 2785 或更高。确切的阈值可能因构建版本而异。
当 PHP 不披露其版本时,扫描器无法区分这种修补后安全发生的 OOM 与修补前存在漏洞的行为。因此,结果应结合已安装的 PHP 版本以及任何供应商回补进行验证。