En bref : pour trouver des clés SSH inconnues, vous devez vérifier tous les fichiers authorized_keys du serveur, pas seulement celui de root. Déterminez avec sshd -T quels fichiers lit votre service SSH, listez les empreintes de chaque clé et comparez-les avec les clés connues. Sauvegardez d'abord les entrées étrangères, supprimez-les ensuite, puis durcissez l'accès.
La clé qui survit à tout changement de mot de passe
Après un incident, de nombreux exploitants changent d'abord tous les mots de passe. Contre l'une des portes dérobées les plus discrètes, cela n'aide pas : une clé publique supplémentaire dans un fichier authorized_keys. Qui possède la clé privée correspondante se connecte sans mot de passe, tant que personne n'a trouvé la ligne.
Les clés SSH inconnues font donc partie des signes qui devraient toujours être vérifiés après une exécution de code. Pour PHP2Shell, il n'existe pas d'indicateurs de compromission (Indicators of Compromise) publiés et confirmés ; la détection repose sur l'analyse du comportement. Une clé étrangère n'est pas une preuve spécifique de PHP2Shell, mais un signe net que quelqu'un voulait un accès durable. D'autres signes sont décrits dans Suis-je déjà compromis ?.
Où se trouvent les clés SSH sur le serveur
Selon la documentation, OpenSSH lit par défaut deux fichiers dans le répertoire personnel de chaque utilisateur : .ssh/authorized_keys et .ssh/authorized_keys2. Le second est souvent oublié. Le réglage peut être modifié, et avec AuthorizedKeysCommand, le serveur peut même obtenir des clés d'un programme externe. Vérifiez donc d'abord ce qui s'applique réellement sur votre serveur :
# Afficher la configuration SSH effective (lecture seule)
sudo sshd -T | grep -iE '^(authorizedkeysfile|authorizedkeyscommand|permitrootlogin|passwordauthentication|pubkeyauthentication)'
# Fichiers de configuration supplémentaires et blocs Match
ls -la /etc/ssh/sshd_config.d/ 2>/dev/null
sudo grep -rn -iE '^\s*(Match|AuthorizedKeys)' /etc/ssh/
Un endroit particulier est le répertoire personnel de l'utilisateur du serveur web. Sous Debian et Ubuntu, c'est souvent /var/www pour www-data. Si ce répertoire est accessible en écriture pour PHP, du code injecté peut y créer un .ssh/authorized_keys. Que la connexion réussisse ensuite dépend du shell de connexion et des réglages SSH, mais le fichier lui-même est déjà un signe d'alarme.
Toute entrée inconnue n'est pas malveillante. Des outils de déploiement, des services de sauvegarde ou d'anciens prestataires déposent leurs propres clés. De telles entrées devraient toutefois avoir un propriétaire et un objet connus.
Vérifier authorized_keys : pas à pas
Les commandes suivantes ne modifient rien. Elles listent tous les fichiers de clés des utilisateurs et affichent l'empreinte de chaque clé :
# Tous les fichiers authorized_keys dans les répertoires personnels de tous les utilisateurs
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
# Afficher les empreintes et commentaires d'un fichier
sudo ssh-keygen -lf /root/.ssh/authorized_keys
# Autres fichiers de clés en dehors des emplacements habituels
sudo find / -xdev -name 'authorized_keys*' 2>/dev/null
Passez en revue le résultat avec cette liste de contrôle :
- Chaque clé appartient-elle à une personne ou à un service connu ? Comparez les empreintes, pas seulement le commentaire.
- Un utilisateur a-t-il une clé alors qu'il ne devrait pas en avoir ? Par exemple l'utilisateur du serveur web, ou des comptes de base de données ou de service.
- Y a-t-il des options devant la clé ? Les entrées avec
command=exécutent une commande fixe à chaque connexion. C'est légitime pour des sauvegardes, mais aussi une cachette. - Quand le fichier a-t-il été modifié pour la dernière fois ? Une date de modification après le 17/10/2026, première tentative d'attaque PHP2Shell observée selon les médias, mérite une attention particulière. Les horodatages peuvent toutefois être falsifiés.
- Le propriétaire et les droits sont-ils cohérents ? Un fichier qui appartient à un autre utilisateur que celui du répertoire personnel est remarquable.
Supprimer en sécurité les clés étrangères
Avant de supprimer une ligne, sauvegardez le fichier avec horodatage et somme de contrôle hors du serveur. Notez l'empreinte de la clé étrangère. Elle aide plus tard à savoir si la même clé apparaît aussi sur d'autres serveurs, par exemple pour une agence gérant de nombreux systèmes clients.
Vérifiez en outre les journaux de connexion. Dans /var/log/auth.log (Debian, Ubuntu) ou /var/log/secure (famille RHEL), le service SSH journalise les connexions réussies avec l'empreinte de la clé utilisée. Vous voyez ainsi si la clé étrangère a déjà été utilisée et depuis quelle adresse.
Pensez aussi au sens inverse. Si des clés privées se trouvent sur le serveur, par exemple sous ~/.ssh/id_* pour des déploiements ou des sauvegardes, un attaquant a pu les copier. Avec elles, il atteint peut-être d'autres serveurs, dépôts Git ou destinations de sauvegarde. De telles clés sont considérées comme compromises après une intrusion : générer de nouvelles clés et supprimer les anciennes sur tous les systèmes cibles.
Une clé étrangère est rarement la seule trace. Qui l'a déposée avait des droits d'écriture et a peut-être mis en place d'autres voies, par exemple des tâches cron ou des comptes supplémentaires. Vérifiez donc aussi les tâches cron cachées et les comptes admin inconnus. Si l'attaquant avait les droits root, une reconstruction du serveur est souvent plus fiable qu'un nettoyage.
Ne supprimez les clés étrangères que lorsque PHP est à un état corrigé (8.5.12, 8.4.27, 8.3.36, 8.2.35 ou rétroportage confirmé) et que tous les workers ont été redémarrés. Sinon, l'attaquant peut réinscrire immédiatement la clé par la même faille.
Durcir ensuite l'accès SSH
Après le nettoyage, un court durcissement vaut la peine. La plupart des points sont vite mis en œuvre, mais devraient toujours être testés avec une seconde session ouverte, afin que vous ne vous enfermiez pas dehors.
| Mesure | Réglage ou procédure |
|---|---|
| Connexion par clé uniquement | PasswordAuthentication no |
| Ne pas autoriser la connexion directe de root | PermitRootLogin no, travail via des comptes personnels avec sudo |
| Désactiver le second fichier de clés | AuthorizedKeysFile .ssh/authorized_keys |
| Limiter les clés selon la provenance | option from= devant la clé, par exemple pour les serveurs de sauvegarde |
| Restreindre les clés de service | option restrict et command= fixe pour l'automatisation |
| Utilisateur du serveur web sans connexion | shell de connexion nologin, pas de .ssh dans le répertoire personnel |
Tenez en outre une liste de toutes les clés autorisées avec propriétaire et objet. Lorsqu'un collaborateur ou un prestataire part, sa clé est supprimée sur tous les serveurs. Sans cette liste, la prochaine vérification redevient un travail de détective. Les CIS Benchmarks contiennent aussi des recommandations de durcissement reconnues pour SSH.
Comment PHP SOS aide-t-il concrètement ?
- Nous déterminons quels fichiers de clés votre service SSH lit réellement et vérifions chaque entrée par rapport aux propriétaires connus.
- Nous sauvegardons les découvertes et exploitons les journaux de connexion pour établir si une clé étrangère a été utilisée.
- Nous nettoyons clés, comptes et tâches cron dans le bon ordre et fermons auparavant la faille.
- Dans le cadre du durcissement de serveur, nous mettons en œuvre les réglages SSH et mettons en place une gestion des clés avec liste des propriétaires.
Questions fréquentes
Comment reconnaître qu'une clé SSH est étrangère ?
Chaque clé a une empreinte et le plus souvent un commentaire en fin de ligne. Comparez les empreintes avec les clés de vos collaborateurs et prestataires. Le commentaire seul ne prouve rien, car il est librement choisi et peut être falsifié.
Changer le mot de passe root aide-t-il ?
Pas contre une clé injectée. La connexion par clé n'a pas besoin de mot de passe. Les fichiers authorized_keys eux-mêmes doivent donc être vérifiés et nettoyés.
Pourquoi l'utilisateur du serveur web peut-il avoir une clé SSH ?
L'utilisateur du serveur web a son propre répertoire personnel, sous Debian et Ubuntu souvent /var/www. Si un .ssh/authorized_keys s'y trouve et que le compte a un shell de connexion, une connexion en tant que cet utilisateur est possible. Si le répertoire web est accessible en écriture, du code PHP injecté peut créer un tel fichier.
Qu'est-ce que authorized_keys2 ?
Un second fichier plus ancien que OpenSSH lit lui aussi selon le réglage par défaut. De nombreux guides de vérification l'oublient. Contrôlez avec sshd -T quels fichiers votre serveur exploite réellement.