Kurz gesagt: Um unbekannte SSH-Schlüssel zu finden, müssen Sie alle authorized_keys-Dateien auf dem Server prüfen, nicht nur die von root. Ermitteln Sie mit sshd -T, welche Dateien Ihr SSH-Dienst liest, listen Sie die Fingerabdrücke jedes Schlüssels auf und gleichen Sie sie mit den bekannten Schlüsseln ab. Fremde Einträge zuerst sichern, dann entfernen und den Zugang anschließend härten.
Der Schlüssel, der jeden Passwortwechsel übersteht
Nach einem Vorfall ändern viele Betreiber als Erstes alle Passwörter. Gegen eine der unauffälligsten Hintertüren hilft das nicht: einen zusätzlichen öffentlichen Schlüssel in einer authorized_keys-Datei. Wer den passenden privaten Schlüssel besitzt, meldet sich ohne Passwort an, so lange, bis jemand die Zeile findet.
Unbekannte SSH-Schlüssel gehören deshalb zu den Anzeichen, die nach einer Codeausführung immer geprüft werden sollten. Für PHP2Shell gibt es keine veröffentlichten, bestätigten Indicators of Compromise; die Erkennung beruht auf Verhaltensanalyse. Ein fremder Schlüssel ist kein spezifischer PHP2Shell-Beleg, aber ein klares Zeichen dafür, dass jemand dauerhaften Zugang wollte. Weitere Anzeichen beschreibt Bin ich schon kompromittiert?.
Wo SSH-Schlüssel auf dem Server liegen
OpenSSH liest laut Dokumentation standardmäßig zwei Dateien im Home-Verzeichnis jedes Benutzers: .ssh/authorized_keys und .ssh/authorized_keys2. Die zweite wird oft vergessen. Die Einstellung lässt sich ändern, und mit AuthorizedKeysCommand kann der Server Schlüssel sogar aus einem externen Programm beziehen. Prüfen Sie daher zuerst, was auf Ihrem Server tatsächlich gilt:
# Effektive SSH-Konfiguration ausgeben (nur lesend)
sudo sshd -T | grep -iE '^(authorizedkeysfile|authorizedkeyscommand|permitrootlogin|passwordauthentication|pubkeyauthentication)'
# Zusätzliche Konfigurationsdateien und Match-Blöcke
ls -la /etc/ssh/sshd_config.d/ 2>/dev/null
sudo grep -rn -iE '^\s*(Match|AuthorizedKeys)' /etc/ssh/
Ein besonderer Ort ist das Home-Verzeichnis des Webserver-Benutzers. Unter Debian und Ubuntu ist das für www-data häufig /var/www. Ist dieses Verzeichnis für PHP beschreibbar, kann eingeschleuster Code dort eine .ssh/authorized_keys anlegen. Ob die Anmeldung dann gelingt, hängt von Login-Shell und SSH-Einstellungen ab, die Datei selbst ist aber schon ein Alarmzeichen.
Nicht jeder unbekannte Eintrag ist böswillig. Deployment-Werkzeuge, Backup-Dienste oder frühere Dienstleister hinterlegen eigene Schlüssel. Solche Einträge sollten aber einen bekannten Besitzer und Zweck haben.
authorized_keys prüfen: Schritt für Schritt
Die folgenden Befehle verändern nichts. Sie listen alle Schlüsseldateien der Benutzer und zeigen für jeden Schlüssel den Fingerabdruck:
# Alle authorized_keys-Dateien in den Home-Verzeichnissen aller Benutzer
getent passwd | cut -d: -f1,6 | while IFS=: read -r user home; do
for f in "$home/.ssh/authorized_keys" "$home/.ssh/authorized_keys2"; do
[ -f "$f" ] && echo "== $user: $f" && sudo ls -la --time-style=full-iso "$f"
done
done
# Fingerabdrücke und Kommentare einer Datei anzeigen
sudo ssh-keygen -lf /root/.ssh/authorized_keys
# Weitere Schlüsseldateien außerhalb der üblichen Orte
sudo find / -xdev -name 'authorized_keys*' 2>/dev/null
Gehen Sie das Ergebnis mit dieser Prüfliste durch:
- Gehört jeder Schlüssel einer bekannten Person oder einem bekannten Dienst? Gleichen Sie die Fingerabdrücke ab, nicht nur den Kommentar.
- Hat ein Benutzer Schlüssel, der gar keine haben sollte? Etwa der Webserver-Benutzer, Datenbank- oder Dienstkonten.
- Stehen Optionen vor dem Schlüssel? Einträge mit
command=führen bei jeder Anmeldung einen festen Befehl aus. Das ist legitim für Backups, aber auch ein Versteck. - Wann wurde die Datei zuletzt geändert? Ein Änderungsdatum nach dem 17.10.2026, dem laut Medienberichten ersten beobachteten PHP2Shell-Angriffsversuch, verdient besondere Aufmerksamkeit. Zeitstempel lassen sich aber fälschen.
- Stimmen Eigentümer und Rechte? Eine Datei, die einem anderen Benutzer gehört als dem Home-Verzeichnis, ist auffällig.
Fremde Schlüssel sicher entfernen
Bevor Sie eine Zeile löschen, sichern Sie die Datei mit Zeitstempel und Prüfsumme außerhalb des Servers. Notieren Sie den Fingerabdruck des fremden Schlüssels. Er hilft später bei der Frage, ob derselbe Schlüssel auch auf anderen Servern auftaucht, etwa bei einer Agentur mit vielen Kundensystemen.
Prüfen Sie außerdem die Anmeldeprotokolle. In /var/log/auth.log (Debian, Ubuntu) oder /var/log/secure (RHEL-Familie) protokolliert der SSH-Dienst erfolgreiche Anmeldungen mit dem Fingerabdruck des verwendeten Schlüssels. So sehen Sie, ob der fremde Schlüssel schon benutzt wurde und von welcher Adresse.
Denken Sie auch an die Gegenrichtung. Liegen auf dem Server private Schlüssel, etwa unter ~/.ssh/id_* für Deployments oder Backups, konnte ein Angreifer sie kopieren. Mit ihnen erreicht er womöglich andere Server, Git-Repositories oder Backup-Ziele. Solche Schlüssel gelten nach einem Einbruch als verbraucht: neue Schlüssel erzeugen und die alten auf allen Zielsystemen entfernen.
Ein fremder Schlüssel ist selten die einzige Spur. Wer ihn hinterlegt hat, hatte Schreibrechte und hat womöglich weitere Wege eingerichtet, etwa Cronjobs oder zusätzliche Konten. Prüfen Sie deshalb auch versteckte Cronjobs und fremde Admin-Konten. Hatte der Angreifer Root-Rechte, ist ein Neuaufbau des Servers oft verlässlicher als eine Bereinigung.
Entfernen Sie fremde Schlüssel erst, wenn PHP auf einem behobenen Stand ist (8.5.12, 8.4.27, 8.3.36, 8.2.35 oder bestätigter Backport) und alle Worker neu gestartet sind. Sonst kann der Angreifer den Schlüssel über dieselbe Lücke sofort wieder eintragen.
Den SSH-Zugang danach härten
Nach der Bereinigung lohnt eine kurze Härtung. Die meisten Punkte sind schnell umgesetzt, sollten aber immer mit einer zweiten, offenen Sitzung getestet werden, damit Sie sich nicht aussperren.
| Maßnahme | Einstellung oder Vorgehen |
|---|---|
| Anmeldung nur per Schlüssel | PasswordAuthentication no |
| Root nicht direkt anmelden lassen | PermitRootLogin no, Arbeit über persönliche Konten mit sudo |
| Zweite Schlüsseldatei abschalten | AuthorizedKeysFile .ssh/authorized_keys |
| Schlüssel auf Herkunft begrenzen | Option from= vor dem Schlüssel, etwa für Backup-Server |
| Dienstschlüssel einschränken | Option restrict und festes command= für Automatisierung |
| Webserver-Benutzer ohne Login | Login-Shell nologin, keine .ssh im Home-Verzeichnis |
Führen Sie außerdem eine Liste aller berechtigten Schlüssel mit Besitzer und Zweck. Scheidet ein Mitarbeiter oder Dienstleister aus, wird sein Schlüssel auf allen Servern entfernt. Ohne diese Liste ist die nächste Prüfung wieder Detektivarbeit. Anerkannte Härtungsvorgaben für SSH enthalten auch die CIS Benchmarks.
Wie hilft PHP SOS konkret?
- Wir ermitteln, welche Schlüsseldateien Ihr SSH-Dienst wirklich liest, und prüfen jeden Eintrag gegen die bekannten Besitzer.
- Wir sichern Funde und werten die Anmeldeprotokolle aus, um zu klären, ob ein fremder Schlüssel benutzt wurde.
- Wir bereinigen Schlüssel, Konten und Cronjobs in der richtigen Reihenfolge und schließen zuvor die Lücke.
- Im Rahmen der Server-Härtung setzen wir die SSH-Einstellungen um und richten eine Schlüsselverwaltung mit Besitzerliste ein.
Häufige Fragen
Wie erkenne ich, ob ein SSH-Schlüssel fremd ist?
Jeder Schlüssel hat einen Fingerabdruck und meist einen Kommentar am Zeilenende. Gleichen Sie die Fingerabdrücke mit den Schlüsseln Ihrer Mitarbeiter und Dienstleister ab. Der Kommentar allein beweist nichts, denn er ist frei wählbar und lässt sich fälschen.
Hilft es, das Root-Passwort zu ändern?
Gegen einen eingeschleusten Schlüssel nicht. Die Anmeldung per Schlüssel braucht kein Passwort. Deshalb müssen die authorized_keys-Dateien selbst geprüft und bereinigt werden.
Warum kann der Webserver-Benutzer einen SSH-Schlüssel haben?
Der Webserver-Benutzer hat ein eigenes Home-Verzeichnis, unter Debian und Ubuntu oft /var/www. Liegt dort eine .ssh/authorized_keys und hat das Konto eine Login-Shell, ist eine Anmeldung als dieser Benutzer möglich. Bei schreibbarem Webverzeichnis kann eingeschleuster PHP-Code eine solche Datei anlegen.
Was ist authorized_keys2?
Eine ältere zweite Datei, die OpenSSH laut Standardeinstellung ebenfalls liest. Viele Prüfanleitungen übersehen sie. Kontrollieren Sie mit sshd -T, welche Dateien Ihr Server tatsächlich auswertet.