
Repositorio para la búsqueda de exposiciones de PHP2Shell y análisis relacionados
Búsqueda de exposición en Defender XDR para PHP2Shell (CVE-2026-109618 / CVE-2026-109619).
v3.3 · 22 oct 2026
Propósito: Encontrar dispositivos incorporados que ejecutan PHP activamente y que podrían estar expuestos a PHP2Shell.
Alcance: Defender XDR Advanced Hunting · endpoints Windows y Linux incorporados · ventana de retrospectiva de 30 días por defecto · solo PHP activo. No cubierto: instalaciones inactivas y dispositivos no gestionados. No ejecutable en Sentinel, porque la tabla de software instalado (TVM) solo se puede consultar en Defender XDR.
| Búsqueda | Windows | Linux | Pregunta |
|---|---|---|---|
| 1 | windows/01-any-php.kql | linux/01-any-php.kql | ¿Algún PHP? Sí/no por dispositivo. |
| 2 | windows/02-evidence-breakout.kql | linux/02-evidence-breakout.kql | Desglose de evidencias con versiones. |
| 3 | windows/03-safety-net.kql | linux/03-safety-net.kql | Red de seguridad: dispositivos que sirven en puertos web, el proceso en escucha y el estado de PHP. |
Todas las comprobaciones de eventos usan una única ventana de retrospectiva, let Lookback = 30d; al inicio de cada búsqueda. Las direcciones IP provienen del informe más reciente por adaptador en los últimos 7 días. El software instalado es la instantánea actual de TVM. Solo se comprueban los endpoints incorporados (OnboardingStatus == "Onboarded", DeviceCategory == "Endpoint").
Un dispositivo cuenta como PHP visto si coincide cualquiera de estos casos.
Cómo se comparan los nombres:
^…$), por lo que debe coincidir con el nombre de archivo completo, nunca con parte de él.startswith "php", más frankenphp en ambos SO y lsphp en Linux. Después, la regex se ejecuta solo sobre lo que queda.php9.dll) coinciden automáticamente.patterns.test.js ejecuta cada regex contra estos ejemplos. Si cambias una regex, actualiza los ejemplos allí.Windows
| Comprobación | Tabla | Coincidencias | Por qué importa |
|---|---|---|---|
| Ejecutables PHP iniciados | DeviceProcessEvents | Regex ^(php(-cgi|-win)?|frankenphp)\.exe$, que permite exactamente cuatro nombres: php.exe (CLI), php-cgi.exe (worker FastCGI), php-win.exe (CLI, sin consola), frankenphp.exe (PHP embebido en un servidor web). phpstorm64.exe y otras herramientas php* no coinciden | Demuestra que PHP se ejecutó. La búsqueda 2 muestra la versión a partir de la información de versión del binario (ProcessVersionInfoProductVersion) |
| DLLs del motor PHP cargadas | DeviceImageLoadEvents | Regex ^php\d*(ts|isapi|apache[\w_]*)?\.dll$: php, cualquier número de versión, un sufijo opcional ts / isapi / apache…, y luego .dll. Los ejemplos están en la tabla de DLL a continuación. Las DLLs de extensión (php_curl.dll y otras php_*.dll) no coinciden, porque el guion bajo no está permitido justo después de php | La única forma de ver PHP ejecutándose dentro de otro proceso, como IIS o Apache, donde no se inicia ningún php*.exe. La búsqueda 2 muestra la DLL y el proceso que la cargó |
| Software instalado | DeviceTvmSoftwareInventory | No es una regex: SoftwareName has "php" (php como palabra completa en el nombre) o SoftwareVendor =~ "php" (exacto, sin distinguir mayúsculas de minúsculas) | Detecta instalaciones registradas. Las instalaciones por Zip (el método habitual en Windows) normalmente no se registran |
Ejemplos de DLLs del motor PHP que coincide con el patrón de Windows
| DLL | Qué es | Proceso host típico (mostrado en la búsqueda 2) |
|---|---|---|
php8.dll, php7.dll | Motor, compilación no thread-safe | php-cgi.exe (FastCGI bajo IIS, nginx o Apache mod_fcgid), php.exe |
php8ts.dll, php7ts.dll, php5ts.dll | Motor, compilación thread-safe | httpd.exe (módulo Apache), php.exe |
php8apache2_4.dll, php7apache2_4.dll, php5apache2_2.dll | Cargador del módulo Apache | httpd.exe |
php5isapi.dll | Módulo ISAPI heredado de IIS (PHP 5.2 y anteriores, sin soporte) | w3wp.exe |
La tabla enumera nombres comunes, no una lista de permitidos: cualquier nombre que coincida con el patrón coincide. El nombre de la DLL solo indica la versión mayor. La versión exacta proviene de una fila de proceso php-cgi.exe o php.exe, o del software instalado, en el mismo dispositivo.
Linux
| Comprobación | Tabla | Coincidencias | Por qué importa |
|---|---|---|---|
| Binarios PHP iniciados | DeviceProcessEvents | Regex ^(php[\d.]*|php-(fpm|cgi)[\d.]*|lsphp[\d.]*|frankenphp)$: php, php-fpm, php-cgi o lsphp (LiteSpeed), cada uno con una versión opcional formada por dígitos y puntos, más frankenphp. Ejemplos: php, php8.3, php83, php-fpm8.3, php-cgi8.2, lsphp83. Herramientas como phpunit, phpize y php-config no coinciden, porque solo pueden seguir dígitos y puntos al nombre base | Demuestra que PHP se ejecutó. La búsqueda 2 muestra una pista de major.minor, extraída del nombre, la ruta o la línea de comandos mediante una segunda regex, php-?(?:fpm|cgi)?/?(\d+\.\d+) (por ejemplo, php-fpm8.3 o /etc/php/8.3/ da 8.3.x) |
| Paquetes instalados | DeviceTvmSoftwareInventory | No es una regex: SoftwareName contains "php" (subcadena, por lo que coinciden nombres con versión como php8.3-fpm y libapache2-mod-php8.3) o SoftwareVendor =~ "php" | La única comprobación para Apache mod_php y para php-fpm en ejecución desde antes de la ventana: Linux no tiene aquí comprobación de carga de bibliotecas, y los workers php-fpm bifurcados no crean inicios de proceso |
| Comprobación | Tabla | Coincidencias | Por qué importa |
|---|---|---|---|
| Servicio web activo | DeviceNetworkEvents | InboundConnectionAccepted en una lista fija de puertos: 80, 443, 8080, 8443. Se excluye loopback (RemoteIPType != "Loopback"). Muestra orígenes distintos y públicos, además del proceso que acepta (via <process>) | Demuestra que un dispositivo está sirviendo, incluso si su servidor web se inició antes de la ventana de retroceso. ntoskrnl.exe = HTTP.sys (IIS, ADFS, RD Gateway, Windows Admin Center, SSTP) |
| Servidor web iniciado | DeviceProcessEvents | No es una regex: una lista fija de nombres exactos, sin distinguir mayúsculas (in~). Windows: w3wp.exe, httpd.exe, nginx.exe, caddy.exe, lighttpd.exe, frankenphp.exe. Linux: httpd, apache2, nginx, lshttpd, litespeed, openlitespeed, caddy, lighttpd, frankenphp | Un servidor web que se inició en la ventana y no cargó PHP da "Not seen" con alta confianza. Windows también muestra nombres de grupos de aplicaciones de IIS, extraídos de la línea de comandos de w3wp.exe mediante la regex -ap\s+"?([^"\s]+) |
Valores de la columna PHP en la búsqueda 3