Tâches cron malveillantes sur WordPress : comment nettoyer rapidement
Quand un site WordPress commence à se comporter bizarrement, on pense vite au thème, aux plugins, au cache, voire à une mise à jour ratée. Pourtant, dans les cas les plus agaçants, la source du problème n’est pas visible dans l’interface d’administration. Le déclencheur, c’est souvent en arrière-plan: des tâches cron malveillantes, planifiées pour injecter du code, créer des comptes, envoyer du spam ou rediriger les visiteurs.
Le pire, c’est que ces tâches peuvent rester dormantes longtemps, puis se réveiller toutes les heures, toutes les nuits, ou à une heure précise. Tant que vous ne coupez pas le mécanisme, vous “nettoyez” une infection, puis elle revient. Voilà pourquoi un nettoyage rapide, mais méthodique, doit commencer par le cron.
Je vais vous montrer comment identifier ces tâches, les supprimer proprement, puis remettre votre WordPress d’aplomb sans casser le site. Et comme l’objectif est de gagner du temps, je vais aussi parler des décisions à prendre quand on hésite, des cas limites, et des erreurs qu’on peut regretter.
Pourquoi le cron est un terrain de jeu pour les attaquants
Le cron, c’est la planification automatique de commandes sur un serveur. Sur un hébergement mutualisé, il peut être contrôlé via l’interface, mais aussi via des fichiers système, ou via des scripts placés dans des chemins que vous ne consultez jamais.
Les attaquants profitent de trois choses.
D’abord, le cron tourne sans interaction. Un visiteur ne “clique” pas, personne ne voit un bouton rouge. Ensuite, le cron peut lancer des commandes qui modifient des fichiers, téléchargent du contenu externe, ou appellent des endpoints en HTTP. Enfin, l’exécution peut être discrète: quelques secondes, une requête, puis retour au silence.
Dans un incident réel que j’ai géré, le site semblait propre pendant la journée. Les logs applicatifs montraient quelques erreurs 404 “classiques”. Puis, vers 02:15, les performances chutaient brutalement. Le pic correspondait à l’heure d’une tâche cron. Une fois la commande coupée, les anomalies ont cessé en quelques minutes. Là où le malware “revenait” après chaque purge, il s’est mis à ne plus réapparaître.
Les symptômes qui pointent vers des tâches cron
Vous pouvez tomber sur une infection par d’autres voies (fichiers modifiés, admin déployée, spam envoyé), mais certains signaux sont plus fortement associés au cron.
Par exemple:
Le site change de comportement à des heures régulières, surtout la nuit. Vous voyez des créations de fichiers “fraîches” même après nettoyage. Les plugins ou thèmes ne sont pas forcément corrompus, mais des fichiers dans des répertoires peu visibles ont été modifiés. Les logs serveur montrent des exécutions d’utilitaires (wget, curl, php, base64) que vous ne lancez jamais. Votre base de données n’explose pas, mais l’activité du serveur augmente.
Avant de vous lancer dans une chasse aux fichiers, prenez trente minutes pour comparer, à heure près, ce qui se passe “avant” et “après”. Si le problème arrive toutes les 6 heures, vous n’avez pas besoin d’imaginer des scénarios compliqués, vous cherchez une planification.
Le premier tri: WordPress, mais aussi serveur et hébergement
Beaucoup de gens se limitent à WordPress: ils fouillent wp-admin, inspectent les thèmes, les plugins, et les fichiers du dossier wp-content. C’est logique. Mais si la tâche cron est ajoutée au niveau serveur, vous pouvez avoir une situation où WordPress semble entier, pendant que le serveur planifie une commande qui touche WordPress, ou des fichiers externes.
Donc, dans votre diagnostic, distinguez ces trois niveaux:
La configuration cron côté serveur (fichiers du système, configuration de l’utilisateur, panneau d’hébergement). Les fichiers déclenchés par la tâche (scripts déposés, commandes appelées). Les effets dans WordPress (fichiers injectés, modifications de base de données, appels réseau).
La vitesse de réponse dépend de la clarté de ce tri.
Accès et prudence: ce que vous devez faire avant de “couper”
Avant de supprimer quoi que ce soit, sécurisez votre capacité à revenir en arrière.
Créez une sauvegarde rapide, même partielle: fichiers WordPress, dossiers susceptibles d’être touchés (souvent wp-content et parfois la racine), et une copie de la base de données si vous pouvez le faire sans bloquer le site. Si vous n’avez pas la fenêtre pour une sauvegarde complète, commencez par un snapshot ou au minimum un export SQL et une archive des fichiers modifiés récemment, selon ce que votre hébergement propose.
Ensuite, vérifiez l’accès: si vous êtes bloqué, que vous ne pouvez plus vous connecter au panneau, ou que des comptes sont créés, l’objectif n’est plus seulement de nettoyer, c’est de contenir. Le cron est un levier de containment, mais pas le seul.
Enfin, gardez en tête un piège fréquent: certains plugins de “sécurité”, ou certains outils de cache, utilisent déjà wp-cron. Ce n’est pas forcément malveillant. La question n’est pas “cron existe donc c’est mauvais”, la question est “cron déclenche quoi, et quand”.
Comprendre wp-cron vs cron serveur
WordPress a son mécanisme “wp-cron”, qui simule une tâche planifiée. Il se déclenche généralement lors des visites du site, en fonction du trafic, et il peut appeler des actions en PHP.
À côté, il y a le cron serveur, géré par le système (ou via l’outil d’hébergement). Les deux ne sont pas interchangeables.
Ce que vous cherchez en cas d’infection, ce sont les traces d’exécution externe, ou de commandes système. Dans la pratique, cela se manifeste souvent par un fichier ou un script appelé via une commande de type:
lancement de PHP sur un script dans un répertoire inattendu, téléchargement via curl ou wget, exécution de commandes base64, sh, ou équivalent, usage de répertoires temporaires ou de noms “camouflés”.
Si tout se limite à wp-cron, avec un comportement cohérent, ce n’est pas forcément un malware. Mais si vous voyez un cron serveur qui appelle PHP sur un chemin suspect, là, on passe en mode incident.
Où regarder pour trouver les tâches cron malveillantes
Les emplacements exacts dépendent de l’hébergement, mais la logique reste la même: cherchez la planification, puis remontez à la commande.
Souvent, sur un hébergement, vous pouvez trouver la configuration dans l’interface (cron jobs). Sinon, il faut regarder du côté des fichiers de configuration utilisateur ou du système. Sur un serveur avec accès SSH, on peut aussi chercher dans:
la configuration cron de l’utilisateur sous lequel tourne le serveur web, les fichiers “cron.daily”, “cron.hourly”, “cron.weekly”, si votre système les utilise, les scripts déposés dans des répertoires que WordPress ne nécessite pas.
L’approche qui marche le mieux, c’est de filtrer “ce qui a changé” ou “ce qui tourne”.
Un bon réflexe est de chercher dans l’environnement d’exécution des indices de fraîcheur: dates de modification de scripts, taille des fichiers, et présence de chaînes suspectes (URL, “base64_decode”, “eval”, “gzinflate”, en-têtes d’attaque, etc.). Sans exagérer les diagnostics, vous pouvez généralement repérer des motifs récurrents.
Lecture des commandes: ce que votre instinct doit repérer
Quand vous trouvez une ligne cron étrange, ne vous précipitez pas. “Nettoyer vite” ne signifie pas “supprimer au hasard”. Il faut comprendre ce que fait la commande.
Les attaquants tentent souvent de masquer par:
des variables et des chemins courts, des encodages dans la ligne elle-même, un chaînage avec plusieurs commandes, une exécution depuis un répertoire non standard.
Un exemple typique de pattern (je simplifie, car chaque cas diffère) est une commande qui appelle php avec un script dans wp-content ou dans une sous-arborescence improbable, puis qui télécharge une charge utile, ou appelle une URL externe.
Si la commande inclut des outils systèmes que vous n’avez jamais utilisés, comme curl, wget, nc, ou un appel à sh, c’est un drapeau rouge. Si en plus le script cible a été modifié récemment, vous avez quasi la certitude.
Procédure de nettoyage rapide: couper, auditer, éradiquer, puis restaurer
L’idée générale est simple: arrêter l’exécution du malware, identifier ce qui a été touché, supprimer ce qui est malveillant, corriger la cause (souvent une compromission d’accès), puis consolider.
Le “rapidement” ne veut pas dire improvisé. Sur un incident, une minute de réflexion évite parfois une heure de reconstruction.
Étape 1: désactiver la tâche cron suspecte sans casser le serveur
Dès que vous identifiez une commande suspecte, désactivez-la. Sur beaucoup d’hébergeurs, vous pouvez la supprimer ou la désactiver. Si vous pouvez la commenter dans un fichier de configuration, faites-le, mais uniquement si vous êtes à l’aise.
Si vous ne savez pas exactement quoi elle déclenche, vous pouvez faire un premier geste conservateur: désactiver la tâche, puis observer. Dans mon expérience, si c’est la cause, les symptômes se calment vite. Si rien ne change, vous explorez d’autres tâches ou vous cherchez des exécutions via un autre mécanisme.
Ne partez pas du principe que “la dernière tâche ajoutée” est la bonne. Certains malwares créent des tâches qui s’exécutent en boucle à des heures précises, d’autres utilisent des scripts déclenchés indirectement.
Étape 2: identifier le script ou les fichiers appelés
Une fois la tâche coupée, remontez à la cible. Si la tâche appelle php sur un script, localisez ce script. S’il télécharge du contenu, vérifiez si le code téléchargé existe déjà en local. Cherchez:
les fichiers modifiés récemment dans l’arborescence de WordPress, les fichiers PHP “isolés” dans des dossiers non habituels, les fichiers dont la taille est petite mais dont le contenu ressemble à un loader.
L’objectif est de faire un inventaire, pas encore de tout supprimer.
Étape 3: nettoyage des fichiers WordPress et des traces de persistance
C’est là que beaucoup de gens font demi-tour en disant “on a supprimé un fichier, mais ça revient”. Souvent, ce n’est pas qu’ils ont “mal nettoyé”. C’est que la persistance est multiple: le cron est un levier, mais il peut aussi y avoir des modifications dans des plugins, dans le thème actif, des fichiers dans wp-content/uploads, ou des backdoors en base.
Donc, quand vous nettoyez site WordPress infecté, pensez en couches:
fichiers chargés au runtime, fichiers déposés dans des dossiers d’apparence anodine, configuration ou options en base qui persistent la charge utile, comptes admin ou utilisateurs créés par l’attaque.
Pour la base, ne supprimez pas au hasard. Cherchez plutôt des utilisateurs créés récemment, des rôles inattendus, et des entrées d’options modifiées. Dans WordPress, l’infection peut aussi déposer des données dans des endroits internes, mais le plus fréquent https://gardewp.fr/nettoyage-malware-wordpress/ https://gardewp.fr/nettoyage-malware-wordpress/ dans les cas “cron malveillants” est un script PHP déposé quelque part, puis une exécution planifiée.
Étape 4: corriger la cause d’accès
Nettoyer ne suffit pas si quelqu’un peut réinjecter. La cause la plus courante, c’est une faiblesse d’identifiants, un thème ou plugin vulnérable, ou une configuration qui autorise trop facilement l’accès.
Vous devez vérifier:
les accès SSH ou FTP (si vous en avez), les comptes WordPress, surtout ceux créés récemment, les logs d’authentification (quand c’est disponible), les plugins et thèmes installés récemment.
Ici, l’étape “cause” ne doit pas être parfaite, mais elle doit être cohérente. Si vous avez un plugin non officiel installé la veille, ce n’est pas un hasard.
Étape 5: restauration contrôlée
Une fois le nettoyage effectué, restaurez la stabilité. Si vous avez une sauvegarde saine, remplacez les fichiers WordPress compromis par ceux de la sauvegarde. Si vous n’avez pas de sauvegarde, vous pouvez recharger un core WordPress propre, mais ce n’est pas suffisant si wp-content a été touché.
Le bon geste consiste à combiner:
suppression et remplacement des fichiers suspects, vérification des dossiers uploads, revalidation de l’intégrité du core, recontrôle du cron serveur et de toute autre persistance. Check rapide de triage (à faire en moins d’une heure)
Voici le type de mini-check que j’utilise pour décider où creuser en premier. Pas pour “tout faire”, juste pour ne pas perdre une soirée.
Comparez les heures d’apparition du problème avec les horaires des cron (serveur ou tâches applicatives). Désactivez la tâche cron la plus suspecte puis observez si le symptôme s’arrête. Repérez le script ou la commande appelée, puis vérifiez les fichiers ciblés (date de modification, emplacement). Cherchez dans WordPress les utilisateurs créés récemment et les plugins installés récemment. Préparez une sauvegarde avant toute suppression définitive. Deux cas fréquents qui changent la stratégie
Le cron malveillant n’est pas toujours “un seul fichier, une seule tâche”.
Cas 1: plusieurs tâches identiques, mais avec de petites variations
Parfois, vous trouvez une tâche A et une tâche B quasi identiques, exécutées à des horaires décalés. La première suppression peut masquer la seconde, et l’infection “revient” car la persistance complète n’est pas coupée.
Dans ce cas, vous devez élargir l’audit aux tâches proches, aux scripts appelés, et aux répertoires cibles. Ne vous limitez pas au moment exact où vous avez remarqué le problème, remontez un peu la période.
Cas 2: la tâche cron appelle un script “discret”, puis le vrai payload arrive après
La tâche déclenche un petit script qui fait peu de choses localement, puis télécharge le code réel. Si vous ne bloquez pas le téléchargement, vous pouvez supprimer l’empreinte locale mais laisser un mécanisme. C’est pour ça que couper le cron en premier est crucial.
Une fois la tâche coupée, vous pouvez analyser l’arborescence existante et comprendre ce qui a déjà été déployé. Ensuite seulement, vous supprimez.
Sécuriser après nettoyage: éviter la rechute sans casser l’exploitation
Après un incident cron, la sécurité n’est pas une liste de “cochez tout”. C’est un équilibre entre protection et maintenance.
Vous pouvez par exemple:
changer tous les mots de passe (comptes WordPress et accès serveur si applicable), activer l’authentification forte sur l’espace d’administration si vous pouvez, limiter les tentatives de connexion, mettre à jour thèmes et plugins.
Le point d’attention, c’est la compatibilité. Sur un site où un plugin “fait tout”, un verrou trop strict peut casser l’accès à une API ou à un service. Je préfère donc appliquer les mesures une par une, en surveillant.
Et gardez le cron sous surveillance. Si vous avez une politique de “toutes les tâches cron doivent être documentées”, vous détectez plus vite les prochaines dérives. Sur certains hébergeurs, les cron ne sont pas versionnés, donc la documentation interne devient votre garde-fou.
Comment analyser rapidement sans tout casser
Il y a une tentation forte: “je supprime tout ce qui a l’air bizarre”. C’est tentant, mais sur WordPress, “bizarre” peut être un plugin légitime, ou un script de maintenance.
Un outil utile est l’inspection du contenu et la comparaison des emplacements.
Quand vous trouvez un fichier PHP, posez-vous trois questions:
Est-il dans un dossier attendu par WordPress et par vos plugins? A-t-il été modifié récemment, juste autour de la fenêtre d’incident? Le contenu contient-il des marqueurs typiques de charge utile (encodage, exécution dynamique, téléchargement réseau)?
Sans tomber dans le paranoïa, ce tri réduit fortement les faux positifs.
Si vous êtes sur un site critique, je conseille aussi de garder la capacité à “diff” ou comparer avec une sauvegarde saine. Vous pouvez détecter quels fichiers ont changé, sans supposer.
Mesures de containment pendant que vous nettoyez
Parfois, vous devez agir alors que le site est encore actif et potentiellement exploité.
Le containment vise à réduire l’exposition pendant que vous travaillez.
Concrètement, vous pouvez mettre le site en maintenance temporaire, ou limiter l’accès à l’administration, si votre hébergeur le permet. Vous pouvez aussi bloquer temporairement certains patterns au niveau serveur, si vous identifiez des requêtes répétées.
Attention toutefois: si le malware utilise un appel externe, masquer seulement l’interface peut ne rien changer, il faut aussi couper l’exécution planifiée, donc le cron en premier.
Quelles preuves conserver pour votre prochaine vérification
Une fois le nettoyage fait, conservez des éléments. Pas par amour des rapports, mais parce que vous ne voulez pas refaire le travail si une réinfection survient.
Gardez:
une copie des tâches cron avant suppression (au moins la ligne et la commande), un inventaire des fichiers supprimés ou modifiés, une liste des utilisateurs retirés ou restaurés, et les journaux utiles de la période d’incident.
En cas d’urgence, vous pouvez aussi conserver une capture des heures d’activité serveur. L’idée est de pouvoir corréler à nouveau si un comportement similaire apparaît.
Check-list finale de “stabilisation” (sans entrer dans une liste interminable)
À la fin, avant de rouvrir au public, faites un passage de validation. Voici le genre de séquence que je suis, en restant pragmatique.
Confirmez que la ou les tâches cron suspectes sont bien supprimées ou désactivées. Vérifiez que les fichiers ciblés par ces tâches ne sont plus présents (ou qu’ils sont remplacés par un contenu sain). Contrôlez les comptes WordPress, surtout ceux créés pendant la fenêtre d’incident. Relancez le fonctionnement normal, puis surveillez les performances pendant quelques heures. Gardez un œil sur les logs réseau et d’erreur, car une persistance oubliée se voit souvent dans les premières heures après restauration.
Si tout est propre, vous devriez voir une disparition du pic d’activité et du comportement “à heure fixe”.
Pièges classiques qui font perdre du temps
Quelques erreurs reviennent tout le temps.
La première, c’est de ne couper que wp-cron alors que la persistance est sur le cron serveur. Résultat: vous voyez une amélioration ponctuelle, puis ça repart.
La deuxième, c’est de supprimer des fichiers sans vérifier d’où ils viennent. Vous effacez un loader, mais une autre tâche recrée le loader.
La troisième, c’est de réinstaller WordPress propre sans traiter wp-content et la base. Le core seul n’est pas votre problème si la charge utile vit ailleurs.
Enfin, il y a le piège “c’est probablement le thème”. Parfois oui, mais sur les infections par cron, le thème est rarement le point de départ. Il peut être touché en sortie de compromis, mais la commande planifiée trahit souvent l’origine.
Si vous devez choisir: nettoyer vite ou analyser en profondeur
Vous avez peut-être une contrainte claire, site e-commerce, campagne marketing, ou SLA. Dans ce contexte, l’analyse parfaite peut attendre.
Mon compromis, en pratique, ressemble à ceci:
d’abord, couper le cron malveillant et contenir, ensuite, enlever les fichiers et utilisateurs les plus évidents, et seulement après, faire un audit plus large (plugins, base, traces secondaires).
Si vous inversez, vous risquez de perdre du temps sur des éléments symptomatiques tout en laissant le mécanisme d’infection actif.
Un mot sur l’usage d’outils de sécurité
Les scanners de sécurité WordPress peuvent aider, surtout pour repérer des signatures ou des modifications de fichiers. Mais dans le cas précis des cron malveillants, aucun outil ne remplace l’inspection des tâches planifiées et des commandes associées.
Je vois souvent des équipes “tout scan, puis supprime ce que le scan dit”. C’est utile, mais si la tâche cron reste en place, elle continue de recréer le problème. Les scanners font gagner du temps pour l’audit, pas pour l’arrêt du mécanisme.
Recommandation pratique: documenter votre cron après nettoyage
Une fois que tout est stable, prenez cinq minutes pour une tâche rarement faite: documenter.
Notez quelles tâches existent, à quoi elles servent, qui les a configurées, et à quelle fréquence elles tournent. Si vous avez plusieurs environnements (prod, staging), documentez aussi les différences. Quand un incident revient, vous ne repartez pas de zéro.
Si vous voulez, décrivez-moi votre contexte (hébergement avec panneau ou accès SSH, présence d’une tâche cron identifiée, ou horaires de symptômes). Je peux vous aider à interpréter une ligne suspecte et à décider quoi vérifier en priorité, sans vous faire perdre du temps sur des pistes secondaires.