
Repository zur Suche nach PHP2Shell-Expositionen und zugehörigen Analysen
Defender XDR Exposure Hunting für PHP2Shell (CVE-2026-109618 / CVE-2026-109619).
v3.3 · 22. Okt. 2026
Zweck: Onboarded Geräte finden, auf denen PHP aktiv läuft und die PHP2Shell ausgesetzt sein könnten.
Umfang: Defender XDR Advanced Hunting · onboarded Windows- und Linux-Endpunkte · standardmäßig 30 Tage Rückblick · nur aktives PHP. Nicht abgedeckt: inaktive Installationen und nicht verwaltete Geräte. Nicht in Sentinel ausführbar, da die Tabelle der installierten Software (TVM) nur in Defender XDR abfragbar ist.
| Hunt | Windows | Linux | Frage |
|---|---|---|---|
| 1 | windows/01-any-php.kql | linux/01-any-php.kql | Irgendein PHP? Ja/Nein pro Gerät. |
| 2 | windows/02-evidence-breakout.kql | linux/02-evidence-breakout.kql | Nachweis-Aufschlüsselung mit Versionen. |
| 3 | windows/03-safety-net.kql | linux/03-safety-net.kql | Sicherheitsnetz: Geräte, die auf Web-Ports lauschen, der lauschende Prozess und PHP-Status. |
Alle Ereignisprüfungen verwenden ein einziges Rückblickfenster, let Lookback = 30d; am Anfang jedes Hunts. IP-Adressen stammen aus dem neuesten Bericht pro Adapter der letzten 7 Tage. Installierte Software ist der aktuelle TVM-Snapshot. Es werden nur onboarded Endpunkte geprüft (OnboardingStatus == "Onboarded", DeviceCategory == "Endpoint").
Ein Gerät gilt als PHP gesehen, wenn eine der folgenden Bedingungen zutrifft.
Wie Namen abgeglichen werden:
^…$), muss also auf den gesamten Dateinamen passen, niemals auf einen Teil davon.startswith "php", plus frankenphp auf beiden Betriebssystemen und lsphp auf Linux. Der Regex läuft dann nur noch auf dem, was übrig bleibt.php9.dll) werden automatisch erkannt.patterns.test.js führt jeden Regex gegen diese Beispiele aus. Wenn Sie einen Regex ändern, aktualisieren Sie die Beispiele dort.Windows
| Prüfung | Tabelle | Trifft | Warum es wichtig ist |
|---|---|---|---|
| Gestartete PHP-Executables | DeviceProcessEvents | Regex ^(php(-cgi|-win)?|frankenphp)\.exe$, der genau vier Namen zulässt: php.exe (CLI), php-cgi.exe (FastCGI-Worker), php-win.exe (CLI, ohne Konsole), frankenphp.exe (PHP eingebettet in einen Webserver). phpstorm64.exe und andere php*-Tools treffen nicht zu | Beweist, dass PHP lief. Hunt 2 zeigt die Version aus den Versionsinformationen der Binärdatei (ProcessVersionInfoProductVersion) |
| Geladene PHP-Engine-DLLs | DeviceImageLoadEvents | Regex ^php\d*(ts|isapi|apache[\w_]*)?\.dll$: php, eine beliebige Versionsnummer, ein optionales Suffix ts / isapi / apache…, dann .dll. Beispiele stehen in der DLL-Tabelle unten. Extension-DLLs (php_curl.dll und andere php_*.dll) treffen nicht zu, da der Unterstrich direkt nach php nicht erlaubt ist | Die einzige Möglichkeit, PHP innerhalb eines anderen Prozesses zu sehen, etwa IIS oder Apache, wo kein php*.exe startet. Hunt 2 zeigt die DLL und den Prozess, der sie geladen hat |
| Installierte Software | DeviceTvmSoftwareInventory | Kein Regex: SoftwareName has "php" (php als ganzes Wort im Namen) oder SoftwareVendor =~ "php" (exakt, case-insensitiv) | Erfasst registrierte Installationen. Zip-Installationen (die übliche Windows-Methode) registrieren sich normalerweise nicht |
Beispiele für PHP-Engine-DLLs, die das Windows-Muster trifft
| DLL | Was es ist | Typischer Hostprozess (angezeigt in Hunt 2) |
|---|---|---|
php8.dll, php7.dll | Engine, Non-Thread-Safe-Build | php-cgi.exe (FastCGI unter IIS, nginx oder Apache mod_fcgid), php.exe |
php8ts.dll, php7ts.dll, php5ts.dll | Engine, Thread-Safe-Build | httpd.exe (Apache-Modul), php.exe |
php8apache2_4.dll, php7apache2_4.dll, php5apache2_2.dll | Apache-Modul-Loader | httpd.exe |
php5isapi.dll | Legacy-IIS-ISAPI-Modul (PHP 5.2 und früher, nicht unterstützt) | w3wp.exe |
Die Tabelle listet gängige Namen auf, keine Allow-List: Jeder Name, der dem Muster entspricht, wird erkannt. Der DLL-Name liefert nur die Hauptversion. Die exakte Version stammt aus einer Prozesszeile von php-cgi.exe oder php.exe oder aus der installierten Software auf demselben Gerät.
Linux
| Prüfung | Tabelle | Übereinstimmungen | Warum es wichtig ist |
|---|---|---|---|
| Gestartete PHP-Binaries | DeviceProcessEvents | Regex ^(php[\d.]*|php-(fpm|cgi)[\d.]*|lsphp[\d.]*|frankenphp)$: php, php-fpm, php-cgi oder lsphp (LiteSpeed), jeweils mit einer optionalen Version aus Ziffern und Punkten, plus frankenphp. Beispiele: php, php8.3, php83, php-fpm8.3, php-cgi8.2, lsphp83. Werkzeuge wie phpunit, phpize und php-config werden nicht erkannt, da auf den Basisnamen nur Ziffern und Punkte folgen dürfen | Belegt, dass PHP ausgeführt wurde. Hunt 2 zeigt einen major.minor-Hinweis, der durch eine zweite Regex, php-?(?:fpm|cgi)?/?(\d+\.\d+), aus dem Namen, Pfad oder der Befehlszeile extrahiert wird (zum Beispiel ergibt php-fpm8.3 oder /etc/php/8.3/ den Wert 8.3.x) |
| Installierte Pakete | DeviceTvmSoftwareInventory | Keine Regex: SoftwareName contains "php" (Teilstring, sodass versionierte Namen wie php8.3-fpm und libapache2-mod-php8.3 erkannt werden) oder SoftwareVendor =~ "php" | Die einzige Prüfung für Apache mod_php und für php-fpm, das bereits vor dem Zeitfenster lief: Unter Linux gibt es hier keine Bibliothekslade-Prüfung, und geforkte php-fpm-Worker erzeugen keine Prozessstarts |
| Prüfung | Tabelle | Übereinstimmungen | Warum es wichtig ist |
|---|---|---|---|
| Aktive Web-Bereitstellung | DeviceNetworkEvents | InboundConnectionAccepted auf einer festen Portliste: 80, 443, 8080, 8443. Loopback ist ausgeschlossen (RemoteIPType != "Loopback"). Zeigt eindeutige und öffentliche Quellen sowie den annehmenden Prozess (via <process>) | Belegt, dass ein Gerät Dienste bereitstellt, selbst wenn sein Webserver vor dem Lookback-Zeitfenster gestartet wurde. ntoskrnl.exe = HTTP.sys (IIS, ADFS, RD Gateway, Windows Admin Center, SSTP) |
| Gestarteter Webserver | DeviceProcessEvents | Keine Regex: eine feste Liste exakter Namen, Groß-/Kleinschreibung wird ignoriert (in~). Windows: w3wp.exe, httpd.exe, nginx.exe, caddy.exe, lighttpd.exe, frankenphp.exe. Linux: httpd, apache2, nginx, lshttpd, litespeed, openlitespeed, caddy, lighttpd, frankenphp | Ein Webserver, der im Zeitfenster gestartet wurde und kein PHP geladen hat, ergibt „Not seen" mit hoher Konfidenz. Unter Windows werden außerdem IIS-Anwendungspool-Namen angezeigt, die durch die Regex -ap\s+"?([^"\s]+) aus der Befehlszeile von w3wp.exe extrahiert werden |
PHP-Spaltenwerte in Hunt 3