Am 20. Oktober 2026 wurden zwei schwere Lücken im PHP-Kern veröffentlicht. Der gängige Name ist PHP2Shell, die Kennungen lauten CVE-2026-109618 und CVE-2026-109619. Der CVSS-Wert liegt bei 9,2. Sie erlauben Codeausführung auf dem Server ohne Anmeldung, und Angriffe wurden bereits beobachtet.

In diesem Artikel erkläre ich, was das ist und welche PHP-Versionen betroffen sind. Ich erzähle, wie ich die Server, die ich betreue, abgesichert habe, solange es keinen Patch gab. Außerdem beschreibe ich, wie ich zum endgültigen Update gekommen bin. Hier findest du auch das Skript, das ich benutzt habe, und die Befehle zum Starten.
Was ist PHP2Shell
Das Problem liegt darin, wie PHP Anfragen vom Typ multipart/form-data liest. Das ist das Format, mit dem der Browser Dateien sendet. PHP verarbeitet es, bevor irgendein Skript startet.
Darum braucht es kein Upload-Formular. Eine einzige Anfrage an irgendeine PHP-Datei der Seite kann genügen.
Die beiden Lücken in Kürze:
- CVE-2026-109618. Wenn der Speicher ausgeht, während PHP die Anfrage liest, werden Daten beschädigt. Der Schaden zeigt sich beim Aufräumen am Ende der Anfrage und kann zur Codeausführung führen.
- CVE-2026-109619. Ein Teil des Zustands einer Anfrage bleibt im Speicher. Eine spätere Anfrage im selben Prozess verwendet ihn wieder.
Diese technischen Details stammen aus der Analyse des niederländischen NCSC und aus anderen öffentlichen Quellen. Ich habe nicht versucht, die Lücken auf meinen Servern auszunutzen.
Welche PHP-Versionen sind betroffen
Die korrigierten Versionen erschienen am 21. Oktober 2026: PHP 8.5.12, 8.4.27, 8.3.36 und 8.2.35. Jede ältere Version ist betroffen.
Für die Zweige 8.1 und älter gibt es keine offizielle korrigierte Version, weil sie nicht mehr unterstützt werden. PHP hat nur minimale Backports des Quellcodes für 7.4, 8.0 und 8.1 veröffentlicht. Für noch ältere Zweige ist nichts bekannt.
Das Risiko betrifft jede Art, PHP auszuführen. Am stärksten ausgesetzt ist mod_php. Auch PHP-FPM, php-cgi, FrankenPHP und LiteSpeed zählen. Dazu kommen alle Anwendungen darüber: WordPress, Joomla, Drupal, Nextcloud, phpMyAdmin, Roundcube und das ISPConfig-Panel.
Bei Debian gibt es ein Detail, das man kennen sollte. Debian übernimmt die Korrekturen als Backport und ändert die PHP-Versionsnummer nicht. Ein Server kann eine niedrige Nummer zeigen und trotzdem schon korrigiert sein. Deshalb vergleicht das Skript keine Versionen. Es prüft, ob das Changelog des installierten Pakets die beiden CVEs nennt.
Die Schutzmaßnahme, bis der Patch da ist
Als die Lücken öffentlich wurden, waren die Patches für die Distributionen noch nicht verfügbar. Ich wollte die Server nicht ungeschützt lassen. Also habe ich das Risiko mit einem Skript verringert.
Die Schutzmaßnahme ist kein Patch. Wer session.upload_progress abschaltet, schließt nur einen der bekannten Angriffswege zur CVE-2026-109619. Gegen die CVE-2026-109618 hilft das nicht. Die Maßnahme sollte die Angriffsfläche bis zum Update verkleinern, nicht das Update ersetzen.
Was das Skript macht
Das Skript ist für Debian 12 und 13 gedacht. Es funktioniert mit Apache (mod_php, FastCGI, suPHP, PHP-FPM) und mit Nginx (PHP-FPM). Es erkennt Server, die mit ISPConfig verwaltet werden, ob Apache oder Nginx.
Die Optionen:
- Ohne Optionen prüft es nur. Für jedes PHP-Paket kontrolliert es, ob das Changelog die beiden CVEs nennt. Es meldet Prozesse, die noch eine alte Binärdatei nutzen, und liest die aktiven Einstellungen und die offenen Web-Ports aus.
--updateaktualisiert zuerst den Paketindex.--logssucht verdächtige Spuren: neue PHP-Dateien in Upload- oder Cache-Ordnern, typische Webshell-Muster, Verweise auf php2shell in den Logs. Das ist eine Heuristik und beweist keine Kompromittierung.--hardenwendet die unten beschriebene Absicherung an.--dry-runzeigt zusammen mit--harden, was passieren würde, ohne etwas zu ändern.--skip-disable-functionslässt zusammen mit--hardendisable_functionsunangetastet.--rollbacknimmt zurück, was--hardenangewendet hat.
Was sich mit –harden ändert
Für jede PHP-Version in /etc/php legt das Skript die Datei mods-available/cve-hardening.ini an. Es aktiviert sie mit phpenmod für die SAPIs fpm, apache2 und cgi. So gilt der Schutz für alle Seiten auf einmal.
Die originalen php.ini bleiben unberührt. Die CLI wird nicht angefasst, also laufen composer, artisan und wp-cli weiter.
Die Datei setzt drei Dinge:
session.upload_progress.enabled = Offexpose_php = Offdisable_functionsmit exec, passthru, shell_exec, system, proc_open, popen und pcntl_exec, zusätzlich zu den bereits vorhandenen.
Danach testet das Skript die Konfiguration und lädt PHP-FPM und Apache nur neu, wenn der Test besteht. Vor dem Schreiben legt es ein Backup in /var/backups/php-cve-hardening/ an.
Die Grenzen, die du kennen solltest
disable_functionskann manche Anwendungen kaputt machen, zum Beispiel WordPress mit bestimmten Plugins oder Magento. Dann nimm--rollbackoder starte erneut mit--skip-disable-functions.- Die Direktiven
php_admin_valuein den PHP-FPM-Pools haben Vorrang vor der globalen Datei. Das Skript meldet sie, ändert sie aber nicht. - Bei ISPConfig werden die Dateien in
pool.dvom Panel neu erzeugt. Overrides korrigierst du im Panel unter Sites, Website, Options, Custom php.ini settings, nicht von Hand. - Die
php.inieinzelner Seiten (FastCGI- oder suPHP-Modus von ISPConfig) und PHP-Versionen in/optwerden nicht verwaltet. Sie müssen separat geprüft werden.
So startest du das Skript
Das Skript liegt hier: https://cisilino.com/mscripts/php20261.sh
Bevor du etwas aus dem Internet ausführst, lies es. Du kannst es herunterladen und öffnen:
wget -qO php20261.sh https://cisilino.com/mscripts/php20261.sh
less php20261.sh
Wenn du es direkt aus der Ferne starten willst, brauchst du Root-Rechte. Das sind die Befehle, in der Reihenfolge, die ich empfehle.
1. Nur prüfen, mit Aktualisierung des Paketindex:
wget -qO- https://cisilino.com/mscripts/php20261.sh | sudo bash -s -- --update
2. Absicherung simulieren, ohne Änderungen:
wget -qO- https://cisilino.com/mscripts/php20261.sh | sudo bash -s -- --harden --dry-run
3. Anwenden:
wget -qO- https://cisilino.com/mscripts/php20261.sh | sudo bash -s -- --harden
4. Entfernen, falls etwas kaputtgeht:
wget -qO- https://cisilino.com/mscripts/php20261.sh | sudo bash -s -- --rollback
Nach --harden und nach --rollback musst du nichts von Hand neu starten. Das Skript lädt PHP-FPM und Apache selbst neu, nachdem es die Konfiguration getestet hat. Ein Neustart ist dagegen nach dem Update des PHP-Pakets nötig, weil die laufenden Prozesse die alte Binärdatei im Speicher halten:
sudo systemctl restart 'php*-fpm' apache2
Die Anführungszeichen um php*-fpm sind wichtig. Ohne sie expandiert die Shell das Sternchen, nicht systemctl. Wenn der Server nur Nginx nutzt, lass apache2 weg.
Das Ergebnis des Skripts ist auch ein Exit-Code: 0, wenn alles in Ordnung ist, 1 bei Warnungen, 2 wenn das System verwundbar ist oder etwas getan werden muss.
Auf Servern mit ISPConfig: ispconfig-multipart-guard
Wer ISPConfig nutzt, hat ein zusätzliches Werkzeug. Das Projekt hat das Skript ispconfig-multipart-guard veröffentlicht, beschrieben in der offiziellen ISPConfig-Meldung.
Das Prinzip ist einfach. Wenn das Problem in Multipart-Anfragen liegt, stoppt der Webserver sie, bevor sie PHP erreichen:
- Es blockiert Anfragen mit
Content-Type: multipart/...für alle Seiten, für ausgewählte Seiten oder für das Control Panel; - bei Nginx antwortet es auf PHP-Anfragen der blockierten Seiten mit 415, statische Dateien bleiben unverändert. Bei Apache antwortet es mit 403, auch bei statischen Dateien;
- standardmäßig blockiert es nur das ISPConfig-Panel. Die Seiten blockierst du mit Befehlen wie
block alloderblock esempio.it; - es legt einen Cronjob an, der alle 5 Minuten seine Hooks wiederherstellt, falls ISPConfig die Konfiguration neu schreibt;
- es hat eine Liste erlaubter IPs, die weiterhin Dateien hochladen dürfen.
Es läuft auf Debian und Ubuntu, mit ISPConfig 3.2 oder 3.3 (auch ohne ISPConfig), mit Nginx oder mit Apache 2.4 und neuer.
Der Preis: Auf blockierten Seiten funktionieren Uploads nicht. Das gilt auch für CMS-Medien, Formularanhänge, Anhänge im Webmail und Importe in phpMyAdmin. Normale Seiten und urlencoded-Formulare laufen weiter. Auch das ist eine vorläufige Maßnahme und keine Korrektur.
Dieses Skript und meines schließen sich nicht gegenseitig aus. Meines greift in die PHP-Konfiguration ein, das von ISPConfig in den Webserver. Ich habe sie nicht in der Praxis verglichen und kann dir nicht sagen, wie sie sich zusammen in jeder Konfiguration verhalten.
Das endgültige Update, in zwei Schritten
Die Schutzmaßnahmen sollten nur kurz gelten. Ich habe die Server aktualisiert, sobald die Updates verfügbar waren, in zwei Schritten:
- Direkt kompilieren. Solange die Distribution auf dem jeweiligen Server ihr Paket noch nicht veröffentlicht hatte, habe ich PHP aus dem Quellcode in den korrigierten Versionen kompiliert.
- Offizielles Paket. Als das offizielle Paket der Distribution für diesen Server erschien, habe ich die Kompilierung durch das Paket ersetzt.
Der zweite Schritt ist wichtig. Ein von Hand kompiliertes PHP aktualisiert sich nicht zusammen mit dem Rest des Systems. Das Paket der Distribution schon, und das Skript kann das über das Changelog prüfen.
Was du jetzt tun solltest
- Aktualisiere PHP auf 8.5.12, 8.4.27, 8.3.36 oder 8.2.35. Unter Debian kannst du auch das Paket der Distribution nehmen, wenn das Changelog die beiden CVEs nennt.
- Starte PHP-FPM und Apache neu und lass das Skript dann ohne Optionen noch einmal laufen. Es darf keine Probleme mehr melden.
- Wenn du PHP 8.1 oder älter nutzt, plane den Wechsel auf einen unterstützten Zweig. Für diese Zweige gibt es keine offizielle korrigierte Version.
- Lass
session.upload_progressdeaktiviert, bis zur nächsten Korrekturversion, falls deine Anwendung es nicht braucht. - Prüfe Logs und neue Dateien, mit
--logsoder von Hand, und suche nach PHP-Dateien, die in Upload-Ordnern aufgetaucht sind. - Vergiss PHP in Containern, Images und Appliances von Dritten nicht. Sie müssen separat aktualisiert werden.
- Wenn deine Seite WordPress nutzt: Das Plugin Cisilino Site Defense Network löst PHP2Shell nicht. Es schützt aber den Login und führt ein Aktivitätsprotokoll, das hilft zu verstehen, was auf der Seite passiert.
Quellen
- ISPConfig: PHP2Shell, kritische PHP-Schwachstellen (CVE-2026-109618, CVE-2026-109619)
- NCSC-NL: Wiki zu PHP2Shell
ISPConfig, PHP, Debian und die anderen genannten Namen sind Marken der jeweiligen Inhaber. Sie dienen nur zur Identifizierung der Produkte.

Schreibe einen Kommentar