Scanner malware WordPress : corriger les vulnérabilités après nettoyage

Quand un site WordPress est infecté, la tentation est simple: nettoyer, remettre en ligne, aller vite. Le problème, c’est que beaucoup d’attaques ne se résument pas à “un fichier malveillant” ou “un plugin qui a été compromis”. Souvent, la compromission laisse derrière elle des portes dérobées, des comptes dont les identifiants ne sont pas vraiment “nettoyés”, ou des paramètres qui continuent de donner de l’oxygène au prochain nettoyage.

J’ai vu des sites revenir au bout de quelques jours, parfois même en moins de 24 heures. Le mécanisme était rarement “un nouveau piratage” au sens strict. Plus souvent, c’était une vulnérabilité restée en place, ou une persistance déjà installée: un cron malveillant, une modification de fichiers au chargement, un script qui se réinsère après suppression, ou une base qui garde des entrées altérées. C’est pour ça que la phase “après nettoyage” compte autant que la suppression initiale.

Ce billet explique comment penser le problème comme une série de contrôles orientés preuves, avec une logique de correction des vulnérabilités après que le site a été débarrassé. On va parler de scanner malware WordPress, mais surtout de ce que vous faites ensuite avec les résultats.

Pourquoi “nettoyer” ne suffit pas

Un nettoyage classique consiste à supprimer des fichiers suspects, désactiver ou réinstaller des thèmes et plugins, changer des mots de passe, et vérifier les tâches planifiées. C’est nécessaire. Mais c’est parfois insuffisant parce que les causes racines sont multiples:

    une mise à jour manquée côté WordPress, thème ou plugin, qui ouvre une faille connue; des permissions trop larges (fichiers modifiables par le mauvais user, dossier accessible en écriture); des identifiants compromis qui restent valides pour l’attaquant; une configuration web qui permet l’exécution de scripts dans des répertoires inattendus; une chaîne de compromission plus profonde, par exemple modification de la base de données via une injection, ou ajout de code via l’éditeur de thème.

Un bon réflexe, c’est de traiter l’incident comme un audit de sécurité, pas comme un dépannage. Un scanner malware WordPress peut vous dire “il y a des fichiers malveillants” ou “des signatures correspondent à X”. Ensuite, il faut répondre à une question plus difficile: “Pourquoi l’attaquant a pu entrer, et comment empêcher la même logique de réapparaître ?”

Un point de départ pragmatique: repartir de preuves, pas d’intuitions

Après nettoyage, vous avez généralement trois types d’indices:

Ce qui a été supprimé (fichiers, lignes, fonctions, endpoints). Ce qui a été détecté mais pas supprimé, ou supprimé sans certitude totale. Ce qui reste incohérent dans la configuration.

Le piège, c’est de considérer que “si tout semble propre maintenant, c’est bon”. J’ai déjà vu des scripts auto-réinsérants, qui ne se révèlent pas au moment du scan, mais qui réapparaissent après un événement, comme un accès précis à une page ou une exécution cron. D’où l’importance de planifier la vérification dans le temps, et pas seulement juste après la restauration.

Le but n’est pas de multiplier les outils. Le but est d’assembler un puzzle cohérent.

Utiliser le scanner malware WordPress sans s’y enfermer

Un scanner malware WordPress est utile pour repérer rapidement des anomalies. Par contre, il a ses limites:

image

    il peut s’appuyer sur des signatures, donc rater des variants; il peut produire des faux positifs, surtout si vous avez des bibliothèques ou des scripts légitimes; il peut détecter une trace sans expliquer la vulnérabilité d’origine.

Ce que je recommande, c’est de considérer le scan comme une étape de tri. Quand un outil pointe un chemin, une entrée base, ou une ligne dans un fichier, vous gagnez surtout du temps pour cibler vos corrections.

Un exemple fréquent: le scanner vous signale des modifications dans des fichiers du répertoire racine ou des thèmes. Vous supprimez, mais la “cause” peut venir d’un plugin vulnérable ou d’un compte admin ayant encore des droits trop larges. Tant que la cause n’est pas corrigée, l’attaque peut revenir avec un autre fichier.

À ce stade, je préfère raisonner en trois couches: code et fichiers, comptes et accès, configuration serveur et exécution.

Recontrôler l’intégrité des fichiers: où la plupart des histoires échouent

Après nettoyage, on vérifie souvent seulement “les fichiers du thème” ou “ceux que le scan a pointés”. C’est normal, mais insuffisant. L’attaquant cherche souvent à rester dans des zones qui ne déclenchent pas forcément une alerte immédiate.

Concrètement, je surveille:

    les fichiers PHP modifiés en dehors des mises à jour habituelles; les fichiers dans des répertoires qui ne devraient pas contenir de PHP (uploads, caches, templates custom, certains dossiers de plugins); les ajouts de code dans des fichiers d’amorçage, comme des hooks, des inclusions, des fonctions de thème.

Si vous avez un contrôle d’intégrité côté hébergement (certains environnements proposent des comparaisons à une référence), profitez-en. Sinon, utilisez une approche “diff” en comparant avec une source saine: même version WordPress, même ensemble de thèmes et plugins (au moins pour les parties standard).

Et surtout, vérifiez la cohérence des timestamps. Un changement “récent” sur un fichier core ou un fichier que vous n’avez pas touché est un signal. Ce signal n’est pas une preuve à lui seul, mais il vous oriente vers ce qui mérite une validation ligne par ligne.

Base de données: les modifications qui se cachent derrière l’apparence

Une fois, j’ai supprimé des scripts côté fichiers, tout était “propre” en apparence. Le site affichait toujours des comportements étranges sur certaines pages. Au final, la base contenait des modifications persistantes, notamment via des entrées liées aux options, aux champs stockés dans la configuration, ou à des champs textuels utilisés dans le rendu.

WordPress stocke beaucoup de choses dans la base. Un attaquant peut:

    modifier des options globales; ajouter des scripts ou des contenus dans des champs exploités ensuite par le thème; créer des comptes ou altérer des métadonnées.

Après nettoyage, je conseille de valider la base avec des contrôles ciblés. Un scan malware WordPress peut parfois indiquer des tables ou des champs à inspecter. Si votre outil ne le fait pas, vous pouvez aussi adopter une vérification pratique: comparez les valeurs critiques (URL, options de cache, paramètres de debug, configurations d’authentification) avec une copie de référence quand elle existe, ou au minimum avec ce que vous aviez avant l’incident.

Dans les cas où vous n’avez aucune copie, la méthode “prudente” consiste à reconstruire un site à partir de sources propres et à migrer seulement le nécessaire (contenus et médias) après avoir sécurisé la couche d’accès. Ce n’est pas toujours rapide, mais c’est souvent plus sûr que “rattraper” en patchant un puzzle impossible à reconstituer.

Les comptes et sessions: la persistance la plus sous-estimée

Un nettoyage réussit souvent à supprimer le code visible, mais l’attaquant peut rester via un compte. Parfois, il ne s’agit pas de “quelqu’un s’est reconnecté”, mais plutôt de comptes créés ou modifiés avec des rôles étendus.

Voici ce que je vérifie systématiquement après un incident:

    liste des utilisateurs, rôle par rôle; présence d’utilisateurs inconnus, ou dont le nom d’affichage ne correspond pas à la gestion normale; changements de rôles pour des comptes existants; activité récente, quand elle est disponible (et à défaut, cohérence des dates et événements).

Sur un site de petite équipe, on a tendance à réduire les rôles. Pourtant, le compromis après incident est important: vous devez remettre des droits minimaux. Si un auteur n’a pas besoin d’accéder à l’éditeur de thème, retirez-le. Si un rôle peut modifier des plugins, vérifiez l’appartenance et le besoin.

Ce que je recommande aussi, c’est de forcer une invalidation des sessions quand c’est possible. Selon votre configuration, vous pouvez déconnecter les utilisateurs, régénérer des cookies, et nettoyer les sessions persistantes. L’objectif est simple: même si un identifiant a été capturé, il ne doit plus donner un accès durable.

Revenir au “pourquoi”: corriger la vulnérabilité d’entrée

Le cœur du sujet, ce n’est pas seulement l’éradication, c’est la correction. La question à résoudre est: “Qu’est-ce qui a permis la compromission ?”

Typiquement, l’entrée vient d’un couple vulnérabilité + vecteur. Quelques exemples réalistes, sans supposer un cas unique:

    un plugin obsolète exposant une faille d’exécution de code ou d’édition non autorisée; un thème qui inclut une fonctionnalité dangereuse, ou qui ouvre la voie via un endpoint interne; une configuration d’hébergement qui permet l’exécution dans des répertoires non prévus; un mot de passe faible ou réutilisé, même si le code n’avait pas de faille évidente; un accès trop large à des utilisateurs (éditeur, admin) alors que le site devrait fonctionner avec des droits plus stricts.

Après nettoyage, je fais correspondre les traces du scan avec l’hypothèse la plus probable. Si le scan révèle des modifications liées à un plugin précis, c’est un indice. Si l’outil signale une chaîne de chargement particulière, je cherche le code d’où elle provient, puis je corrige l’origine: mise à jour, suppression du composant, ou modification de l’environnement.

Et si vous ne trouvez pas la cause exacte, vous pouvez quand même réduire la surface d’attaque de manière robuste, sans dépendre d’un diagnostic parfait.

Durcissement WordPress: réduire les chances que “ça revienne”

Corriger “après nettoyage”, c’est aussi durcir. Le durcissement n’est pas une garantie absolue, mais c’est une réduction de probabilité et de dégâts.

Je mets l’accent sur trois axes: mise à jour, séparation des rôles, et exécution côté serveur.

Mettre à jour correctement, pas juste “réinstaller”

La mise à jour doit être cohérente. Si vous mettez à jour WordPress mais laissez un plugin vulnérable, vous ne corrigez pas l’entrée. Si vous réinstallez un thème mais gardez les mêmes paramètres et mêmes hooks compromis, vous réintroduisez un chemin.

Dans les environnements où l’on peut planifier, je procède souvent ainsi: restaurer un état sain, mettre à jour dans un ordre contrôlé, puis re-tester. L’ordre compte. Un plugin incompatible peut casser un site, et cette casse peut vous faire perdre du temps, ou vous inciter à “revenir en arrière” avec des versions vulnérables.

Réduire les droits au minimum utile

Sur WordPress, les rôles trop permissifs sont une porte classique. Un incident réussi signifie que quelqu’un (ou quelque chose) a eu assez de privilèges pour écrire. Donc, après nettoyage, j’évite de laisser des rôles admin inutiles.

C’est aussi là que l’approche “compte dédié” aide. Les comptes https://gardewp.fr/nettoyage-malware-wordpress/ pour la maintenance, la publication, et l’admin technique ne devraient pas se mélanger si l’équipe peut s’organiser.

Contrôler l’exécution serveur et la surface d’accès

La couche serveur, je la traite comme une barrière. On ne gagne pas seulement contre le malware, on gagne contre les erreurs futures.

Quelques points qui reviennent souvent lors d’investigations:

    autoriser l’édition de fichiers via WordPress dans des contextes non prévus; permettre l’exécution PHP dans des dossiers de stockage non conçus pour cela; ouvrir des ports ou des endpoints inutiles; laisser des permissions trop larges côté système de fichiers.

Je ne rentre pas dans des configurations spécifiques à votre hébergeur, mais je vous recommande de vérifier la logique “ce qui est écrit ne doit pas pouvoir s’exécuter librement”.

Une stratégie de vérification après correction: tester, puis observer

Après corrections, vous ne validez pas juste “en ouvrant la page d’accueil”. Les malwares WordPress aiment se manifester sur des chemins précis, ou après un certain délai. J’ai déjà vu un site “normal” dans la navigation principale, mais infecté sur des pages de catégorie, des flux RSS, ou des pages de recherche.

image

La meilleure méthode, c’est d’assigner un petit protocole d’observation, même si vous êtes une petite équipe.

Voici une checklist courte que j’utilise souvent, surtout quand on doit convaincre un client que le risque est réellement réduit:

    Vérifier les fichiers récemment modifiés, au moins sur WordPress core, les thèmes et les plugins actifs Forcer la rotation des identifiants, et supprimer les comptes inconnus ou trop permissifs Inspecter les événements cron et tâches planifiées pour repérer des exécutions inhabituelles Contrôler les options et contenus modifiés dans la base, surtout celles liées au rendu ou aux hooks Tester des pages “suspectes” et parcourir plusieurs entrées SEO, pas seulement l’accueil

L’idée est simple: vous couvrez des zones où les malwares se cachent, sans exiger un audit exhaustif impossible.

Ensuite, j’observe. Si possible, je garde une surveillance sur les logs d’accès et d’erreurs. Même sans être expert syslog, vous pouvez repérer des motifs: requêtes répétées vers des endpoints inexistants, pics d’erreurs PHP, ou pics de 404 sur des chemins bizarres.

Cas particulier: quand le scanner “ne trouve plus rien”, mais que le risque persiste

Parfois, le scanner malware WordPress devient calme après nettoyage. C’est bon signe. Mais si vous n’avez pas corrigé la vulnérabilité d’entrée, le calme peut être temporaire.

Deux scénarios concrets:

    La vulnérabilité existe encore, et l’attaquant peut réexploiter quand il recommence à sonder. L’infection a été neutralisée, mais une porte dérobée reste “inactive” tant qu’un certain état n’est pas déclenché, par exemple la visite d’une page précise ou l’exécution d’un cron.

Dans ces cas, je reviens à l’essentiel: versionning et surface. WordPress, thème, plugins. Comptes. Permissions. Cron. Et exécution serveur. Si tout est cohérent, le fait que le scanner n’ait plus rien devient une validation plus solide.

L’approche “rebuild” quand la confiance baisse

Il y a un moment où vous perdez du temps à “raccorder” des pièces. Si l’infection est ancienne, si vous n’avez pas de sauvegarde propre, ou si les logs sont trop confus, reconstruire peut être la meilleure décision.

Rebuild ne veut pas dire refaire tout le site “à la main”. Ça veut souvent dire: repartir d’une installation propre de WordPress, installer thèmes et plugins uniquement si nécessaires, importer les contenus (articles, pages) et les médias, puis valider.

Le compromis, c’est le coût temps. Mais quand vous additionnez les heures passées à traquer des anomalies sur des fichiers inconnus, la reconstruction devient rationnelle.

Je le fais surtout quand le scan a montré beaucoup de modifications dispersées, et quand les timestamps et la base de données racontent une histoire incohérente. Là, la méthode la plus efficace est souvent celle qui réduit l’hypothèse “quelque chose a été oublié”.

Après l’incident: mettre en place une hygiène de sécurité qui tient

Corriger des vulnérabilités après nettoyage, c’est aussi éviter que la prochaine “bonne année” devienne la prochaine mauvaise. WordPress, avec son écosystème, change vite. Vos procédures doivent changer avec lui.

Je privilégie un cadre qui ne dépend pas d’un seul outil de scan, car les outils ont des angles morts.

Voici ce que je mets en place en général, une fois le site revenu stable:

    un suivi régulier des mises à jour (WordPress, thèmes, plugins) avec un calendrier réaliste; des comptes séparés pour la gestion, la publication et l’administration technique; une politique de mots de passe et rotation si l’incident a impliqué une compromission d’accès; une surveillance des logs et des changements de fichiers (au moins basique); une sauvegarde testée, restaurable, pas seulement “existant”.

Ce dernier point est sous-estimé. Une sauvegarde qui ne se restaure pas, ou qui restaure un état déjà compromis, ne fait pas gagner du temps lors d’une récidive.

Ce que j’éviterais, par expérience

Pour finir, quelques erreurs classiques qui rallongent l’arrêt du site:

On supprime des fichiers, puis on laisse des plugins non mis à jour juste pour “éviter de casser”. On réinitialise les mots de passe, mais on oublie les comptes admin inconnus ou on laisse des rôles trop permissifs. On lance un scanner, puis on arrête tout dès qu’il ne trouve plus rien, sans vérifier cron, base, ou cohérence des versions.

Un site WordPress peut paraître “clean”, tout en ayant un chemin de réexploitation ouvert. Le but après nettoyage, c’est justement de fermer ce chemin, pas seulement de le masquer.

En pratique: un plan court pour vos prochaines 24 à 72 heures

Si vous êtes en phase post-cleanup et que vous voulez un cadre concret, voici une manière de structurer votre action sans vous noyer:

image

D’abord, assurez l’intégrité des fichiers sur WordPress core et les éléments qui s’exécutent. Ensuite, passez côté accès, comptes, rôles et sessions. Puis, validez la base de données sur les options et contenus potentiellement modifiés. Enfin, corrigez la vulnérabilité probable, via mises à jour, suppression des composants inutiles, durcissement des permissions et de l’exécution serveur.

Ce n’est pas spectaculaire, mais c’est efficace.

Et si votre scanner malware WordPress vous a donné des indices, utilisez-les comme des points d’ancrage. Pas comme une fin. Le véritable succès, c’est quand la prochaine tentative d’infection se heurte à un site corrigé, cohérent, et moins facile à compromettre.

Si vous me dites votre configuration (type d’hébergement, si vous avez des plugins de sécurité, versions WordPress et principaux plugins, et ce que le scanner a signalé), je peux vous proposer une stratégie de vérification plus ciblée, toujours sans suppositions gratuites.