Scanner malware WordPress : restaurer un site propre et vérifier l’absence de code malveillant

Un site WordPress infecté, ce n’est pas seulement “un souci de sécurité”. C’est souvent une cascade de problèmes qui se ressentent sur le référencement, la délivrabilité des formulaires, le comportement du back-office, et parfois même sur la réputation. J’ai vu des configurations partir en vrille avec des impacts très concrets: pages qui commencent à rediriger vers des sites tiers, faux formulaires qui collectent des données, ou encore une vitesse d’exécution qui chute de façon nette parce que des scripts malveillants se lancent à chaque chargement. Le plus trompeur, c’est que l’infection peut être légère au début, puis s’étendre comme un incendie sous les plafonds.

Le point de départ, c’est de comprendre ce que l’on appelle “malware” dans le contexte WordPress. Souvent, il s’agit d’un mélange de choses: code inséré dans des thèmes ou extensions, charges utiles déposées dans le dossier wp-content/uploads, appels à des serveurs externes, fichiers PHP au contenu obfusqué, ou même des modifications plus subtiles, comme des utilisateurs administrateurs ajoutés via la base de données. Parfois, le “malware” n’est pas un fichier unique mais une suite d’actions qui se déclenchent selon des conditions (par exemple, uniquement pour certains navigateurs, uniquement sur certaines pages, ou uniquement quand l’utilisateur n’est pas un robot).

Dans ce genre de situation, le réflexe consiste à lancer un scanner malware WordPress. C’est utile, mais ce n’est pas une baguette magique. Le scanner peut détecter des signatures, mais il peut aussi manquer un code modifié de façon suffisamment “propre” pour échapper à l’analyse. À l’inverse, un faux positif peut pousser à supprimer un composant fonctionnel. Mon approche consiste donc à combiner un diagnostic outillé et une restauration méthodique, puis à valider l’absence de code malveillant par plusieurs angles.

Comprendre les symptômes avant de toucher au site

Avant toute restauration, j’essaie de répondre à trois questions, parce qu’elles guident le plan d’action.

D’abord, qu’est-ce qui a changé depuis votre dernière période “saine”? Si vous avez des logs de déploiement, un historique de plugins mis à jour, ou des traces de modifications de thème, même approximatives, cela réduit le champ de recherche. Ensuite, quel type de comportement est observé côté visiteurs ou admin? Redirections, pages défigurées, scripts qui s’injectent, ralentissements, erreur 500, accès refusé à certaines pages. Enfin, quelle est la surface de l’incident: uniquement le front, uniquement l’admin, ou les deux?

Sur un site infecté que j’ai traité, le scanner a remonté des “suspects” dans un dossier d’upload. Visuellement, le site semblait intact. Mais les logs serveur montraient une hausse d’erreurs 302 vers des domaines externes, et l’examen HTML d’une page d’article révélait une injection conditionnelle dans le head. Le code malveillant n’avait pas forcément détruit le thème, il s’était contenté d’ajouter un mécanisme.

Cette phase d’observation sert aussi à éviter une erreur classique: restaurer “trop vite”, puis se rendre compte que la compromission continue, parce que le vecteur d’accès n’a pas été corrigé (mot de passe réutilisé, endpoint exposé, plugin vulnérable, clé API détournée, etc.). La restauration doit venir avec une correction, sinon vous nettoyez un symptôme pendant que la cause continue.

Mettre en sécurité: isoler, sauvegarder, documenter

La première décision pratique, c’est l’isolation. Je ne conseille pas d’exécuter des dizaines de scans sur un site vivant si vous suspectez une exécution active de code malveillant, surtout si le site peut charger des scripts distants ou générer des redirections. L’idée n’est pas de “casser” le site, mais de limiter l’impact.

Dans les faits, j’utilise une procédure simple: basculer le site en mode maintenance, ou mieux, mettre une règle de pare-feu pour bloquer temporairement certaines routes très ciblées si vous savez lesquelles sont touchées. Ensuite, je fais une sauvegarde complète, pas uniquement celle fournie par WordPress. Une sauvegarde “vraie” inclut les fichiers, la base de données, et idéalement une copie des logs web du jour de l’incident ou de la période suspecte. Le but est de pouvoir comparer après restauration.

J’insiste aussi sur la documentation. Une capture d’écran des pages incriminées, les URLs touchées, l’heure approximative de la détection, et le résultat du scanner malware WordPress s’il a été lancé. Ce petit dossier de preuves aide énormément quand vous devez expliquer l’incident à un hébergeur, à un client, ou à un expert interne. Et surtout, il vous aide à vérifier que vous avez réellement corrigé l’origine du problème, pas seulement “réduit les dégâts”.

Choisir le bon mode de restauration: revenir à une base saine

Restaurer un site propre, ce n’est pas “réinstaller WordPress”. Si la compromission a modifié un thème, ajouté des fichiers dans des dossiers d’upload, ou altéré des options en base, une simple mise à jour ne suffit pas. Vous devez restaurer depuis une base considérée comme saine.

La question devient donc: avez-vous une sauvegarde antérieure, et cette sauvegarde est-elle fiable? J’ai vu des sauvegardes “mensuelles” qui étaient déjà contaminées, parce que l’incident avait commencé avant la période de sauvegarde. Une restauration vers un état encore compromis peut vous donner l’illusion d’avoir nettoyé, puis vous voir revenir au même problème en quelques heures.

Quand vous disposez d’un snapshot de votre hébergeur ou d’une sauvegarde de routine, je recommande de la traiter comme un candidat, pas comme une vérité. Vous pouvez la pré-analyser localement, sans exposer le site. Si vous avez la capacité de cloner vers un environnement de staging, c’est encore mieux: vous restaurez le clone, puis vous inspectez avant de remettre en ligne.

Analyse des fichiers et de la base: là où les malwares aiment se cacher

Dans WordPress, les points d’atterrissage fréquents sont assez prévisibles, même si chaque incident reste unique. Les extensions et thèmes sont la première cible, parce qu’ils ont le droit d’exécuter du PHP. Les uploads sont la seconde, surtout quand le code malveillant dépose des fichiers, puis déclenche leur chargement via des inclusions. La base de données vient ensuite: options modifiées, utilisateurs ajoutés, champs meta contaminés, et tables du type wp_options qui contiennent parfois des fragments injectés.

Une bonne stratégie consiste à séparer l’analyse en deux boucles: d’un côté, repérer les modifications de fichiers et leur cohérence. De l’autre, repérer les anomalies en base qui ne ressemblent pas à un comportement normal.

Dans la pratique, je commence par examiner l’arborescence de manière “orientée signaux”: fichiers PHP nouveaux ou modifiés récemment, scripts obfusqués, présence d’appels vers des domaines externes, et taille de fichier incohérente. Un thème dont un fichier PHP est passé de quelques dizaines de kilo-octets à plusieurs centaines de kilo-octets peut indiquer une injection. Pareil pour des fichiers très courts contenant pourtant du code étrange, parfois juste un wrapper obfusqué qui charge un contenu distant.

Sur le plan base de données, les anomalies typiques incluent l’apparition d’utilisateurs admin inconnus, des rôles incohérents, des options qui stockent des scripts ou des URLs, et des entrées dans des tables liées à l’URL rewriting ou au contenu. Parfois, l’accès initial est un plugin de sécurité désactivé ou contouré, ce qui masque d’autres traces.

Valider sans tomber dans le piège du “tout est détecté”

Le piège classique, c’est de croire qu’un scanner donne un résultat binaire: “infecté” ou “clean”. En réalité, les scanners font des compromis. Certains cherchent des signatures, d’autres analysent la structure de fichiers, d’autres encore exploitent des heuristiques. Sur un site très “sur-mesure”, avec des plugins anciens ou des thèmes qui utilisent des patterns non standard, vous pouvez obtenir des faux positifs. Sur un site très ciblé, le code peut être légèrement modifié pour éviter les signatures.

C’est la raison pour laquelle je traite les résultats de scanner malware WordPress comme un point de départ. Les fichiers repérés servent à orienter la restauration et la vérification. Mais je vérifie aussi par cohérence: quels fichiers devraient exister et sous quel format, quels composants ont été installés récemment, et quel comportement correspond au symptôme observé.

L’autre aspect, c’est le timing. Un site peut être nettoyé et redevenir “sale” parce que la compromission s’étend depuis l’accès initial, ou parce que des tâches planifiées restent actives (par exemple, via des cron jobs détournés). Je surveille les logs pendant la période suivant la restauration. Si les mêmes patterns réapparaissent, c’est un signal que le vecteur n’est pas corrigé.

Plan d’action pragmatique pour restaurer un site propre

Voici comment je procède quand un site a été déclaré suspect, et que l’objectif est de revenir à un état sain avec des preuves raisonnables. L’ordre exact peut varier selon votre hébergeur et vos outils, mais l’esprit reste le même: isoler, restaurer depuis une base saine, corriger la cause, puis valider.

    Mettre le site en maintenance ou l’isoler (au moins pour les visiteurs non indispensables), puis sauvegarder fichiers et base. Restaurer WordPress, thèmes et plugins depuis une base considérée saine (idéalement un snapshot antérieur analysé) et remettre les fichiers manquants depuis des sources propres. Corriger le vecteur d’accès: mots de passe, rôles, clés, plugins vulnérables, fichiers upload anormaux, et vérification des comptes administrateurs. Vérifier les injections: comparer les diff sur le code PHP des thèmes et plugins, inspecter wp-content/uploads et contrôler les options en base suspectes. Mettre en place une validation multi-angle après remise en ligne, en surveillant logs, comportements de pages, et exécution côté navigateur.

Ce plan est volontairement “large”. Il évite l’erreur de se concentrer sur un seul fichier repéré par un scanner. Les incidents WordPress sont rarement un puzzle simple, ils ressemblent plus à une pièce qui a été bricolée à plusieurs endroits.

Restauration propre, comment faire sans casser le site

La restauration “propre” ressemble souvent à une reconstruction contrôlée. Vous pouvez réinstaller WordPress, mais je recommande surtout de réinstaller ou remplacer à l’identique ce qui provient du répertoire officiel, et de ne pas conserver aveuglément des fichiers qui ont été modifiés en période suspecte.

Ce que je fais généralement:

    Je remplace le core WordPress par une version connue, même si WordPress semble fonctionner. Le core peut être altéré, mais le plus souvent, le core n’est pas le cœur de l’infection. Remplacer quand même réduit le bruit. Je remplace les thèmes et plugins par des versions issues des sources officielles ou des packages de confiance. Si vous avez des modifications custom, vous réappliquez ces changements après la restauration, pas avant. Je traite les fichiers d’upload comme un “dossier à preuves”. Si la compromission a touché ce dossier, le problème peut persister même si thème et plugins sont propres.

Le risque, c’est la perte des personnalisations. Pour l’éviter, je documente les différences avant restauration. Par exemple, si un thème enfant a été utilisé pour modifier le front, je récupère le thème enfant en version attendue, puis je remplace le thème parent avec une version saine. Vous conservez le contrôle sur ce qui doit rester, et vous réduisez la probabilité d’hériter d’un fichier injecté.

Edge case courant: votre site a des plugins “sur mesure” ou des modifications internes. Là, la restauration “à l’identique depuis un dépôt” est impossible. Dans ce cas, je fais une inspection ciblée et une comparaison avec le référentiel de travail. J’ai parfois passé plus de temps à vérifier une poignée de fichiers PHP custom qu’à faire un gros remplacement. C’est moins sexy, mais c’est ce qui réduit le risque de supprimer une fonctionnalité critique.

Vérifier l’absence de code malveillant avec méthode

Après restauration, la partie la plus délicate est la validation. Le but n’est pas seulement de vérifier que “ça charge”. Je vérifie que le site ne réexécute rien qui n’a pas de raison d’exister.

Je teste d’abord le comportement navigateur, en m’assurant de voir le code HTML réellement servi. Une injection peut être minuscule et ne pas casser l’UI. Ensuite, je teste l’accès au back-office: ouverture du tableau de bord, chargement des pages d’administration, absence de nouveaux comptes, et pas de redirections internes bizarres.

Je contrôle aussi les traces server. Si un incident a injecté des redirections, les logs de requêtes doivent cesser de montrer des motifs identiques. Si vous avez un pare-feu applicatif ou des règles de logs, c’est le moment de les exploiter.

Pour être concret, voici un mini protocole de vérification que j’utilise en local ou en staging, avant de remettre le site au public.

    Comparer la liste des fichiers modifiés récemment avec une référence saine (core, thèmes, plugins, mu-plugins). Contrôler les fichiers PHP dans wp-content/uploads, y compris les noms inhabituels, les extensions inattendues, et les contenus obfusqués. Rechercher les domaines externes dans les fichiers PHP des thèmes et plugins, surtout quand ils sont absents des versions officielles. Vérifier la base de données pour des utilisateurs ajoutés, options modifiées, et planifications cron anormales. Faire un test de navigation sur plusieurs rôles (visiteur, auteur, admin), en inspectant le HTML et les requêtes déclenchées.

Ce protocole ne remplace pas un scanner, il le complète. Un scanner peut signaler un fichier, mais la validation par navigation et logs vous confirme que le comportement malveillant a réellement cessé.

Corriger la cause, pas seulement l’effet

Une fois le site restauré, je reviens gardewp.fr sur la question “comment l’attaquant est entré”. Si vous corrigez uniquement l’infection visible, il est fréquent que l’incident revienne.

Les causes les plus courantes que j’ai rencontrées:

    un mot de passe faible ou réutilisé, parfois pour un compte WordPress ou pour un compte d’hébergement utilisé pour accéder aux fichiers. une exécution via un plugin ou thème vulnérable, surtout quand les mises à jour sont en retard. des comptes administrateurs créés sans trace évidente, ou des rôles modifiés pour donner un accès inattendu. des sessions ou tokens de connexion compromis qui continuent d’avoir un effet tant que vous ne forcez pas la rotation.

Sur ce point, j’adopte une logique de réduction du risque: je force la rotation des mots de passe, je déconnecte toutes les sessions, je supprime les comptes inattendus, et j’applique les mises à jour de sécurité. Je vérifie aussi les paramètres de connexion, le cas échéant, et je m’assure que les extensions de sécurité ne sont pas elles-mêmes compromise ou désactivées.

Quand il y a des scripts de backdoor, il arrive que l’accès initial ait été fait via un endpoint admin accessible, ou via une tentative brute sur des chemins connus. Là, le correctif passe aussi par le durcissement: règles de limitation, filtrage, et surveillance.

Surveiller après remise en ligne: détecter la rechute tôt

Après restauration, je ne fais pas “un audit final” et je pars. Je surveille. La rechute, quand elle arrive, se voit souvent dans les heures ou les jours qui suivent.

Je surveille trois choses: les logs web pour des motifs d’erreurs ou de redirections, le nombre d’accès aux pages sensibles, et les déclenchements de scripts suspects dans les chargements front. Si vous avez un outil APM ou au moins un monitoring de disponibilité, je regarde aussi les variations de temps de réponse.

Un détail utile: surveiller les changements du dossier uploads. Si vous observez de nouveaux fichiers PHP, de nouveaux fichiers avec des noms aléatoires, ou des tailles qui évoluent de façon “brutale”, vous avez un signal. Ce type de surveillance peut être simple, par exemple via des alertes sur modifications de fichiers, si votre hébergeur le permet.

Enfin, je recommence un scan malware WordPress après restauration, mais je le fais en cohérence avec le reste: si le scanner revient “clean”, c’est encourageant. Si le scanner remonte des alertes, je ne réagis pas à l’aveugle, je fais l’analyse du fichier pour savoir si c’est un faux positif ou un reste de compromission.

Prévenir la prochaine fois, sans transformer WordPress en forteresse inutile

On ne supprime jamais tout le risque, mais on peut réduire le coût d’un incident futur. Dans un contexte WordPress, j’aime travailler sur trois piliers: réduction des surfaces, hygiène de mises à jour, et mécanismes de détection.

Concrètement, vous pouvez améliorer beaucoup de choses sans complexité excessive: garder core et plugins à jour, limiter le nombre de plugins, désactiver ce qui n’est pas utilisé, et mettre en place une politique de sauvegardes testées. Le point que beaucoup oublient: une sauvegarde utile, c’est une sauvegarde que vous savez restaurer. Tester la restauration une fois, même sur un environnement de staging, coûte moins cher qu’une urgence un dimanche soir.

Je conseille aussi d’instaurer un suivi des comptes WordPress. Les utilisateurs inattendus sont un signe fort. La même logique s’applique aux fichiers modifiés: si vous avez une procédure interne pour recevoir des alertes sur changements, vous gagnez du temps.

Il y a des compromis. Une protection trop intrusive peut bloquer des comportements légitimes, et une supervision trop lourde peut devenir du bruit. Mon approche consiste à viser ce qui détecte tôt et ce qui aide à distinguer un incident d’un simple bug applicatif.

image

Quand faire appel à un spécialiste, et quand vous pouvez agir seul

Il y a un moment où “je fais moi-même” se transforme en risque inutile. Si le site est très exposé (e-commerce, formulaire critique, trafic important) ou si vous n’avez pas de sauvegarde fiable, il est souvent plus prudent de solliciter un spécialiste. Le temps de l’expert, c’est surtout du temps gagné en méthodes éprouvées, et la capacité à repérer des injections subtiles.

Je fais appel quand:

image

    vous observez des redirections persistantes vers des domaines externes malgré une restauration initiale, vous n’avez pas d’état sain antérieur clairement exploitable, le site a des plugins custom complexes sans source de référence, ou les logs montrent une activité répétée qui ressemble à une compromission en cours.

Sinon, une restauration méthodique combinée à une validation sérieuse peut suffire. L’important est de ne pas confondre “ça marche” avec “c’est propre”.

Si vous me décrivez votre situation, je peux vous orienter sur une démarche adaptée. Par exemple, est-ce que l’injection touche surtout le front, l’admin, ou les deux? Avez-vous un snapshot antérieur et savez-vous quels plugins ou thèmes ont été mis à jour avant la suspicion? Ces détails changent vraiment la stratégie, et ils évitent de chercher au mauvais endroit.