Enlever virus WordPress : éradiquer les scripts iframe injectés

Sur WordPress, les infections ne se ressemblent pas toutes. Certaines laissent des traces grossières, d’autres sont presque invisibles, jusqu’au moment où le site commence à faire “quelque chose” de mauvais dans le navigateur d’un visiteur. L’un des scénarios les plus pénibles, c’est l’injection de scripts dans des iframes, souvent via des fragments HTML glissés dans le code d’un fichier, dans la base de données, ou dans le contenu d’une page. Le résultat est sournois: des contenus tiers s’affichent, des redirections se déclenchent, parfois au simple chargement, parfois après un clic, et surtout, l’empreinte du script disparaît entre deux vues si on ne la capture pas au bon moment.

Quand on cherche à enlever virus WordPress et à éradiquer ces scripts iframe injectés, le plus important n’est pas seulement de “supprimer ce qu’on voit”. Il faut aussi casser la mécanique d’infection: comment le script revient, d’où il part, et ce qui permet à l’attaquant de réécrire. Sans ça, on a l’impression de nettoyer, puis le site replante au même endroit, quelques heures ou quelques jours plus tard.

Comment une infection par iframe s’installe, en pratique

Les scripts iframe injectés suivent souvent un schéma classique. Quelqu’un obtient un accès, même temporaire. Cela peut être un compte compromis, une faiblesse de plugin, un mot de passe réutilisé, ou une faille d’édition de fichiers. Une fois dans le tableau de bord, l’attaquant peut modifier un thème, un plugin, ou insérer un bout de code dans un emplacement “qui dure”.

Sur WordPress, les points de persistance typiques sont les suivants:

    un fichier du thème (souvent functions.php ou un template de page) qui contient une logique conditionnelle (par exemple selon la langue, l’IP, un user-agent) un plugin modifié, parfois renommé ou laissé avec une structure normale mais une fonction cachée des options ou méta-données en base, pour injecter du HTML dans le rendu un fichier d’include dans wp-content avec un nom banal (et peu de code visible à première vue) des injections dans des champs d’articles ou de pages, surtout si le site permet l’édition de contenu par des rôles trop larges

Les iframes, elles, servent souvent à charger un contenu externe, ou à exécuter un script au travers d’une page intermédiaire. Parfois l’iframe est “vide” au départ, puis se remplit avec un script, parfois il n’y a même pas d’iframe dans le HTML final, le script la crée côté client.

Ce qui trompe, c’est la forme du symptôme. Un site peut rester utilisable, une seule page peut être touchée, ou seulement une partie du trafic. J’ai déjà vu un cas où seule la version mobile chargeait l’iframe, parce que l’injection testait window.innerWidth et n’activa la charge externe qu’en dessous d’un certain seuil. Sans outils de développement et comparaison entre navigateurs, on peut nettoyer le mauvais endroit.

Les signes qui pointent vers une injection iframe

Avant de modifier des fichiers, il faut confirmer le mécanisme. Sinon, on risque de “désactiver” quelque chose d’important du site sans éradiquer l’origine.

Voici des signaux concrets que vous verrez souvent. Je les formule en mode “observables”, parce qu’en incident, ce sont eux qui comptent.

La première piste, ce sont des éléments qui ne devraient pas exister dans le HTML ou le DOM final. Ouvrez une page touchée, inspectez le code et cherchez des balises iframe ou des scripts qui ne ressemblent pas à votre thème ou à vos plugins. Ensuite, regardez les sources externes: domaines inconnus, chemins longs, paramètres encodés.

Deuxième piste, les patterns de redirection. Par exemple, un chargement déclenche une redirection discrète vers une URL qui n’a aucun lien avec votre site, parfois via un relais. L’iframe peut être le relais, ou le script peut créer l’iframe, puis rediriger.

Troisième piste, le comportement “réversible” quand on recharge en cache. Sur certains sites compromis, la charge externe varie selon la session ou l’ordre des ressources chargées. C’est pour ça qu’un simple test manuel peut ne pas reproduire le problème. Faites des tests avec cache désactivé, et idéalement depuis deux navigateurs ou deux profils (un en navigation privée, l’autre non).

Quatrième piste, le site se “récupère” puis replante. Si vous corrigez un fichier puis l’infection revient, il faut considérer que quelqu’un ou quelque chose a la capacité d’écrire dans votre WordPress. Ça peut être un compte admin compromis, une tâche cron malicieuse, ou un webshell.

Cinquième piste, des fichiers nouvellement créés. Même si le contenu visuel semble identique, un simple listing du dossier wp-content et des dates de modification peut révéler un plugin ou un fichier “fantôme” qui n’existait pas avant.

Préparer l’assainissement sans aggraver la situation

Avant de supprimer, il faut figer l’état. Sinon, on perd le fil. J’ai vu des équipes supprimer rapidement des fichiers puis, une heure après, ne plus savoir où était l’iframe dans l’ancienne version. Résultat, on nettoie à l’aveugle, et la récidive arrive.

Commencez par faire un snapshot propre de ce que vous avez, même si ce n’est pas parfait. L’idée: conserver l’original en cas de besoin de comparaison.

Ensuite, mettez en pause la surface d’attaque. Si vous pouvez le faire sans casser le service, vous avez deux options pragmatiques. Soit vous placez le site en maintenance pour empêcher les nouveaux edits, soit vous bloquez l’accès admin (au minimum) pendant l’investigation.

Enfin, gardez en tête une règle simple: vous ne pouvez pas “réparer” un site compromis avec des changements à chaud sur une machine déjà compromise. Le téléchargement de fichiers par FTP depuis une session admin compromise peut exposer le poste. Dans la pratique, cela dépend de votre contexte, mais au minimum, travaillez depuis une machine saine, et changez les mots de passe à la fin, pas au milieu, si vous devez encore accéder pour diagnostiquer.

Première vérification: valider l’injection avant de toucher aux fichiers

Vous voulez répondre à trois questions: où est injecté le code, à quel moment, et dans quel contexte.

Le moyen le plus fiable consiste à comparer le HTML “avant exécution” et le DOM “après exécution”. Ouvrez les DevTools, filtrez sur iframe et sur les fragments suspects. Souvent, l’injection se trouve dans un endroit qui n’est pas immédiatement évident, par exemple un echo de contenu dans un template, ou un filtre WordPress.

Regardez aussi la source exacte du script injecté. Si l’iframe pointe vers un domaine inconnu, notez-le. Ce n’est pas pour alimenter une chasse abstraite, c’est pour identifier si le domaine a plusieurs alias, et si le code injecté a une base commune (souvent une URL unique encodée dans un paramètre).

Pendant cette phase, ne faites pas encore de suppression. Prenez des captures, exportez les fichiers suspects si nécessaire, et notez les heures. Ce détail devient utile si vous observez une récidive, car vous verrez parfois une logique planifiée, par exemple via cron.

Éradication: méthodes concrètes pour supprimer les scripts iframe injectés

Ici, on vise une procédure de nettoyage qui ne se contente pas de retirer un fragment. L’objectif est de supprimer les modifications introduites, puis de restaurer une base saine, tout en vérifiant que l’accès compromis est réellement fermé.

Restaurer ce qui a été modifié, plutôt que “triturer”

Dans une infection par iframe, il est tentant d’éditer un fichier à la main et de supprimer le bout de code autour de l’iframe. Parfois ça suffit. Mais quand la persistance est en base ou dans un fichier inclus indirectement, vous allez passer à côté d’un morceau qui relance l’injection.

image

Quand c’est possible, la stratégie la plus robuste consiste à repartir des versions officielles et à reconstruire uniquement ce qui était légitime. Cela veut dire:

    réinstaller les thèmes et plugins à partir des versions propres comparer les fichiers de votre thème actif avec une version de référence recharger les fichiers WordPress core (pas seulement ceux qui semblent touchés)

Évidemment, cela a un coût. Si vous avez un thème custom très modifié, “réinstaller” ne sera pas simple. Dans ce cas, comparez finement, puis isolez les zones modifiées. Si vous trouvez une fonction étrange ajoutée, une condition sur user-agent, ou un encodage douteux, c’est souvent elle qu’il faut supprimer. Mais la comparaison et la preuve restent essentielles.

Identifier l’entrée d’infection: compte, plugin, ou base

Une infection iframe revient parce qu’elle a une porte d’entrée.

La porte d’entrée la plus courante, c’est le compte. Dans WordPress, vérifiez les utilisateurs et surtout les derniers ajouts. Regardez aussi les rôles. Un attaquant peut créer un compte admin ou modifier les capacités. Si un compte est compromis, supprimer une iframe ne sert à rien, l’attaquant réécrira au prochain passage.

La deuxième porte d’entrée fréquente est un plugin compromis. Même si vous désactivez le plugin, il peut avoir déjà modifié des fichiers du thème ou laissé du code en base. Donc, vous désactivez, vous inspectez, puis vous réinstallez proprement.

La troisième porte d’entrée est la base. L’attaquant peut injecter du HTML dans une option, un filtre, un champ de bloc, ou une meta. C’est là que l’injection peut sembler “mystérieuse”. Le fichier ne montre rien, mais le HTML final l’a.

Dans tous les cas, votre objectif est de prouver l’origine avant de dire “c’est fini”.

Chercher le code réellement responsable

Quand vous examinez les fichiers, ne vous contentez pas de chercher le mot iframe. Les attaquants utilisent souvent des concaténations, des base64, ou des chaînes dynamiques. Dans certains cas, la balise iframe n’apparaît même pas comme texte, elle est construite. Cherchez plutôt des indicateurs de logique d’injection:

    usage de base64_decode ou fonctions de décodage concaténations de chaînes avec des fragments HTML ajout de hooks (actions, filters) dans functions.php ou dans des fichiers annexes modifications dans wp_head ou wp_footer requêtes HTTP sortantes via curl, file_get_contents, wp_remote_get écriture de fichiers à la volée ou accès au système via des fonctions de type fopen sur des chemins bizarres

L’exemple le plus frustrant est celui où le code n’a l’air de rien. Une fonction très courte ajoute un script, puis charge tout le reste depuis une URL. En supprimant seulement la ligne qui insère l’iframe, vous pouvez laisser la fonction qui réinsère le script à chaque chargement.

Une approche par “bascule” pour réduire le périmètre

Si le site a plusieurs pages et que vous ne savez pas où chercher, une méthode pragmatique consiste à isoler le thème actif et les plugins un par un. Vous désactivez temporairement le thème si possible, ou vous passez sur un thème propre de test.

Cette étape sert à répondre à une question simple: l’injection vient-elle du rendu du thème, ou d’un plugin qui se déclenche sur toutes les pages. Si l’iframe n’apparaît plus avec un thème neutre, vous savez où concentrer votre attention.

Si l’iframe apparaît malgré le thème neutre, c’est très probablement un plugin ou un code de base en actions globales.

Cela dit, ne le faites pas en boucle sans garde-fous. Sur un site déjà compromis, chaque changement peut être une nouvelle occasion de déclencher un mécanisme caché. Procédez méthodiquement, consignez, et gardez des points de retour (copies de fichiers et états de base).

Plan de réponse rapide, propre et reproductible

Voici un plan d’action que j’utilise en intervention, ajusté à la réalité des scripts iframe injectés. Il n’est pas “magique”, mais il limite les oublis.

Geler et documenter: captures DevTools, URL du script ou de la page iframe externe, pages touchées, horodatage. Isoler l’accès: désactiver la connexion admin si nécessaire, vérifier comptes utilisateurs et rôles. Nettoyer en remplaçant: réinstaller WordPress core, réinstaller thèmes et plugins depuis des sources fiables, puis comparer les fichiers modifiés. Vérifier la base: rechercher dans les options et contenus les fragments HTML suspects, les injections encodées, les champs de blocs modifiés. Empêcher la récidive: changer tous les mots de passe, supprimer les comptes créés, renforcer les permissions, puis surveiller les logs.

C’est une séquence courte en apparence. En pratique, le travail le plus long se cache dans l’étape 4 et dans la preuve de l’origine. Quand vous avez trouvé l’endroit exact de l’injection, la suppression devient presque “mécanique”. Tant que vous n’avez pas trouvé l’origine, vous jouez au chat et à la souris.

Supprimer la persistance en base: là où beaucoup perdent du temps

Les injections par iframe se cachent parfois dans un endroit que l’œil ne visite jamais. Les thèmes et plugins, au moins, se voient dans le code. La base, elle, est plus difficile à inspecter sans outil, surtout quand les données sont encodées.

Si vous suspectez une injection en base, commencez par chercher les chaînes probables que vous avez vues dans le HTML final. Recherchez le nom de domaine externe, ou des fragments uniques. Même sans connaître exactement le champ, le fait de retrouver la chaîne permet d’isoler ce qui l’a injectée.

Attention, toutefois, à ne pas interpréter une occurrence isolée comme preuve. Un domaine peut apparaître dans un contenu légitime, ou dans un paramètre de configuration. Dans les incidents, ce qui vous intéresse est la combinaison: occurrence + context d’insertion + déclencheur (par exemple une condition de page, un hook, un bloc).

Une fois la zone identifiée, vous supprimez ou corrigez le champ concerné, puis vous validez en rechargeant avec cache désactivé. Si l’iframe réapparaît, ce n’est pas uniquement un contenu. Il y a probablement un code qui réécrit la donnée ou qui génère le HTML au moment du rendu.

C’est là que la logique conditionnelle des scripts devient évidente. Beaucoup d’injections sont “propres” sur une partie du trafic, “sales” sur une autre. Une base avec une insertion permanente peut être moins fréquente qu’un mécanisme qui recompose le HTML à chaque chargement.

Renforcer le site après nettoyage, sans le rendre inutilisable

Après avoir enlevé le virus et supprimé les scripts iframe injectés, le vrai défi commence: éviter le retour.

Le plus gros levier, ce sont les accès. Changez les mots de passe de tous les comptes WordPress, y compris les comptes inactifs. Vérifiez aussi les sessions actives. Déconnectez-les si possible. Ensuite, changez aussi les identifiants côté hébergement, car certains compromettent la chaîne via l’accès serveur ou le panneau de contrôle.

Ensuite, examinez les permissions de fichiers et la capacité d’édition. Un attaquant aime écrire. Si vos permissions sont trop larges, il peut réussir plus facilement à déposer un fichier.

Côté plugins et thèmes, mettez à jour ce que vous utilisez réellement. Une partie des infections vient de plugins non maintenus. La mise à jour n’est pas une garantie absolue, mais elle réduit la surface. Et si un plugin est inutilisé, supprimez-le plutôt que de le laisser “au cas où”.

Enfin, pensez à la surveillance. Les logs serveur, les logs d’accès, et des outils de détection d’intégrité peuvent vous alerter rapidement. Je privilégie une approche simple: alerte sur modifications de fichiers (sur le périmètre pertinent) et revue des événements d’administration.

Le point d’équilibre, c’est le bruit. Un trop grand nombre d’alertes peut vous faire ignorer les vraies. L’idée est de cibler le périmètre: wp-content et fichiers liés au thème actif, base pour les champs à risque, et événements admin.

Cas particuliers: quand le site “semble propre” mais l’iframe revient

Parfois, on nettoie, et le site paraît correct. Puis l’iframe réapparaît seulement sur certains visiteurs. Ce n’est pas forcément une récidive complète. Ça peut être une logique ciblée.

Les injections ciblent souvent des critères comme:

    certains user-agents des pays ou plages IP des heures spécifiques la présence de cookies des comportements de navigation

Dans ce cas, la validation doit être réaliste. Testez avec navigation privée, testez avec différentes configurations, et comparez le HTML en “vue source” au moment où ça bugue. Si vous ne reproduisez pas, vous pouvez croire que c’est réglé alors que la logique existe encore.

L’autre cas frustrant est celui des caches. Si un CDN ou un cache serveur a stocké une page infectée, le contenu infecté peut rester visible même après correction. Vous pensez que “ça revient”, alors que c’est un contenu servi depuis un cache. C’est pour ça que vous devez purge le cache et tester avec cache désactivé, ou depuis une autre région si vous utilisez un CDN.

Enfin, il existe des mécanismes de redéploiement via des scripts planifiés. Si une tâche cron a été modifiée, la recréation peut être automatique. Dans ce cas, même un nettoyage complet du contenu visible ne suffit pas, parce que la base et les fichiers sont réécrits régulièrement.

Éviter les erreurs classiques pendant l’assainissement

Dans la pratique, les erreurs les plus coûteuses ne sont pas “techniques” au https://gardewp.fr/nettoyage-malware-wordpress/ sens strict. Ce sont des erreurs de méthode.

La première, c’est de supprimer uniquement ce qui ressemble à l’iframe, sans chercher la logique qui l’insère. Si la fonction d’injection reste, elle rechargera tout au prochain cycle.

La deuxième, c’est de réinstaller un plugin ou un thème après avoir modifié des fichiers directement, sans comparaison. Si vous copiez un fichier infecté d’une sauvegarde “pas si propre”, vous réimportez le problème.

image

La troisième, c’est de laisser un compte admin compromis en place “le temps de finir”. Même un court délai peut suffire à laisser l’attaquant réécrire. Et il n’y a pas besoin d’un grand niveau de sophistication, les scripts peuvent être prêts à tourner dès que l’accès est restauré.

La quatrième, c’est de changer les mots de passe avant d’avoir coupé la persistance. Si un script malicieux écoute ou récupère des secrets, vous pouvez perdre du temps et compliquer le diagnostic. L’approche plus sûre est de couper l’accès, nettoyer, puis seulement à la fin finaliser la rotation des identifiants.

Ce que vous devriez constater une fois le nettoyage terminé

Après une vraie éradiquer une injection iframe, on devrait observer un ensemble de confirmations, pas une seule.

Le plus simple est de vérifier que l’HTML final ne contient plus les balises iframe, ni les scripts suspects, et que les domaines externes inconnus n’apparaissent plus dans les requêtes. Mais il faut aller un peu plus loin: vérifiez que les fichiers modifiés correspondent à des versions attendues, que les plugins et thèmes non utilisés sont supprimés, et que la base ne contient plus de fragments incohérents.

Enfin, faites un test de charge sur plusieurs heures si possible. Sur certaines infections, la charge externe n’est pas immédiate, elle dépend de conditions. Si le comportement reste absent après une période raisonnable, vous pouvez être plus confiant.

Le “raisonnable” dépend de votre site et de votre trafic. Pour un site très actif, vous voulez au moins vérifier sur des fenêtres courtes et répétées. Pour un site plus calme, une surveillance sur un jour ou deux peut suffire à détecter une récidive simple. Si vous constatez un pattern horaire, ajustez.

Si vous êtes en train de nettoyer un site et que vous observez un iframe injecté, dites-moi ce que vous avez déjà trouvé: le fichier où le code apparaît (ou s’il n’apparaît qu’en base), le domaine externe chargé par l’iframe, et si la désactivation d’un plugin ou du thème actif coupe le symptôme. Avec ces indices, on peut orienter la recherche vers la source la plus probable et éviter de nettoyer au hasard.