Nettoyage malware WordPress : combiner scanner et analyse manuelle

Un site WordPress compromis se reconnaît rarement à un seul signe clair. Souvent, les symptômes sont partiels, dispersés, ou déclenchés seulement dans certains contextes: un visiteur sur deux, un pays précis, une fenêtre horaire, ou un rôle (admin seulement, ou au contraire uniquement public). Dans ces conditions, le “nettoyage malware WordPress” qui marche le mieux n’est pas celui qui promet une solution unique, mais celui qui combine deux approches complémentaires: un scanner pour repérer vite et large, puis une analyse manuelle pour comprendre, confirmer et éliminer la cause.

Ce que j’ai vu sur le terrain, c’est que les scanners font gagner des heures, mais qu’ils peuvent aussi te donner un faux sentiment de sécurité. L’analyse manuelle, elle, prend plus de temps au début, mais elle répond à la question essentielle: qu’est ce qui a vraiment été modifié, comment, et comment empêcher la reprise.

Quand un scanner suffit… et quand il ment

Les outils de détection s’appuient sur des signatures (fichiers connus pour contenir du code malveillant), sur des heuristiques (comportements suspects), et parfois sur une analyse de configuration. Sur un WordPress infecté par un script déjà très répandu, ils peuvent donner une liste de fichiers à supprimer avec une efficacité impressionnante. J’ai déjà traité des cas où le scanner identifiait précisément un fichier dans le thème enfant, et où la suppression réglait l’impact en quelques minutes.

Mais dans des scénarios plus “artisanaux”, l’attaquant ajuste son code, le cache, ou le déploie de manière conditionnelle. Le scanner peut alors:

    rater l’élément central si le code est custom, signaler des faux positifs (par exemple un plugin légitime dont le code ressemble à autre chose), ou, pire, trouver une trace résiduelle alors que l’origine est ailleurs.

Le piège classique, c’est de supprimer ce que le scanner pointe, sans vérifier les mécanismes de persistance. Si le malware est réinjecté à chaque chargement via une tâche planifiée, un webhook, une modification de cron, ou un plugin installé en douce, tu “nettoies” sans terminer.

J’ai aussi rencontré des cas où le scanner indiquait “infecté”, mais sans pouvoir expliquer la chaîne. Tu te retrouves avec un ensemble de fichiers suspects, et une décision à prendre sans contexte. À ce moment, l’analyse manuelle devient le filtre de bon sens qui évite de casser le site pendant qu’on cherche le coupable.

Poser le bon diagnostic avant de toucher aux fichiers

Avant même d’exécuter un scanner, j’essaie d’obtenir une image mentale du problème. Ça évite les interventions à l’aveugle et ça réduit les chances de supprimer quelque chose d’utile.

La première étape “humaine”, c’est de documenter le comportement. Si possible, je teste:

    navigation en mode navigation privée et en session normale, affichage public et accès admin, pages clés (accueil, une page populaire, une page de formulaire), et comportements variables (redirige-t-il? Injecte-t-il du contenu? Affiche-t-il des popups?).

Sur certains sites, le malware ne s’active qu’après un événement, par exemple après la mise à jour d’un plugin, ou lorsqu’un utilisateur se connecte. Dans ce cas, attendre la bonne fenêtre de déclenchement fait gagner du temps, et surtout, ça permet de confirmer que ce que tu vois après nettoyage est bien stable.

Je fais aussi un point sur l’état du serveur, en particulier:

    présence de surcharges dans le dossier uploads, permissions inhabituelles, traces dans l’outil de logs de l’hébergement si l’accès est consultable (erreurs PHP, 404 anormaux, pics d’accès).

Même si tu es sur du mutualisé, tu peux souvent trouver des indices dans les logs “bruts” ou dans les rapports de l’hébergeur. Le but n’est pas d’enquêter au sens judiciaire, mais de réduire la liste des hypothèses avant d’agir.

Scanner: obtenir une liste exploitable, pas une vérité absolue

Un scanner sert à deux choses: accélérer la recherche, et fournir un inventaire exploitable. Pour que ça reste utile, je le traite comme un premier tri, pas comme une décision finale.

Dans mon processus, je lance le scanner (ou j’utilise un outil de sécurité) et je collecte trois types d’informations:

Fichiers marqués “suspects” avec leurs chemins, Fichiers réellement “infectés” si l’outil fait la distinction, Actions ou patterns signalés (par exemple une présence de fonctions liées à l’exécution dynamique, ou de chaînes typiques de payload).

Ensuite, je vérifie l’organisation des résultats. Si tu vois beaucoup de fichiers dans des zones qui devraient être propres, comme des dossiers racine WordPress (ou des thèmes et plugins), tu as probablement un compromis côté fichiers. Si le scanner pointe plutôt des bases de données, ou des patterns dans wp-config.php, la stratégie doit être différente.

J’utilise aussi le scanner pour repérer les zones où je dois chercher en manuel. Le meilleur scénario, c’est quand le scanner te donne un petit nombre de suspects, bien placés. Le pire, c’est quand il te donne une longue liste, sans hiérarchie, et que le site est déjà “abîmé” par plusieurs couches. Dans ces cas, l’analyse manuelle doit être structurée pour éviter la procrastination technique.

Un exemple concret de faux chemin

J’ai déjà vu un site où le scanner insistait sur un fichier dans le thème. Le propriétaire avait supprimé ce fichier, mais les redirections continuaient. En manuel, on a découvert que le vrai point de persistance était ailleurs, dans une tâche cron et dans un champ de base de données stockant un script. Le thème, lui, était une victime indirecte: le code malveillant ne s’exécutait qu’une fois une page chargée, à partir d’une configuration injectée par ailleurs.

Le scanner avait signalé un symptôme. L’analyse manuelle a révélé la cause.

Analyse manuelle: vérifier la cause, la persistance et l’intégrité

Une analyse manuelle efficace n’a pas besoin d’être spectaculaire. Elle doit être systématique, orientée preuves, et surtout prudente pour ne pas “casser” pendant qu’on cherche.

Contrôle de l’intégrité des fichiers “nativement attendus”

Le point de départ, c’est de comparer ce que tu as sur disque avec ce qui est attendu. Sur WordPress, beaucoup de fichiers ont une structure standard. Si un core file a été modifié, ou si des patterns “exotiques” apparaissent dans wp-admin, wp-includes, ou dans des fichiers qu’on ne touche jamais, c’est un signal fort.

Je regarde notamment:

    wp-config.php: toute modification non justifiée, surtout ajout de constantes bizarres, inclusion de fichiers inattendus, ou altération de paramètres. .htaccess et fichiers de configuration: ajout de règles de redirection ou de rewrites spécifiques. thèmes et plugins: comparaison rapide des fichiers changés, présence de scripts obfusqués, accès à des variables inattendues.

L’idée n’est pas de comprendre tout le code immédiatement. C’est de détecter des zones à forte probabilité et de prioriser les vérifications.

Recherche de persistance côté base de données

Sur WordPress, les compromis sont souvent “vivants” dans la base de données. Le code ne vit pas toujours dans un fichier PHP visible. Il peut être stocké dans des options, des métadonnées, ou des contenus “injectés” de manière routée.

En manuel, je vérifie les éléments qui ont tendance à être modifiés par des malwares:

    comptes admin ajoutés ou rôles inattendus, utilisateurs “fantômes”, options et paramètres inhabituels, contenus postés (ou réécrits) sans explication.

La base de données, c’est aussi le lieu où une logique conditionnelle se met en place. Si le site n’injecte le code que pour un type de visiteur, tu as souvent un indicateur dans des options ou dans des champs stockant des règles.

Les indices qui trahissent le code malveillant

Dans le code, je cherche des caractéristiques plus que des signatures. Les malwares WordPress, surtout quand ils cherchent la furtivité, s’appuient sur des mécanismes connus pour exécuter ou https://gardewp.fr/nettoyage-malware-wordpress/ charger autre chose.

Quelques exemples d’indicateurs, sans tomber dans une liste rigide:

    fonctions qui évaluent du code dynamique, concaténations et transformations qui “reconstruisent” un payload, inclusion de fichiers depuis des chemins non habituels, scripts courts et obfusqués, parfois avec des noms de variables sans sens, délais ou conditions basées sur l’horodatage.

L’analyse manuelle, ici, ressemble à une autopsie. Tu ne veux pas seulement retirer ce qui est visible, tu veux comprendre comment ça s’exécute, à quel moment, et dans quel périmètre.

Concilier les deux mondes: méthode de tri

Pour combiner scanner et manuel sans se perdre, j’utilise une logique de tri simple: “pointe le scanner, mais décide en manuel”. Concrètement, je ne supprime rien immédiatement si le scanner donne des suspects multiples. Je prends d’abord ceux qui ont le plus de chances d’être la persistance.

La persistance est presque toujours ce qui se cache derrière des effets visibles. Si ton site redirige ou injecte du contenu, cherche d’où vient la logique d’exécution. Typiquement, c’est:

    une modification de configuration, un fichier de plugin ou thème qui fait tourner le code, ou une action planifiée qui re-dépose du code.

Quand le scanner repère des fichiers, je me demande: lesquels de ces fichiers sont susceptibles d’être appelés au chargement? Les meilleurs candidats sont ceux qui se trouvent dans un point d’entrée WordPress, ou qui sont inclus par des hooks et des fichiers “sœurs” (index, loader, ou plugin boot).

À l’inverse, certains fichiers trouvés par signature peuvent être juste des résidus. En manuel, si un fichier n’est jamais inclus ou jamais exécuté, le retirer seul peut ne pas suffire.

Nettoyer sans casser: ordre d’intervention réaliste

Le plus gros risque pendant un nettoyage, ce n’est pas seulement de ne pas supprimer le malware, c’est de dégrader le site en supprimant ce qui était légitime. Comme tu ne connais pas toujours l’historique, l’ordre d’action compte.

Je privilégie généralement:

Sécuriser les accès pour éviter une re-compromission pendant que tu travailles, Mettre le site dans un état où tu peux tester sans gêner tout le trafic, Retirer les éléments à haute probabilité de persistance, Vérifier que l’effet a cessé, Ensuite seulement, traiter les éléments secondaires repérés par le scanner.

Sur des sites très chargés ou critiques (e-commerce, formulaires), j’ai parfois fait un “mode maintenance” minimal, le temps de valider le comportement. Si tu n’as pas de staging, je recommande fortement de copier les fichiers et la base de données avant d’aller trop loin, ne serait-ce que pour pouvoir comparer et revenir.

Ajuster selon la gravité: un repère pratique

Il y a une différence entre:

    une injection de contenu simple, une redirection agressive, et une compromission plus large, qui modifie des plugins, des comptes, et des tâches système.

Quand plusieurs de ces aspects sont présents, je considère que le site a probablement été modifié en profondeur. Dans ce cas, je traite le nettoyage comme un chantier: plus de vérifications, plus de tests, moins de suppression “au feeling”.

Pièges fréquents observés sur des WordPress compromis

Ces pièges reviennent assez souvent pour qu’ils fassent partie de mon attention de base.

Les “faux nettoyages” après suppression d’un fichier

Supprimer un fichier suspect est utile, mais si le code est réinjecté, tu perds du temps. Un signe que tu es dans cette situation: tu observes un retour du comportement quelques minutes après la suppression, ou un rechargement qui re-propage le code.

Dans ces cas, il faut regarder immédiatement:

image

    cron, scripts planifiés, utilisateurs et rôles, options base de données, et mécanismes de chargement de plugin.

Les plugins légitimes modifiés ou “parasités”

Un cas que je préfère traiter avec méthode: un plugin légitime a été modifié. Parfois l’attaquant modifie quelques lignes uniquement, et le plugin semble fonctionner. Le scanner peut signaler un fichier “infecté” dans un plugin, mais tu pourrais vouloir remplacer le plugin par une version fraîche. C’est parfois la meilleure option, mais pas toujours sans vérifier les réglages et la compatibilité.

Mon conseil pratique: si le plugin est modifié, le remplacement par une version propre est généralement plus sûr que de tenter de “corriger à la main” ligne par ligne. Mais je documente les paramètres du plugin avant, et je fais une vérification de la configuration après mise à jour.

L’oubli des comptes et des droits

Même si tout le code PHP est “nettoyé”, un compte admin ajouté par l’attaquant peut suffire à repropager le malware. Je fais donc un contrôle des utilisateurs, et je supprime ce qui est manifestement anormal.

Parfois, le compte “malveillant” a un nom banal. Parfois, il a été créé avec une date proche du pic d’activité. L’important, c’est de lier le compte à un contexte. Si tu n’expliques pas sa présence, tu le traites comme suspect.

Stratégie de test après nettoyage: prouver que c’est réglé

Un nettoyage réussi se prouve. Sinon, tu restes au niveau du “ça a l’air”. Or un malware conditionnel peut rester latent et revenir plus tard.

Pour tester correctement, je combine des observations dans le navigateur et des vérifications techniques. Je cherche des indicateurs stables:

    pages qui n’injectent plus de code, absence de redirection, comportement identique pour plusieurs types de visiteurs, et absence de nouveaux fichiers déposés après un délai.

Sur un WordPress compromis, j’aime attendre au moins quelques cycles de chargement, puis vérifier les zones traitées. Le délai exact dépend du malware. Parfois, la réinfection est presque immédiate, parfois elle arrive après un événement. Si tu as accès à l’outil de logs du serveur, tu peux aussi vérifier si des requêtes suspectes continuent.

Deux scénarios qui changent tout

Scénario 1: tu as accès à une sauvegarde propre

Si tu as une sauvegarde antérieure à l’incident, tu peux souvent réduire fortement le risque. Le bon réflexe, c’est de restaurer la sauvegarde dans un environnement temporaire (ou sur une copie), puis de reprendre le traitement de manière ciblée. Tu compares ce qui diffère. Ça donne une base factuelle.

Dans ce cas, scanner et analyse manuelle deviennent plus rapides, car tu sais quoi comparer, et tu peux éviter de partir d’un état déjà “contaminé”.

Scénario 2: tu n’as pas de sauvegarde utilisable

Sans sauvegarde propre, tu dois faire plus d’analyse, et tu acceptes un risque résiduel jusqu’à ce que tout soit prouvé. Ici, la méthode devient: sécuriser l’accès, nettoyer les persistances, remplacer ce qui est modifié et essentiel (core, plugins actifs, thèmes), puis tester.

Dans certains cas graves, j’ai déjà proposé une reinstallation à partir de versions officielles, puis réintégration contrôlée du contenu. C’est coûteux en temps, mais parfois c’est le seul moyen de stopper une boucle de réinfection.

Une checklist courte pour passer du scanner à la certitude

Voici la petite logique que j’applique quand les résultats du scanner sont “trop nombreux” ou quand je sens que le malware est intelligent.

Tracer les meilleurs candidats à la persistance parmi les alertes du scanner, plutôt que traiter toute la liste. Vérifier wp-config.php, la configuration d’accès et les fichiers de réécriture (comme .htaccess) pour tout ajout non justifié. Contrôler utilisateurs, rôles, et contenu injecté dans la base, car c’est souvent là que se cache la logique de réactivation. Remplacer par des versions propres les plugins et thèmes manifestement modifiés, puis tester les pages sensibles. Confirmer l’arrêt du comportement sur plusieurs cas (public, admin, navigation privée) avant de rouler le site en production.

Cette checklist n’élimine pas la nécessité de lire le code ou d’analyser la base, mais elle force à ne pas se limiter à un “effacement de symptômes”.

Prévenir la réinfection après le nettoyage

Le nettoyage malware WordPress ne finit pas à la suppression. Une fois le site “repassé au vert”, tu dois éviter que l’attaque s’installe de nouveau.

Les mesures de base que je recommande systématiquement sont celles qui réduisent les chances de réintroduction:

    mettre à jour WordPress, thèmes et plugins (en gérant prudemment les incompatibilités), supprimer les comptes inutiles et vérifier les rôles, imposer des mots de passe solides et distincts, limiter les vecteurs d’accès (durcissement de l’authentification, blocage d’IP si nécessaire, et contrôles d’activité).

Je garde toutefois un regard réaliste: sans corriger la porte d’entrée (vulnérabilité de plugin, faiblesse d’accès, mauvaise configuration), tu peux renforcer la défense tout en restant vulnérable à la prochaine tentative.

Ce que je ferais si je devais recommencer de zéro

Si je reprends mentalement un cas typique où je dois combiner scanner et analyse manuelle, je reconstitue une trajectoire fiable:

    D’abord, je comprends le symptôme et je le reproduis. Même partiellement. Ensuite, je lance un scanner, mais je transforme ses résultats en carte de zones à vérifier. Je commence par la persistance, parce que c’est ce qui maintient l’infection en vie. Je remplace ce qui a été modifié, quand c’est faisable et moins risqué que de “réparer au stylo”. Je vérifie utilisateurs, options et comportements après un délai, pas seulement juste après suppression. Enfin, je durcis l’environnement pour empêcher la répétition.

Ce processus n’est pas le plus rapide sur le papier, mais c’est celui qui évite les cycles interminables de “nettoyer, constater que ça revient, re-nettoyer”.

Le bon compromis: vitesse du scanner, rigueur du manuel

Le scanner te donne une vitesse, une direction, une liste. L’analyse manuelle te donne la preuve, la compréhension, et la capacité de trancher dans les zones ambiguës. La combinaison, c’est précisément ce qui rend le nettoyage fiable quand l’infection est partielle, obfusquée, ou conditionnelle.

Si tu n’as le temps que pour l’un des deux, choisis le scanner pour démarrer, mais ne t’arrête pas là. Le risque, ce n’est pas seulement de laisser un fichier suspect. C’est de laisser intact le mécanisme qui remet le malware en place.

Et c’est souvent ce mécanisme, invisible au premier regard, que l’analyse manuelle finit par mettre au jour.