Kurz gesagt: Wenn PHP-FPM, Apache oder ein anderer Webserver-Prozess eine Shell wie sh oder bash startet, ist das eines der stärksten Warnsignale für einen Einbruch über die Website. Prüfen Sie den Prozessbaum, die Kommandozeile und das Arbeitsverzeichnis der Shell, bevor Sie etwas beenden. Einzelne kurze Shells können legitim sein; lange laufende Shells mit Netzwerkwerkzeugen sind es fast nie.
Warum dieses Muster so viel aussagt
Ein Webserver beantwortet Anfragen. PHP-FPM, das ist der Prozessverwalter, der PHP-Skripte für den Webserver ausführt, startet dafür normalerweise keine weiteren Programme. Eine Shell unter dem Webserver bedeutet, dass PHP-Code bewusst ein Programm aufgerufen hat. Entweder die Anwendung tut das absichtlich, oder jemand anderes hat Code eingeschleust.
Für PHP2Shell gibt es keine veröffentlichten, bestätigten Indicators of Compromise, also keine Liste fester Erkennungsmerkmale. Die Erkennung beruht auf Verhalten. Laut den uns vorliegenden Berichten gehören Webserver- oder PHP-FPM-Prozesse, die eine Shell starten, zu den stärksten allgemeinen Warnsignalen. Das gilt für jede Lücke, über die Angreifer Code auf dem Server ausführen. Einen Überblick über weitere Anzeichen gibt Bin ich schon kompromittiert?.
Warum ist die Shell für einen Angreifer so wichtig? Mit einer Lücke kann er zunächst nur einzelne Befehle über den PHP-Prozess absetzen. Eine Shell macht daraus einen bequemen Arbeitsplatz: Er kann sich umsehen, Werkzeuge nachladen, Zugangsdaten aus Konfigurationsdateien lesen und sich dauerhaft einrichten. Wer die Shell erkennt, erkennt den Angreifer also oft in dem Moment, in dem er vom ersten Zugriff zum eigentlichen Vorhaben übergeht.
PHP-FPM startet bash: den Prozessbaum lesen
Jeder Prozess unter Linux hat einen Elternprozess. Die Frage ist, ob eine Shell als Kind eines Webserver-Prozesses läuft. Die folgenden Befehle lesen nur:
# Prozessbaum mit Benutzer, Eltern-PID und Startzeit
ps -eo user,pid,ppid,lstart,cmd --forest | grep -B2 -A4 -E "[p]hp-fpm|[a]pache2|[h]ttpd|[l]sphp"
# Shells, die unter typischen Webserver-Benutzern laufen
ps -eo user,pid,ppid,lstart,cmd | grep -E "^(www-data|apache|nginx) " | grep -E "[ /](ba|da)?sh( |$)"
# Baum ab dem ältesten PHP-FPM-Prozess
pstree -alp "$(pgrep -o php-fpm)"
Haben Sie eine verdächtige Shell gefunden, liefern die Einträge unter /proc weitere Hinweise, ebenfalls nur lesend:
PID=12345 # PID der verdächtigen Shell
tr '\0' ' ' < /proc/$PID/cmdline; echo # vollständige Kommandozeile
ls -l /proc/$PID/cwd /proc/$PID/exe # Arbeitsverzeichnis und Programmdatei
ls -l /proc/$PID/fd 2>/dev/null | grep socket # offene Netzwerkverbindungen
Prozessnamen auf Debian und Ubuntu lauten oft php8.3-fpm oder ähnlich; passen Sie die Suchmuster an. Arbeitsverzeichnisse in /tmp, /dev/shm oder in Upload-Ordnern sind ein deutliches Zeichen.
Legitime Ausnahmen und echte Warnzeichen
Manche Anwendungen rufen Programme über PHP auf. Dabei kann kurz eine Shell entstehen, etwa wenn PHP über sendmail_path Mails übergibt oder eine Anwendung Bilder mit einem externen Werkzeug verarbeitet. Solche Shells leben nur Sekunden und rufen immer dasselbe Programm auf. Dokumentieren Sie diese erwarteten Fälle einmal sauber; dann fällt jede Abweichung davon sofort auf, statt in einer Flut bekannter Meldungen unterzugehen.
| Beobachtung | Eher harmlos, wenn | Verdächtig, wenn |
|---|---|---|
| Kurze Shell unter PHP-FPM | sie ein bekanntes Programm der Anwendung startet | Ziel und Zweck unklar sind |
| Länger laufende Shell | nie | sie Minuten oder Stunden läuft |
| Netzwerkwerkzeuge als Kindprozess | bekannte Update- oder API-Abfrage der Anwendung | Downloads in temporäre Verzeichnisse folgen |
| Arbeitsverzeichnis | Projektordner der Anwendung | /tmp, /dev/shm, Upload-Ordner |
| Zeitpunkt | passt zu einer bekannten Aktion, etwa Mailversand | nachts, ohne Nutzeraktivität, gehäuft |
Wenn Sie nicht wissen, ob Ihre Anwendung Programme aufruft, fragen Sie den Entwickler oder suchen Sie im Code nach Funktionen wie exec, shell_exec, system, passthru, proc_open und popen. Treffer im eigenen Code sind normal, Treffer in unbekannten Dateien nicht.
Dauerhaft überwachen statt einmal nachsehen
Eine Momentaufnahme mit ps erwischt nur Shells, die gerade laufen. Kurzlebige Prozesse rutschen durch. Verlässlicher ist es, Programmstarts durch den Webserver-Benutzer dauerhaft zu protokollieren. Unter Linux leistet das der Audit-Dienst auditd mit einer Regel für Programmstarts des Webserver-Benutzers. Ausgewertet wird lesend:
# Protokollierte Programmstarts unter einem Regel-Schlüssel anzeigen (Schlüssel als Beispiel)
sudo ausearch -k web_exec --start today -i | grep -E "exe=|proctitle="
Wie die Regel aussieht, hängt von Distribution und Benutzer-ID ab; testen Sie sie zuerst, denn auf stark belasteten Servern entstehen viele Einträge.
Zwei Ergänzungen machen die Überwachung belastbar. Erstens sollten die Protokolle zusätzlich an ein zentrales System gehen, denn ein Angreifer mit Root-Rechten kann lokale Logs löschen. Zweitens braucht es eine Alarmierung: Ein Programmstart des Webserver-Benutzers, der nicht auf einer kurzen Liste erwarteter Programme steht, sollte eine Meldung auslösen, nicht nur einen Logeintrag. Wer bereits eine Lösung zur Erkennung auf Endgeräten oder Servern einsetzt, kann dieselbe Regel dort abbilden. Vorbeugend lässt sich mit disable_functions sperren, was die Anwendung nicht braucht. Das schliesst keine Lücke im Interpreter, erschwert aber den nächsten Schritt eines Angreifers. Details stehen unter disable_functions richtig nutzen.
Was tun, wenn Sie eine Shell unter dem Webserver finden
- Dokumentieren: Ausgabe von
ps, Kommandozeile, Arbeitsverzeichnis und offene Verbindungen in eine Datei ausserhalb des Webverzeichnisses sichern. - Nicht aufräumen: Keine Dateien löschen und keine Prozesse beenden, bevor die Spuren gesichert sind.
- Isolieren: Den Server vom Netz nehmen oder den Zugriff stark einschränken.
- Ursache suchen: Logs, neue Dateien und Persistenz wie Cronjobs prüfen, siehe Verdächtige Prozesse auf Linux-Servern finden.
- Zugänge wechseln: Alle Passwörter und Schlüssel, die auf dem Server lagen, gelten als bekannt.
Läuft die Anwendung in Containern, gilt dasselbe Prinzip im Kleinen. Eine Shell im PHP-Container ist ebenso verdächtig wie auf einem klassischen Server, und Container-Images enthalten sie oft nur, weil das Basis-Image sie mitbringt. Sichern Sie vor dem Neustart des Containers dessen Zustand, denn mit dem Container verschwinden auch die Spuren im flüchtigen Dateisystem.
Prüfen Sie ausserdem die Nachbarschaft. Ein Angreifer mit Shell auf einem Webserver versucht häufig, von dort andere Systeme zu erreichen, etwa die Datenbank, Backup-Speicher oder interne Verwaltungsoberflächen. Zugangsdaten in Konfigurationsdateien der Anwendung machen ihm das leicht.
Eine lange laufende Shell unter PHP-FPM auf einem Server mit Kundendaten ist ein Sicherheitsvorfall. Behandeln Sie sie so: sichern, isolieren, strukturiert aufarbeiten, Meldepflichten prüfen lassen.
Wie hilft PHP SOS konkret?
- Befund einordnen: Wir prüfen Prozessbaum, Kommandozeilen und Verbindungen und trennen Anwendungsverhalten von Einbruchsspuren.
- Spuren sichern: Wir sichern den Systemzustand nachvollziehbar, bevor etwas verändert wird.
- Vorfall bearbeiten: Mit der Incident Response führen wir von der Eindämmung bis zum dokumentierten Abschluss.
- Dauerhaft absichern: Wir richten die Protokollierung von Programmstarts ein und begrenzen die PHP-Funktionen auf das Nötige. Wie PHP-FPM intern arbeitet, erklärt PHP-FPM erklärt.
Häufige Fragen
Ist jede Shell unter PHP-FPM ein Angriff?
Nicht jede. Manche Anwendungen rufen über PHP bewusst Programme auf, etwa für Bildbearbeitung oder Mailversand, und dabei kann kurz eine Shell entstehen. Verdächtig wird es, wenn die Shell länger läuft, Netzwerkwerkzeuge startet oder aus untypischen Verzeichnissen arbeitet.
Sollte ich den verdächtigen Prozess sofort beenden?
Erst dokumentieren, dann handeln. Halten Sie Prozessdaten, Kommandozeile, Arbeitsverzeichnis und Netzwerkverbindungen fest. Danach isolieren Sie den Server. Ein vorschnelles Beenden zerstört Spuren und verhindert nicht, dass der Angreifer zurückkommt.
Gibt es für PHP2Shell bestätigte Erkennungsmerkmale?
Nein. Es gibt keine veröffentlichten, bestätigten Indicators of Compromise. Shells unter dem Webserver sind ein allgemeines Warnsignal für Einbrüche über Webanwendungen, nicht spezifisch für PHP2Shell.
Wie verhindere ich, dass PHP überhaupt Shells startet?
Über disable_functions lassen sich Funktionen wie exec, shell_exec, system und proc_open sperren, wenn die Anwendung sie nicht braucht. Das schliesst keine Lücke im PHP-Interpreter, erschwert aber die Ausnutzung.