Enlever virus WordPress : comment contrôler les cron jobs malveillants

Quand un site WordPress “se met à spammer” ou qu’il se retrouve soudainement redirigé vers des pages cheloues, on pense vite au thème compromis ou à un plugin trop curieux. C’est parfois vrai. Mais dans la vraie vie, j’ai vu bien plus souvent le coupable se cacher ailleurs: dans la programmation automatique du serveur, via les cron jobs, ou dans le système de tâches planifiées de WordPress (wp-cron). C’est aussi là que le malware devient insidieux, car il ne se contente pas de modifier des fichiers une fois. Il revient, relance l’infection, et parfois télécharge du nouveau contenu sans que vous ne le remarquiez.

L’objectif ici est simple: enlever virus WordPress quand il est lié à des tâches planifiées, puis reprendre le contrôle pour éviter la récidive. Je vais parler autant de ce que vous pouvez vérifier, que de la manière de raisonner quand vous trouvez quelque chose de “pas normal”.

Le scénario classique: une infection qui revient

Le schéma le plus fréquent est celui-ci. Vous voyez des symptômes: pages qui redirigent, scripts injectés dans le header, comptes administrateurs ajoutés, fichiers créés à des emplacements bizarres, ou encore des requêtes anormales dans vos logs. Vous désinfectez, vous remplacez des fichiers, vous changez des mots de passe. Le site a l’air propre… puis, deux heures, une nuit ou quelques jours plus tard, les mêmes symptômes réapparaissent.

Quand ça arrive, pensez “mécanisme de réactivation”. Dans WordPress, ce mécanisme peut être:

    une tâche wp-cron déclenchée à répétition qui exécute du code malveillant, ou un cron système qui tourne à une fréquence régulière et recolle des scripts, réactive des backdoors, ou télécharge une nouvelle charge utile.

Le piège, c’est que l’“infection” que vous voyez n’est peut-être pas l’origine. Vous pourriez corriger les symptômes visibles, pendant que la source reste en place ailleurs.

Cron système vs wp-cron: deux mondes, deux angles morts

Avant d’aller fouiller, il faut distinguer les deux leviers.

wp-cron est un système de tâches géré par WordPress, déclenché “à la demande” par les visites du site. Concrètement, WordPress stocke une sorte de planification, puis exécute des événements quand le trafic arrive. Si le site reçoit peu de visites, wp-cron peut sembler “paresseux”. Si un malware crée des tâches ou modifie des hooks, vous pouvez vous retrouver avec des déclenchements inattendus lors de connexions, de chargements de pages, ou d’appels AJAX.

cron système (celui du serveur) est indépendant des visites. Il exécute des commandes à intervalles réguliers: toutes les cinq minutes, toutes les heures, une nuit sur deux, etc. C’est souvent lui qui maintient un malware en vie, parce que le déclenchement ne dépend pas du trafic.

Un indice pratique: si vous observez une activité parfaitement régulière à l’échelle du serveur, cherchez le cron système. Si l’activité semble dépendre du comportement utilisateur (pics après connexions, après certains appels), le focus peut être wp-cron, mais il faut quand même vérifier le serveur.

Symptômes à associer à des tâches planifiées

Tous les malwares ne se présentent pas pareil. En atelier, j’ai tendance à regrouper les signaux qui collent particulièrement aux tâches planifiées.

D’abord, la persistance “au bon rythme”. Un site infecté qui “repousse” après une désinfection au même intervalle. Ensuite, la présence de fichiers ou de commandes qui ne sont pas liés au fonctionnement normal de WordPress: scripts dans des dossiers inhabituels, fichiers exécutables, ou fragments de code qui se greffent sur des fichiers PHP légitimes.

Autre signe: l’activité en dehors des fenêtres de déploiement. Si vous n’avez rien modifié côté plugins ou thèmes pendant une période donnée, et que vos logs montrent des accès internes ou des exécutions régulières, il faut suspecter une tâche.

Enfin, le comportement “faible bruit et forte action”. Par exemple, un site qui ne semble pas vraiment cassé, mais qui injecte une charge utile dans certaines pages, parfois uniquement pour des agents utilisateurs précis, ou uniquement pour des pays spécifiques. Le malware se contente alors de planifier et d’exécuter, sans provoquer une panne globale.

Première phase: isoler, sécuriser, éviter l’aggravation

Avant de toucher aux cron jobs, il y a une étape que beaucoup sautent et qui complique tout après: limiter l’exécution pendant que vous inspectez.

L’idée n’est pas de “désactiver pour toujours”, mais de créer une fenêtre de diagnostic.

Vous pouvez, selon votre contexte, prendre deux mesures simples: bloquer temporairement l’exécution de tâches planifiées (au niveau WordPress et au niveau serveur), et isoler votre accès admin pour ne pas déclencher des hooks pendant l’investigation.

image

Si votre site est en production et que vous ne pouvez pas le mettre hors ligne, vous pouvez aussi activer un mode “maintenance” ou restreindre l’accès à l’administration via IP. Ce n’est pas un remède, mais cela réduit le nombre de déclenchements pendant que vous scannez.

Vérifier wp-cron sans tout casser

Le point important: WordPress peut exécuter des événements même si vous n’avez rien demandé. Or, pendant une désinfection, vous ne voulez pas que wp-cron continue de lancer des actions potentiellement malveillantes.

Commencez par vérifier la configuration de planification dans WordPress. Selon votre installation, wp-cron peut être lié à des paramètres. Ensuite, inspectez les tables WordPress concernées par les événements planifiés, et repérez des événements qui ne correspondent à rien de vos plugins habituels.

Sans vous noyer dans https://gardewp.fr/nettoyage-malware-wordpress/ le détail technique, retenez ceci: si vous voyez des événements dont le “réciproque” ne correspond à aucun plugin légitime, ou si des tâches apparaissent peu après une désinfection, c’est un bon signal.

Côté fichiers, inspectez aussi les emplacements où des malwares aiment se greffer: fichiers de cache, includes, ou endroits où des injections PHP peuvent se loger. Ce n’est pas systématiquement dans un seul endroit, donc l’inspection doit être guidée par les logs et par les dates de modification.

Contrôler le cron système: là où la persistance se cache souvent

Le cron système est généralement plus facile à contrôler, parce qu’il est explicite: il y a des entrées, des commandes, des chemins. La difficulté, c’est qu’un malware peut avoir créé des tâches dans des contextes différents: l’utilisateur qui possède le site, un autre utilisateur, ou même des fichiers de configuration inattendus.

Pour examiner proprement, vous devez accéder à la liste des cron jobs du serveur ou du compte d’hébergement. Sur beaucoup d’environnements, vous pouvez voir:

    les cron jobs de l’utilisateur qui exécute le site, parfois des fichiers déposés dans des répertoires où le système lit automatiquement des crontabs, et des scripts lancés via php, sh, ou des commandes exotiques.

Quand vous identifiez un cron suspect, ne vous contentez pas de le supprimer. Pensez à l’origine: ce cron a probablement été créé par quelqu’un ou quelque chose qui a eu accès aux fichiers. Donc, en parallèle, vous devez vérifier l’intégrité des fichiers et des droits.

image

Voici une première checklist courte, qui m’a évité des erreurs bêtes plus d’une fois.

Couper l’exécution temporairement (wp-cron et cron système) pendant l’inspection, le temps de vérifier les déclenchements. Repérer les entrées cron qui exécutent un script hors du périmètre attendu (fichiers, chemins, commandes). Contrôler qui possède les fichiers ciblés (propriétaire, groupe, droits) et depuis quand ils ont été modifiés. Lister les accès récents et tentatives de connexion sur le serveur, en particulier autour de l’heure du redémarrage du malware. Ne supprimer que ce que vous comprenez, et documenter chaque action avant de toucher au reste.

Cette liste n’est pas une recette universelle, mais elle force une discipline utile: arrêter le feu, diagnostiquer, puis agir sans perdre la traçabilité.

Comment reconnaître un cron malveillant (sans paranoïa)

Un cron “normal” ressemble à un travail de routine: exécuter un script de maintenance, lancer un backup, envoyer des notifications, ou purger un cache. Un cron malveillant a souvent des signaux discrets mais constants:

    la commande pointe vers un fichier ou un dossier qui n’appartient pas à WordPress, le chemin contient des dossiers générés récemment, la commande exécute php avec des arguments inhabituels, par exemple un script placé dans un répertoire non prévu, ou la tâche lance un binaire shell, un wget ou un curl pour récupérer une charge utile.

Attention à un piège fréquent: certains environnements d’hébergement utilisent des scripts de maintenance ou de sécurité légitimes qui ressemblent à “wget”, “curl” ou des commandes réseau. La question n’est pas “est-ce que curl apparaît”. La question est “à quoi correspond exactement la commande” et “pourquoi elle apparaît maintenant”.

C’est aussi pour cela que l’étude des timestamps est cruciale. Si le fichier exécuté par le cron n’existait pas avant une date précise, et qu’à cette date vos symptômes commencent, le dossier est suspect même si la commande n’est pas totalement farfelue.

Désinfecter: supprimer la charge utile, mais aussi la mécanique

Une désinfection efficace a deux couches:

1) retirer la charge utile visible et les fichiers compromis,

2) supprimer ou neutraliser la mécanique qui relance l’infection, typiquement les cron jobs malveillants et les hooks wp-cron créés par le malware.

Le risque, c’est de faire seulement la couche 1. Vous remplacez des fichiers, vous supprimez l’injection. Le cron système continue, et il recrée. Ou wp-cron continue, et il régénère.

Dans l’autre sens, si vous coupez le cron malveillant mais oubliez des fichiers compromis, vous pouvez aussi vous retrouver avec un site qui reste “sale”, mais plus discret. Parfois l’injection persiste dans un cache ou dans des fichiers de template, et les symptômes peuvent réapparaître quand le cache saute ou quand certains pages sont régénérées.

Dans un cas concret que j’ai vu, une équipe avait supprimé l’entrée cron système, mais pas un fichier de script caché dans un dossier de uploads. Le cron n’était plus déclenché, mais quand un utilisateur avait le malheur de déclencher une https://gardewp.fr/ régénération, le script avait encore assez de matière pour réinjecter un morceau de code. Moralité: la désinfection doit être complète, pas seulement “sur le point de déclenchement”.

Vérifier et corriger les permissions et les propriétaires

Quand un malware gère un cron, il a presque toujours trouvé une faille de contrôle. Cela peut venir d’un mot de passe faible, d’une vulnérabilité dans un plugin ou un thème, d’une mauvaise configuration, ou de droits trop permissifs sur des dossiers.

Après avoir retiré la tâche malveillante et les fichiers suspects, prenez le temps de vérifier:

    le propriétaire des fichiers WordPress, les droits sur les répertoires et fichiers, et les autorisations d’écriture sur des zones critiques.

Si des scripts ont été exécutés, il est possible que le malware ait créé des fichiers avec des droits qui facilitent les retours. Même si vous supprimez ce qu’il a créé, une configuration de droits trop ouverte peut redonner une surface d’attaque.

Je sais que c’est pénible, mais c’est souvent le moment où on stoppe la récidive. En général, vous ne voulez pas que “n’importe qui” puisse écrire dans des endroits où WordPress ou votre utilisateur système doit être le seul acteur.

Mots de passe et comptes: couper l’accès initial

Les cron jobs sont l’exécution. L’accès initial est souvent ailleurs. Après un incident, je recommande de traiter le mot de passe comme compromis, même s’il “semble” intact.

Changez les mots de passe pour les comptes administrateurs WordPress, et si possible pour les comptes de service liés à l’hébergement (notamment ceux qui ont accès à l’espace fichier, à la base de données, et à la gestion du serveur). Si vous utilisez des identifiants d’automatisation, surveillez-les aussi.

Ensuite, vérifiez les comptes WordPress pour détecter des utilisateurs ajoutés discrètement, des rôles inattendus, et des sessions actives.

Le lien avec les cron jobs est direct: si un utilisateur a été créé, ou si une session persistante a été conservée, le malware peut reconfigurer les tâches planifiées rapidement, dès que vous coupez une partie de l’infection.

Mettre en place une garde anti-récidive sur les cron

Une fois le site nettoyé, le but est d’empêcher la création silencieuse de nouvelles tâches.

Sur le plan “process”, cela passe par la surveillance et le contrôle. Sur le plan “technique”, cela passe par:

    limiter les écritures sur les répertoires, surveiller la création de scripts dans les zones inhabituelles, restreindre qui peut modifier la configuration de cron, et garder un inventaire de ce qui est censé exister.

Si vous avez accès à des outils de journalisation, exploitez-les. Un cron malveillant laisse souvent une signature: une commande lancée depuis un chemin non attendu, puis des modifications de fichiers à proximité.

Voici une deuxième liste courte, orientée opération, pour cadrer la fin de l’incident et la prévention.

Établir la “liste attendue” des cron jobs légitimes (commande, fréquence, propriétaire, chemin). Activer ou renforcer les alertes de changements sur la crontab et sur les fichiers exécutés (même simples). Mettre en place une rotation de clés et vérifier les accès admin et SSH, si vous les utilisez. Vérifier périodiquement l’intégrité de dossiers critiques (au minimum les fichiers PHP principaux). Mettre à jour plugins et thèmes, en priorisant ceux récemment installés ou ceux qui ont été laissés longtemps sans maintenance.

Ce n’est pas glamour, mais ça réduit de façon drastique les “incidents de retour”.

Cas limites: quand le malware imite le fonctionnement normal

Parfois, ce que vous trouvez n’est pas franchement malveillant, ou du moins pas évident. Par exemple:

    un hébergeur met en place des tâches d’audit, un plugin de performance planifie une purge ou une minification, un outil de sécurité utilise des scripts pour collecter des données.

Dans ce contexte, le test n’est pas “suppression immédiate”. Le test, c’est l’adéquation.

Posez-vous ces questions:

    Est-ce que la commande correspond à la description d’un outil légitime que vous utilisez ? Le fichier exécuté existe-t-il et a-t-il un historique cohérent avec votre installation ? La fréquence est-elle “raisonnable” et stable ? Est-ce que la commande déclenche des modifications de fichiers ou des téléchargements réseau non expliqués ?

Si vous avez un doute, vous pouvez aussi dupliquer l’environnement en local à partir d’une sauvegarde propre. Vous inspectez, vous observez ce que déclenche la tâche, puis vous décidez. L’important est d’éviter l’erreur classique: casser une tâche légitime et perdre du temps, pendant que la vraie menace reste active ailleurs.

Une méthode d’analyse pratique quand vous avez un chaos de logs

Quand les logs sont confus, je fais une approche “chronologie”. Je pars de l’heure approximative du symptôme, puis je remonte.

    D’abord, cherchez des événements autour de cette heure: création de fichiers, appels à des scripts, connexions. Ensuite, croisez avec les planifications. Si un cron tourne à une minute près, c’est un lien plausible. Puis, identifiez la première modification. Souvent, la première action du malware est celle qui compte pour retrouver la cause.

Cette approche marche particulièrement bien quand vous avez des horaires de sauvegarde et de mise à jour. Si vous n’avez rien déployé, mais qu’un fichier a été modifié, et qu’un cron a été ajouté juste après, vous tenez une piste solide.

Remettre WordPress d’aplomb: modèle de restitution

Une bonne désinfection ne se limite pas à “supprimer ce qui est mal”. Vous voulez aussi reconstruire sur une base saine.

Selon votre niveau d’accès et votre tolérance au risque, vous pouvez:

    restaurer certains dossiers critiques depuis une sauvegarde connue propre, réinstaller WordPress en conservant prudemment la configuration, et purger les caches.

Le point crucial est de ne pas “réinjecter” des fichiers compromis. Si vous avez une sauvegarde partiellement infectée, la restauration peut ramener la charge utile. C’est pour cela que la sauvegarde “propre” doit être choisie intelligemment, souvent celle qui précède la première apparition des symptômes.

Si vous avez des doute sur la sauvegarde, vous pouvez procéder par comparaison: dates de modification, présence de fichiers inconnus, et cohérence avec l’installation actuelle.

Checklist finale avant de remettre le site en production à pleine vitesse

Une fois que vous pensez avoir neutralisé cron jobs malveillants et autres mécanismes, faites une dernière validation pragmatique. Je ne parle pas d’un audit parfait, mais d’une série de vérifications “qui attrapent la plupart des retours”.

Sur le site, testez les pages sensibles et les zones d’accès: pages publiques exposant des injections, connexion admin, pages générées par des formulaires. Côté serveur, surveillez quelques heures les comportements: pas de nouvelles commandes suspectes, pas de création de fichiers en boucle, pas de pics d’erreurs liés à des scripts.

Et gardez un œil sur les requêtes sortantes si votre serveur en produit. Beaucoup de malwares se “mettent à jour” de manière sournoise, tant qu’ils ont une capacité réseau.

Ce qui m’évite le plus souvent d’être “trop tard”

Je reviens à un point de méthode, parce qu’il change la qualité du résultat: ne chassez pas un malware “au feeling”. Reliez toujours vos actions aux déclencheurs. Si vous voyez un symptôme, cherchez ce qui le relance.

Quand vous suspectez un virus WordPress lié aux cron jobs, le vrai travail consiste à trouver la mécanique de réactivation. Une fois que vous coupez cette mécanique et que vous corrigez les accès à l’origine, la désinfection devient beaucoup plus stable.

Si vous me décrivez votre contexte, par exemple votre hébergeur (ou au moins si vous avez accès à la crontab et à des logs), et les symptômes exacts (redirige-t-on, spam dans un formulaire, injection dans header, comptes créés), je peux vous proposer une démarche d’investigation plus ciblée, avec les endroits à regarder en priorité.