Scanner malware WordPress : évaluer l’étendue de l’infection

Quand un site WordPress commence à se comporter bizarrement, la tentation est grande de lancer un scanner, attendre un rapport, puis “nettoyer”. Sur le terrain, ça marche rarement si on n’a pas d’abord répondu à une question plus difficile : jusqu’où l’attaque a-t-elle pénétré ?

Évaluer l’étendue de l’infection, c’est ce qui sépare un simple nettoyage de surface d’une reprise de service qui tient dans le temps. Une infection “partielle” peut survivre dans un fichier oublié, un plugin abandonné, un cron interne, ou un compte administrateur nouvellement créé. Et si l’historique des changements est déjà contaminé, vous risquez de restaurer une version qui contient encore le code malveillant.

Je vais détailler une méthode réaliste, centrée sur l’usage d’un scanner malware WordPress, mais surtout sur l’exploitation de ses résultats, la vérification d’hypothèses, et la décision claire entre correction locale, restauration, et reconfiguration plus profonde.

Ce que révèle vraiment un scanner malware WordPress

Un scanner est un indicateur. Pas une preuve absolue.

La plupart des scanners examinent des signatures connues, analysent la structure des fichiers, repèrent des comportements typiques (telles fonctions, appels obfusqués, URLs suspectes) et parfois vérifient l’intégrité contre une base de référence. Mais ils ont trois limites pratiques.

D’abord, tous ne scannent pas avec la même profondeur. Certains vont parcourir le dossier racine et les répertoires standard, d’autres suivent les liens, d’autres encore ignorent des zones comme certains répertoires cachés, des caches ou des uploads atypiques.

Ensuite, la qualité du résultat dépend du contexte. Un faux positif peut vous pousser à supprimer un fichier légitime. À l’inverse, un malware “sur mesure” peut ne pas être reconnu si son code est légèrement modifié.

Enfin, l’étendue ne se lit pas uniquement dans “les fichiers infectés”. Il faut aussi regarder ce que l’attaque a pu faire pendant qu’elle était en place : scripts lancés via cron, comptes utilisateurs créés, droits modifiés, base de données altérée, redirections ajoutées, ou chargement de payload à un endroit que le scanner a raté.

Mon réflexe quand je traite un incident WordPress est simple : je considère le rapport du scanner comme une carte. La mission consiste à valider la route, pas seulement à regarder la légende.

Les signes qui orientent l’échelle du problème

Avant même de lancer le scan, je collecte les signaux. Ça réduit le temps perdu et évite de “poursuivre” un malware alors que le vrai foyer est ailleurs.

Sur un site compromis, on voit souvent l’une de ces situations :

    trafic qui tombe, ou augmentation soudaine de requêtes sur des endpoints inexistants pages qui changent uniquement pour certains visiteurs (par géolocalisation ou User-Agent) erreurs PHP répétées, parfois liées à des fichiers qui n’existaient pas la veille redirections vers des domaines douteux baisse des performances liée à des requêtes internes en boucle ajout d’utilisateurs, ou réinitialisations de mot de passe inexpliquées

Le point crucial, c’est la cohérence temporelle. Si le site a commencé à afficher des redirections “hier”, puis que le scanner trouve des fichiers modifiés “il y a deux semaines”, vous avez peut-être une intrusion plus longue que ce que vos utilisateurs ont perçu.

Dans mes interventions, une infection qui a servi à mettre en place un mécanisme persistant donne rarement un comportement uniforme. Elle produit des anomalies intermittentes, et c’est souvent là que l’étendue devient visible.

Première passe : scanner, mais avec un cadre

Lancer un scanner “en mode automatique” peut suffire pour un premier diagnostic, mais pour évaluer l’étendue, je recommande une approche plus structurée.

Le plus important est de savoir ce que vous scannez réellement. WordPress s’appuie sur plusieurs zones, et une attaque peut viser l’une sans toucher les autres.

Sur un hébergement classique, les zones qui comptent sont :

    les fichiers dans la racine et les répertoires applicatifs (wp-content, wp-includes, wp-admin) les thèmes et plugins, surtout les zones d’uploads et les fichiers PHP personnalisés les fichiers déposés dans wp-content/uploads, y compris des variantes “images” qui contiennent du code la configuration et les scripts côté serveur, parfois via des fichiers de type .htaccess la base de données (options, utilisateurs, tables liées aux plugins)

Un bon scanner malware WordPress vous liste souvent des chemins précis. Le piège consiste à ne traiter que les fichiers listés, surtout si la charge malveillante est déclenchée via une autre porte d’entrée.

image

Avant toute modification, je fais deux choses. Je garde une copie “forensic” des fichiers suspects (même si j’en supprime ensuite certains). Et je note les dates de modification, car elles orientent la chronologie et la persistance.

Lire les résultats comme un enquêteur

Un rapport utile ne vous donne pas seulement “infecté / non infecté”. Il vous donne des indices.

Quand j’analyse les résultats, je cherche trois types d’information :

1) Où se trouve la fonction de déclenchement Certains malwares ne font rien tant qu’ils ne sont pas appelés. Ils sont “silencieux” au quotidien, puis s’activent via une condition, par exemple sur une requête spécifique. Si le scanner marque des fichiers “payload”, mais que les fichiers qui déclenchent l’exécution sont ailleurs, vous risquez d’avoir une impression de nettoyage partiel.

2) Y a-t-il un mécanisme de persistance La persistance peut passer par un plugin modifié, un thème infecté, un fichier ajouté dans un répertoire improbable, ou un cron interne qui recharge le payload.

3) Le malware a-t-il “touché” la base de données Quand la base est atteinte, les chances de réinfection augmentent. Même si vous restaurez les fichiers, une option contaminée peut continuer à réinjecter du code, ou un utilisateur malveillant peut continuer à se connecter.

Un exemple concret, assez fréquent : le scanner repère un fichier obfusqué dans un dossier de plugin. Mais en regardant les options WordPress, on trouve aussi une valeur qui charge ce code à chaque initialisation. Si vous supprimez seulement le fichier, le site retombe en défaut ou redéclenche le chargement via un autre chemin.

Étendue “faible” vs “moyenne” vs “élevée”

Sans tomber dans une grille trop rigide, j’utilise une classification pratique. Elle m’aide à décider du niveau de remise en état.

Étendue faible

Je la soupçonne quand :

    les fichiers malveillants sont localisés, sans modification de thèmes et de plugins multiples aucune anomalie n’apparaît côté base de données (pas de nouveaux utilisateurs, pas d’options incohérentes) les redirections ne sont pas persistantes, ou elles cessent après suppression ciblée

Même dans ce cas, je vérifie quand même la persistance, car une infection “faible” peut être juste la partie visible.

Étendue moyenne

C’est le scénario qui survient souvent après une compromission via un compte ou une faiblesse de plugin :

    plusieurs fichiers modifiés dans wp-content des occurrences de code suspect dans des endroits différents une persistance discrète via des hooks ou des scripts de mise à jour

Ici, la restauration partielle peut échouer. Si un plugin a été altéré, il faut être sûr que les modifications sont bien retirées de tous les endroits.

Étendue élevée

Je la considère probable quand :

    le scanner remonte trop d’éléments, et les dates semblent dispersées sur plusieurs semaines des utilisateurs apparaissent, même après changement de mots de passe des mécanismes serveur ou des scripts externes sont impliqués des traces de modification apparaissent côté base de données, y compris dans des tables d’options, d’éléments d’admin, ou de métadonnées plugin

Dans ce cas, la stratégie la plus fiable est souvent une restauration “clean” depuis une sauvegarde antérieure à l’incident, combinée à un durcissement (désactivation temporaire, rotation des clés, vérification des accès).

La chronologie : le point qui change tout

L’étendue de l’infection ne se juge pas seulement à la taille de la liste du scanner, mais à la séquence des événements.

Si vous savez quand le site a basculé (par exemple, au moment d’une mise à jour plugin, ou d’une connexion suspecte), vous pouvez confronter les dates de modification des fichiers et les logs d’accès.

Même sans avoir une parfaite visibilité serveur, vous pouvez souvent reconstituer une partie de l’histoire :

    logs du serveur (ou de l’hébergement) : pics sur des endpoints étranges, requêtes vers des fichiers non attendus logs WordPress : tentatives de connexion, modifications de profil, erreurs modification times sur les fichiers : utile, mais pas infaillible si un attaquant “normalise” les timestamps historique de déploiement : quelles versions de plugins ont été changées, quand

Dans un cas que j’ai traité, le scanner avait une liste impressionnante de fichiers, mais l’analyse temporelle montrait qu’une seule campagne de modification avait eu lieu sur une courte fenêtre. Une fois le “point d’entrée” identifié, le nettoyage ciblé a réduit le risque de réinfection, contrairement à une restauration immédiate qui aurait ramené des erreurs déjà corrigées entre-temps.

Base de données : vérifier au-delà des fichiers

Un https://gardewp.fr/nettoyage-malware-wordpress/ malware WordPress moderne peut vivre dans la base même si vos fichiers semblent “propres” en apparence.

Le scanner liste parfois des anomalies, mais l’évaluation de l’étendue nécessite d’aller plus loin, en particulier quand vous observez des symptômes persistants après un nettoyage.

Les points à vérifier dans la base ne sont pas forcément “des injections visibles” comme on les imagine. Souvent, ce sont des options ou des métadonnées qui contrôlent le comportement du site.

Je surveille en particulier :

    utilisateurs : nouveaux comptes, rôles admin, dernière connexion incohérente options : valeurs qui pilotent des hooks, des redirections, des chargements de scripts contenus : modifications dans des pages ou articles, parfois avec des modèles ou des blocs compromis plugins et thèmes : traces de modification dans leurs options internes

Il y a un équilibre à trouver. Tout inspecter à la main prend du temps, mais ne rien regarder augmente le risque de réinfection. En pratique, je commence par les éléments qui ont le plus de probabilité de persister, puis j’élargis si des indicateurs remontent.

Persistances typiques que le scanner peut sous-estimer

Même un scanner sérieux peut sous-évaluer certains mécanismes, surtout si le malware est actif seulement dans des conditions précises.

J’ai vu plusieurs formes de persistance revenir fréquemment sur WordPress :

    un plugin ou un thème “modifié légèrement”, avec un simple appel à un fichier externe chargé au runtime un cron interne qui exécute une opération de recharge ou de nettoyage bidon une fonction greffée à un hook commun (par exemple dans un fichier injecté), qui ne fait rien si une condition n’est pas remplie une modification de configuration qui désactive une partie des protections ou redirige vers un chemin alternatif un fichier “qui ne fait rien” à première vue, mais qui contient une logique d’activation obfusquée

Si vous évaluez l’étendue, vous devez supposer que l’attaquant a cherché la durabilité. Le rapport du scanner est un point de départ, pas le dernier mot.

Confronter le scanner à des preuves externes

Le site ne ment pas, au sens où ses réponses HTTP révèlent des comportements anormaux.

Si votre contexte le permet, je fais des tests de surface :

    pages qui redirigent vers un autre domaine ressources statiques qui ne correspondent plus à ce qu’elles devraient être erreurs sur des scripts ou des fichiers inexistants

Et je croise avec des données côté navigateur et réseau, en particulier quand l’infection est conditionnelle.

Dans certains incidents, le scanner indique peu de fichiers, mais le site continue à rediriger sur certaines requêtes. Cela ressemble à une logique de déclenchement par User-Agent, cookies, ou chemin précis. Là, l’étendue peut être “petite en fichiers”, mais “grande en impact” car le code s’active dans le bon contexte.

Choisir la bonne stratégie de réponse selon l’étendue

Une fois l’étendue évaluée, vous avez trois axes : corriger localement, restaurer, ou reconstruire.

La correction locale consiste à supprimer les fichiers compromis, restaurer ceux qui ont été modifiés, réinstaller les plugins et thèmes suspects, puis durcir l’accès. C’est viable quand l’infection est limitée et que la base semble saine.

La restauration est plus adaptée quand vous avez des traces de persistance ou quand l’attaque a touché des zones multiples. Le point délicat est la sauvegarde : une sauvegarde “ancienne” mais prise après l’infection réelle peut vous réinstaller le problème.

La reconstruction complète (dans le sens “repartir d’une base saine et réimporter uniquement le contenu utile”) devient pertinente quand les modifications sont diffuses, ou quand vous ne pouvez pas garantir l’intégrité de l’hébergement.

Dans les équipes, c’est souvent là que les discussions deviennent difficiles. Tout le monde a envie d’une action rapide. Mais si l’étendue est élevée, la vitesse apparente vient d’une hypothèse implicite : “le nettoyage suffira”. Sur WordPress, cette hypothèse échoue trop souvent.

Un protocole de triage pratique en conditions réelles

Voici comment j’organise le triage quand l’objectif est de mesurer l’étendue sans tomber dans l’excès de travail.

image

    Isoler le site, au moins temporairement, pour éviter la propagation et pour stabiliser les symptômes. Lancer un scanner malware WordPress sur l’ensemble des répertoires applicatifs et sur les zones d’uploads, puis relever uniquement les chemins récurrents et ceux liés au déclenchement. Examiner les comptes utilisateurs : rechercher les créations récentes, les rôles élevés, et les incohérences de dernière connexion. Vérifier la base de données sur les éléments à forte probabilité de persistance (options critiques, hooks de plugins, contenus modifiés de manière anormale). Comparer les fichiers modifiés avec vos déploiements attendus, puis décider entre restauration et correction ciblée.

Ce protocole n’est pas un “manuel universel”, mais il évite l’erreur classique : traiter les symptômes immédiats sans valider la persistance.

Indicateurs concrets d’étendue, à collecter avant de toucher au code

Pour décider, il faut des critères. Plutôt que de vous fier au volume de la liste du scanner, je collecte des indicateurs qui changent la décision.

| Indicateur | Ce que ça signale | Impact sur la stratégie | |---|---|---| | Nombre de répertoires touchés (pas seulement de fichiers) | Probabilité d’une intrusion plus large | Favorise restauration si plusieurs zones “logiques” sont touchées | | Dates de modification dispersées | Infection sur durée plutôt que sur une fenêtre | Restauration plus “ancienne” à chercher, ou reconstruction si incertitude | | Changements dans wp-content multiples (plugins et thèmes) | Persistance probable via chargement de code | Correction ciblée uniquement si la base est saine et que tout est vérifié | | Apparition de nouveaux utilisateurs admin | Porte d’entrée récurrente | Rotation des accès obligatoire, et validation base indispensable | | Anomalies persistantes malgré suppression de fichiers listés | Déclenchement ailleurs que dans les fichiers signalés | Investiguer base, hooks, cron, et configuration serveur |

Les indicateurs ne remplacent pas le jugement, mais ils évitent les décisions “émotionnelles”.

Cas particulier : infection déclenchée seulement dans certains contextes

C’est l’un des pièges les plus agaçants. Un scanner voit peu ou rien, mais les visiteurs sont redirigés.

Quand cela arrive, l’évaluation d’étendue doit intégrer la notion d’activation conditionnelle. Le malware peut utiliser :

    des paramètres d’URL spécifiques des cookies des signatures de navigateur (User-Agent) des horaires ou une fréquence (activations intermittentes)

Dans ce contexte, la “taille” de l’infection en fichiers est trompeuse. Si le payload s’active seulement dans certains cas, vous pouvez sous-estimer l’impact et fermer trop vite l’incident.

La stratégie consiste alors à :

    tester des scénarios représentatifs (navigateurs différents, chemins différents) regarder les appels réseau depuis le site dans ces scénarios vérifier les mécanismes qui traitent ces conditions, souvent via des hooks, des fonctions utilitaires modifiées, ou des scripts côté uploads

Après le nettoyage : empêcher la réinfection

Évaluer l’étendue ne sert à rien si vous laissez la porte ouverte. Une infection WordPress passe rarement par “magie”. Il y a presque toujours un point faible : mot de passe, plugin obsolète, thème non maintenu, mauvaise configuration, API exposée, ou compte partagé.

Une fois le site stabilisé, je fais un durcissement minimal mais réel. Par exemple, je m’assure que :

    les mots de passe des comptes à privilèges ont été changés, et que le principe du “je change juste celui qui a été compromis” n’est pas utilisé les plugins et thèmes inutiles sont désinstallés, pas seulement désactivés l’accès admin n’est pas exposé via des vecteurs évidents (comptes partagés, accès trop ouvert, outils tiers non maîtrisés) les mises à jour reprennent de manière disciplinée, avec une fenêtre de validation

Le durcissement est aussi une mesure d’étendue indirecte. Si malgré tout le site se recontamine, c’est un signal qu’il existe encore une persistance non localisée, ou un point d’entrée côté hébergement.

Quand envisager une restauration, même si le scanner “dit” que tout va bien

Il y a une situation où j’insiste sur la restauration, même si les résultats semblent rassurants : quand les symptômes ont une persistance difficile à expliquer.

Par exemple :

    redirections intermittentes visiteurs redirigés mais pas tous traces de code exécuté dans un environnement qui n’est pas celui du scanner délais étranges après nettoyage, où des anomalies reviennent

Le scanner peut ne pas voir le code qui se télécharge ensuite depuis une autre ressource, ou il peut ne pas identifier tous les emplacements. Dans ce cas, la restauration depuis une sauvegarde fiable avant la période suspecte devient le moyen le plus robuste de “réinitialiser” l’état attendu.

Le trade-off, c’est la perte potentielle de modifications récentes. Mais quand l’étendue est incertaine, rester dans le “nettoyage au cas par cas” peut coûter plus cher que le retour arrière.

Ce que je demande à mes équipes avant de valider la fin de l’incident

La fin d’un incident n’est pas un “feu vert” parce que le site réaffiche des pages. Je veux des confirmations.

Avant de considérer l’incident clôturé, il me faut au minimum une combinaison de preuves : absence de déclenchement dans les scénarios observés, comptes admin propres, et cohérence des fichiers et de la base avec l’état attendu.

Et je garde une règle pratique : si vous ne pouvez pas expliquer clairement l’origine, la persistance, et la correction, vous n’avez pas fini. Vous êtes seulement en pause.

Conclusion qui n’en est pas une, parce que l’essentiel est la méthode

L’évaluation de l’étendue, c’est la différence entre un “nettoyage” et une reprise maîtrisée. Le scanner malware WordPress aide, mais il doit être mis en perspective avec la chronologie, la base de données, les mécanismes de persistance, et le comportement réel du site.

Si vous prenez une seule idée : ne jugez pas l’infection au nombre de fichiers listés. Jugez-la au nombre de chemins possibles par lesquels le site peut encore exécuter ou reconstituer le code malveillant. C’est cette approche, plus lente au départ mais beaucoup plus fiable, qui réduit le risque de réinfection et sécurise vos prochains déploiements.