Objectif
Remettre en service un site WordPress après compromission sans se limiter à supprimer le fichier visible, en préservant les éléments d’investigation, en corrigeant le vecteur initial, en reconstruisant les composants depuis des sources fiables et en révoquant toutes les identités ou secrets qui auraient pu être exposés.
Prérequis
- Accès hébergement/SSH/FTP, base de données, DNS
- Emplacement sécurisé pour exporter fichiers, base et logs avant nettoyage.
- Sauvegardes datées et historique des dernières mises à jour ou vulnérabilités connues.
- Possibilité de mettre le site en maintenance ou de travailler sur un clone isolé.
- Liste des secrets à tourner : hébergeur, SFTP/SSH, base, WordPress, API, SMTP et clés/salts.
Procédure pas à pas
Contenir sans détruire les preuves
Placez le site en maintenance ou limitez temporairement l’accès si l’activité malveillante est en cours. Copiez le document root, exportez la base et conservez les logs web, WAF, FTP/SSH et authentification. Notez l’heure, le premier signal et les fichiers récemment modifiés. Travaillez idéalement sur un clone.
tar -czf wordpress-compromis-$(date +%F-%H%M).tar.gz <DOCROOT>
wp db export wordpress-compromis.sql
- Un état avant nettoyage est conservé hors du serveur compromis.
Inventorier les comptes et sessions
Listez les administrateurs WordPress, comptes SFTP/SSH et utilisateurs de l’hébergeur. Recherchez un compte créé récemment ou une élévation inattendue. Révoquez les accès manifestement non légitimes mais conservez leur identité dans le rapport. Si l’attaque implique un compte humain, changez le secret depuis un poste sain et activez MFA.
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
- Seuls les comptes attendus gardent des privilèges administrateur.
Vérifier l’intégrité du cœur WordPress
WP-CLI peut comparer le cœur installé aux checksums officiels sans charger WordPress. Utilisez include-root pour signaler aussi les fichiers inhabituels à la racine. Une différence n’est pas automatiquement malveillante, mais chaque fichier du cœur modifié doit être expliqué ou remplacé par une copie officielle de la même version.
wp core verify-checksums --include-root --version=$(wp core version)
- Les écarts de cœur sont identifiés et expliqués avant remplacement.
Vérifier plugins et thèmes
Listez les extensions actives, mu-plugins et thèmes. Utilisez les checksums quand ils existent pour les extensions WordPress.org ; pour les plugins premium ou maison, comparez aux archives d’origine ou au dépôt de code. Recherchez surtout les PHP récemment modifiés et les répertoires inconnus dans uploads.
wp plugin list
wp theme list
wp plugin verify-checksums --all --strict
find wp-content -type f -name '*.php' -mtime -14 -print
- Les composants légitimes sont distingués des ajouts ou modifications non autorisés.
Reconstruire depuis des sources fiables
Réinstallez le cœur, plugins et thèmes depuis leurs sources officielles ou vos artefacts validés. Supprimez les extensions inutilisées et les fichiers étrangers uniquement après conservation des preuves. Une reconstruction propre est souvent plus fiable qu’un nettoyage ligne par ligne lorsque l’intégrité n’est plus certaine.
wp core download --force --version=$(wp core version)
- Le code exécutable provient de sources connues et les composants inutiles sont retirés.
Inspecter la base de données
Contrôlez wp_users/wp_usermeta, options autoload, siteurl/home, tâches cron, widgets, contenu et redirections. Cherchez du JavaScript ou iframe injecté dans des options ou contenus. N’exécutez pas de recherche/remplacement global sans sauvegarde : les données sérialisées doivent être manipulées avec des outils WordPress adaptés.
wp option get home
wp option get siteurl
wp cron event list
- Aucun administrateur, cron ou contenu injecté inconnu ne subsiste.
Corriger le vecteur initial
Identifiez la cause la plus probable : extension vulnérable, mot de passe réutilisé, compte hébergeur compromis, fichier upload exécutable, permissions trop larges ou autre site du même compte. Mettez à jour ou retirez le composant, corrigez les permissions et examinez les autres sites hébergés sous le même utilisateur.
- La remise en ligne ne réintroduit pas le même chemin d’attaque.
Tourner les secrets et clés
Changez mots de passe hébergeur, SFTP/SSH, base, WordPress, SMTP et API susceptibles d’avoir été lus. Révoquez les sessions et mots de passe d’application. Régénérez les salts WordPress si wp-config.php a pu être exposé. Ne stockez pas les nouveaux secrets dans le ticket d’incident.
- Les anciennes sessions et secrets ne permettent plus de reprendre l’accès.
Renforcer puis surveiller la récidive
Activez MFA pour les comptes administratifs, mises à jour maîtrisées, sauvegardes externes et surveillance de fichiers/logins. Après réouverture, surveillez plusieurs jours les modifications, nouveaux comptes, tâches cron et requêtes inhabituelles. Vérifiez aussi que les scanners externes et moteurs de recherche ne voient plus de redirection ou contenu injecté.
- Aucun indicateur de persistance ne réapparaît pendant la période de surveillance.
Validation
La procédure est validée lorsque :
- Le cœur et les composants connus passent les contrôles d’intégrité applicables.
- Aucun compte, cron, mu-plugin ou fichier inconnu ne réapparaît après remise en ligne.
- Le vecteur initial est corrigé ou, s’il reste incertain, les contrôles compensatoires et la surveillance sont documentés.
- Une sauvegarde propre post-incident est créée et une restauration de contrôle est possible.
Retour arrière
- Si l’intégrité ne peut pas être démontrée, restaurer une sauvegarde antérieure connue saine sur un environnement propre.
- Ne remettre une sauvegarde en production qu’après patch du vecteur initial et rotation des secrets.
- Conserver l’image compromise et les logs pour investigation au lieu de les réinjecter dans la production.
- Si une extension remise à jour provoque une régression, revenir à une version saine supportée, pas au composant vulnérable.
Dépannage / erreurs fréquentes
- Les fichiers malveillants reviennent : chercher persistance dans cron, mu-plugins, base, autre site du compte ou accès hébergeur.
- Checksums plugin indisponibles : comparer à l’archive éditeur ou au dépôt, ce n’est pas automatiquement une compromission.
- Site propre mais redirection persiste : vérifier cache/CDN, base, .htaccess/nginx et service worker.
- Nouveaux admins après rotation : l’hébergement ou le poste d’administration peut encore être compromis.
- Impossible de dater l’intrusion : conserver les sauvegardes de part et d’autre de la fenêtre et éviter d’affirmer une cause non prouvée.