
Escáner de alta fidelidad para php2shell (CVE-2026-109618 y CVE-2026-109619)
Una herramienta de línea de comandos para detectar CVE-2026-109618 y CVE-2026-109619 en aplicaciones PHP.
El escáner envía una solicitud de control multipart mínima seguida de hasta tres sondas multipart elaboradas. Las sondas utilizan claves de array de PHP anidadas 62 niveles de profundidad y aumentan de 1 MiB a 20 MiB, coincidiendo con la lógica de detección utilizada por el escáner interno de Assetnote.
Se informa que un objetivo es vulnerable cuando la sonda produce un error de agotamiento de memoria de PHP, un HTTP 500 vacío diferencial, un fallo de worker de PHP-FPM, o una versión de PHP anunciada que se sabe que no está parcheada. Las respuestas 5xx iniciales, los estados comunes de rechazo de solicitudes y las respuestas HTTP 500 no vacías sin la firma de error fatal de PHP no se tratan como señales de caída.
El escáner prueba /index.php por defecto. Se conserva una ruta proporcionada en la URL, y --path o --path-file pueden probar rutas personalizadas. Los objetivos de phpMyAdmin se vuelven a probar automáticamente en /show_config_errors.php. No se siguen las redirecciones.
El modo predeterminado --sapi auto aplica tanto las reglas de veredicto de mod_php como las de PHP-FPM, coincidiendo con el comportamiento combinado de los postmódulos de Assetnote. Utilice --sapi mod_php o --sapi fpm para restringir la detección a un SAPI conocido.
Cada ruta probada puede recibir una solicitud de control de 42 bytes y tres sondas que suman aproximadamente 29 MiB. El sondeo se detiene en cuanto se determina el veredicto, y las URL de entrada duplicadas se escanean una sola vez.
pip install -r requirements.txt
Escanear un único host:
python3 scanner.py -u https://example.com
Escanear una lista de hosts:
python3 scanner.py -l hosts.txt
Escanear con múltiples hilos y guardar los resultados:
python3 scanner.py -l hosts.txt -t 20 -o results.json
Escanear con encabezados personalizados:
python3 scanner.py -u https://example.com -H "Authorization: Bearer token" -H "Cookie: session=abc"
Escanear una ruta personalizada:
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
Use solo reglas de veredicto de 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)
El primer descubrimiento original de php2shell se atribuye al equipo de Calif. Puedes leer su informe aquí: https://calif.io/php2shell/.
El escáner fue creado por el Assetnote Security Research Team utilizando la lógica desarrollada para Searchlight's Exposure Platform.
Los resultados se imprimen en la terminal. Al usar -o, los hosts vulnerables se guardan en un archivo JSON con el motivo del veredicto y la evidencia de la solicitud/respuesta HTTP redactada.
En configuraciones específicas de PHP, el escáner puede reportar un falso positivo cuando su sonda multipart supera el memory_limit de PHP. Las versiones parcheadas y vulnerables pueden entonces devolver la misma respuesta HTTP 500 vacía.
Esto se reprodujo en PHP 8.4.27 parcheado con valores de memory_limit de 2M a 32M, y en PHP 8.3.36 con 128M cuando max_multipart_body_parts está configurado en 2785 o superior. El umbral exacto puede variar entre compilaciones.
Cuando PHP no revela su versión, el escáner no puede distinguir este OOM seguro posterior al parche del comportamiento vulnerable anterior al parche. Por lo tanto, los resultados deben verificarse contra la versión de PHP instalada y cualquier backport del proveedor.