
Repository per la ricerca di esposizioni PHP2Shell e analisi correlate
Ricerca delle esposizioni in Defender XDR per PHP2Shell (CVE-2026-109618 / CVE-2026-109619).
v3.3 · 22 ott 2026
Scopo: individuare i dispositivi onboarded che eseguono attivamente PHP e che potrebbero essere esposti a PHP2Shell.
Ambito: Defender XDR Advanced Hunting · endpoint Windows e Linux onboarded · lookback di 30 giorni per impostazione predefinita · solo PHP attivo. Non coperti: installazioni dormienti e dispositivi non gestiti. Non eseguibile in Sentinel, perché la tabella del software installato (TVM) è interrogabile solo in Defender XDR.
| Hunt | Windows | Linux | Domanda |
|---|---|---|---|
| 1 | windows/01-any-php.kql | linux/01-any-php.kql | PHP presente? Sì/no per dispositivo. |
| 2 | windows/02-evidence-breakout.kql | linux/02-evidence-breakout.kql | Evidenze dettagliate con le versioni. |
| 3 | windows/03-safety-net.kql | linux/03-safety-net.kql | Rete di sicurezza: dispositivi in ascolto sulle porte web, processo in ascolto e stato di PHP. |
Tutti i controlli sugli eventi usano un'unica finestra di lookback, let Lookback = 30d; all'inizio di ogni hunt. Gli indirizzi IP provengono dall'ultimo report per adattatore negli ultimi 7 giorni. Il software installato è lo snapshot TVM corrente. Vengono controllati solo gli endpoint onboarded (OnboardingStatus == "Onboarded", DeviceCategory == "Endpoint").
Un dispositivo è considerato PHP rilevato se corrisponde anche solo una di queste condizioni.
Come vengono confrontati i nomi:
^…$), quindi deve corrispondere all'intero nome del file, mai a una sua parte.startswith "php", più frankenphp su entrambi i sistemi operativi e lsphp su Linux. La regex viene poi eseguita solo su ciò che resta.php9.dll) corrispondono automaticamente.patterns.test.js esegue ogni regex su questi esempi. Se modifichi una regex, aggiorna gli esempi al suo interno.Windows
| Controllo | Tabella | Corrispondenze | Perché è importante |
|---|---|---|---|
| Esecutabili PHP avviati | DeviceProcessEvents | Regex ^(php(-cgi|-win)?|frankenphp)\.exe$, che consente esattamente quattro nomi: php.exe (CLI), php-cgi.exe (worker FastCGI), php-win.exe (CLI, senza console), frankenphp.exe (PHP incorporato in un web server). phpstorm64.exe e altri strumenti php* non corrispondono | Dimostra che PHP è stato eseguito. La hunt 2 mostra la versione dalle informazioni di versione del binario (ProcessVersionInfoProductVersion) |
| DLL del motore PHP caricate | DeviceImageLoadEvents | Regex ^php\d*(ts|isapi|apache[\w_]*)?\.dll$: php, un eventuale numero di versione, un suffisso opzionale ts / isapi / apache…, poi .dll. Gli esempi sono nella tabella delle DLL qui sotto. Le DLL delle estensioni (php_curl.dll e altre php_*.dll) non corrispondono, perché il carattere di sottolineatura non è consentito subito dopo php | L'unico modo per vedere PHP in esecuzione all'interno di un altro processo, come IIS o Apache, dove non viene avviato alcun php*.exe. La hunt 2 mostra la DLL e il processo che l'ha caricata |
| Software installato | DeviceTvmSoftwareInventory | Non è una regex: SoftwareName has "php" (php come parola intera nel nome) oppure SoftwareVendor =~ "php" (esatto, case-insensitive) | Individua le installazioni registrate. Le installazioni da zip (il metodo abituale su Windows) normalmente non vengono registrate |
Esempi di DLL del motore PHP che il pattern Windows individua
| DLL | Cos'è | Processo host tipico (mostrato in hunt 2) |
|---|---|---|
php8.dll, php7.dll | Engine, build non thread-safe | php-cgi.exe (FastCGI sotto IIS, nginx o Apache mod_fcgid), php.exe |
php8ts.dll, php7ts.dll, php5ts.dll | Engine, build thread-safe | httpd.exe (modulo Apache), php.exe |
php8apache2_4.dll, php7apache2_4.dll, php5apache2_2.dll | Loader del modulo Apache | httpd.exe |
php5isapi.dll | Modulo ISAPI IIS legacy (PHP 5.2 e precedenti, non supportato) | w3wp.exe |
La tabella elenca i nomi comuni, non un elenco di autorizzati: qualsiasi nome che corrisponda al pattern viene rilevato. Il nome della DLL indica solo la versione major. La versione esatta proviene da una riga di processo php-cgi.exe o php.exe, oppure dal software installato, sullo stesso dispositivo.
Linux
| Controllo | Tabella | Corrispondenze | Perché è importante |
|---|---|---|---|
| Binari PHP avviati | DeviceProcessEvents | Regex ^(php[\d.]*|php-(fpm|cgi)[\d.]*|lsphp[\d.]*|frankenphp)$: php, php-fpm, php-cgi o lsphp (LiteSpeed), ciascuno con una versione opzionale composta da cifre e punti, più frankenphp. Esempi: php, php8.3, php83, php-fpm8.3, php-cgi8.2, lsphp83. Strumenti come phpunit, phpize e php-config non corrispondono, perché dopo il nome base possono seguire solo cifre e punti | Dimostra che PHP è stato eseguito. Hunt 2 mostra un indizio major.minor, estratto dal nome, dal percorso o dalla riga di comando tramite una seconda regex, php-?(?:fpm|cgi)?/?(\d+\.\d+) (ad esempio php-fpm8.3 o /etc/php/8.3/ restituisce 8.3.x) |
| Pacchetti installati | DeviceTvmSoftwareInventory | Non è una regex: SoftwareName contains "php" (sottostringa, quindi nomi con versione come php8.3-fpm e libapache2-mod-php8.3 corrispondono) oppure SoftwareVendor =~ "php" | L'unico controllo per Apache mod_php e per php-fpm in esecuzione da prima della finestra: su Linux qui non c'è alcun controllo sul caricamento delle librerie, e i worker php-fpm forkati non generano avvii di processo |
| Controllo | Tabella | Corrispondenze | Perché è importante |
|---|---|---|---|
| Servizio web attivo | DeviceNetworkEvents | InboundConnectionAccepted su un elenco fisso di porte: 80, 443, 8080, 8443. Il loopback è escluso (RemoteIPType != "Loopback"). Mostra sorgenti distinte e pubbliche, più il processo che accetta (via <process>) | Dimostra che un dispositivo sta servendo, anche se il suo web server è stato avviato prima della finestra di lookback. ntoskrnl.exe = HTTP.sys (IIS, ADFS, RD Gateway, Windows Admin Center, SSTP) |
| Web server avviato | DeviceProcessEvents | Non è una regex: un elenco fisso di nomi esatti, senza distinzione tra maiuscole e minuscole (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 web server avviato nella finestra che non ha caricato PHP dà "Not seen" con alta confidenza. Windows mostra anche i nomi degli application pool IIS, estratti dalla riga di comando di w3wp.exe tramite la regex -ap\s+"?([^"\s]+) |
Valori della colonna PHP in hunt 3