Quand un site WordPress se met à “agir tout seul”, la première tentation est de croire que tout vient des plugins ou d’un thème vérolé. Parfois, c’est vrai. Mais, dans pas mal de cas vus sur le terrain, le point de bascule se cache ailleurs, dans quelque chose de plus discret et plus tenace: les cron jobs.
Les cron jobs, ce sont des tâches planifiées côté serveur qui tournent à intervalles réguliers, souvent sans interaction humaine. Un pirate qui veut persister, exfiltrer des données, injecter du contenu, envoyer du spam ou relancer un téléchargement malveillant n’a pas besoin de garder une porte web ouverte. Il peut simplement programmer des actions et laisser le serveur faire le travail à sa place.
Cette approche marche d’autant mieux que beaucoup d’administrateurs ont une visibilité limitée sur ce qui se lance, à quelle fréquence, et sous quel utilisateur système.
Dans cet article, je vais détailler une méthode réaliste pour investiguer, comprendre et neutraliser des cron jobs suspects dans le cadre d’une désinfection WordPress. L’objectif n’est pas seulement de supprimer, mais d’éviter l’“effet whack-a-mole”, où on supprime une tâche et une autre réapparaît.
Pourquoi les cron jobs mènent souvent la danse
Sur un WordPress compromis, vous pouvez voir des symptômes très variés: redirections vers des domaines douteux, pages qui se mettent à afficher du contenu étranger, fichiers qui changent sans raison, comptes qui tentent des connexions répétées, ou encore une montée de trafic “anormale” sur certains endpoints.
Ce qui relie beaucoup de ces comportements, c’est la façon de déclencher les actions.
Un attaquant peut: 1) déposer un webshell ou une charge dans un répertoire, 2) puis appeler ce webshell périodiquement, 3) ou récupérer une autre charge via curl/wget, 4) ou encore modifier des fichiers directement.
Or, le cron est idéal pour ça. Il permet une répétition automatique, et souvent il est moins visible qu’une porte web, surtout quand on regarde uniquement la partie WordPress (table wp_options, plugins installés, fichiers du thème).
J’ai déjà vu des cas où le site semblait “stabilisé” après suppression de quelques fichiers, puis retombait exactement au même endroit quelques minutes ou heures après. En creusant, on a trouvé une tâche planifiée qui recréait des fichiers et reconfigurait le mécanisme.
Premières observations: repérer le terrain avant de toucher
Avant d’ouvrir votre éditeur de crontab, prenez quelques minutes pour observer. Cela évite les gestes irréversibles pendant que vous perdez la trace de ce que vous cherchez.
Plus vous êtes méthodique, plus vous gagnez du temps après. Par exemple, si vous avez accès aux journaux, regardez:
- les périodes où le site “décroche” (pics de 5 minutes, décalages réguliers), les requêtes HTTP inhabituelles (accès à des scripts bizarres, paramètres suspects), et surtout les événements côté serveur, comme des exécutions de commandes, des erreurs de scripts, des tentatives de téléchargement.
Si votre hébergeur fournit une interface de logs, profitez-en pour corréler les heures. Les cron jobs tournent souvent à une granularité proche de “tous les X minutes”. Une corrélation même grossière aide énormément à prioriser.
À ce stade, la meilleure question est: “qu’est-ce qui tourne à heures fixes, en dehors des actions normales de WordPress ?”.
Où chercher les cron jobs sur un serveur
Les cron jobs ne sont pas tous stockés au même endroit. Selon l’hébergement, vous pouvez avoir plusieurs couches: crontab utilisateur, crontab système, fichiers dans /etc, ou encore des mécanismes générés par des outils de l’hébergeur.
Sur un serveur Linux classique, les emplacements courants incluent:
- les crontab des utilisateurs (commandes que l’utilisateur propriétaire du compte du site a pu programmer), les fichiers crontab système (souvent sous /etc), et parfois des scripts lancés par d’autres services (anacron ou équivalents).
L’idée n’est pas de tout lister à l’aveugle. L’idée est de partir d’un principe de désinfection WordPress: vous neutralisez le point d’entrée, puis vous coupez les mécanismes d’exécution persistants. Les cron jobs font partie de ces mécanismes.
Si vous êtes en hosting mutualisé, vous n’aurez pas toujours la même main que sur un VPS. Dans ce cas, l’interface de votre hébergeur devient votre “lecteur de crontab”, et c’est elle qui dicte ce que vous pouvez voir.
Ce que “suspect” veut dire, concrètement
Beaucoup de tâches planifiées existent pour des raisons légitimes: sauvegardes, mises à jour, tâches de cache, monitoring, nettoyage de logs.
Le piège, c’est de confondre fréquence, chemin et commande. Un cron “propre” ressemble souvent à ceci: il exécute un binaire connu, dans un répertoire attendu, avec une commande simple et une trace cohérente. Un cron “suspect” a souvent au moins un de ces traits.
J’ai tendance à me méfier si je vois:
- une commande qui télécharge quelque chose (curl, wget, tftp, ftp) vers ou depuis un chemin dans l’arborescence de votre site, un enchaînement de commandes avec des opérateurs comme “;” ou des redirections qui écrivent dans des répertoires web, des chemins qui sortent des répertoires de travail habituels (par exemple, des exécutions sous un dossier rarement utilisé par WordPress), des tâches qui appellent des scripts depuis des fichiers dont la date de modification ne colle pas avec votre historique, ou une exécution très répétée, surtout si elle n’a aucune logique métier.
Pour rester utile, voici une petite grille de lecture en pratique, sans prétendre remplacer votre propre analyse.
| Indice | Pourquoi c’est gênant | Exemple typique à inspecter | |---|---|---| | Téléchargement réseau | Peut servir à recréer une charge ou à mettre à jour un implant | curl/wget vers un fichier sous wp-content | | Exécution de script en lieu étrange | Peut indiquer une persistance hors des scripts attendus | bash appelé depuis un chemin “non WordPress” | | Redirections et logs bizarres | Souvent utilisé pour dissimuler ou pour stocker des sorties | “> /dev/null 2>&1” ou écriture dans un fichier web | | Fréquence élevée | Un attaquant préfère relancer vite avant d’être détecté | toutes les 1 ou 5 minutes | | Références à des domaines aléatoires | Peut indiquer une exfiltration ou récupération distante | URLs non liées à votre activité |
J’insiste sur un point: “suspect” ne signifie pas “malveillant” à 100 %. Un outil d’hébergement peut appeler curl pour des raisons légitimes, ou un script de sauvegarde peut manipuler des chemins. La désinfection WordPress devient efficace quand vous recoupez la commande, le fichier cible, et l’historique de modification.
Méthode d’enquête: lire, reproduire mentalement, puis vérifier
Une fois que vous avez identifié une tâche planifiée, ne la “supprimez” pas tout de suite. Cherchez d’abord à comprendre la chaîne.
Le cron est une commande, mais derrière la commande il y a souvent un parcours: un script appelant une autre commande, qui dépose ou modifie quelque https://gardewp.fr/nettoyage-malware-wordpress/ chose, puis qui nettoie les traces.
Un bon réflexe consiste à reconstituer, commande par commande, le chemin logique:
- Quel binaire est lancé ? Quel script est appelé ? Où se situe la cible sur le disque ? Est-ce que le script télécharge, exécute, ou modifie des fichiers ? Qu’est-ce que ça écrit (ou efface) en fin de course ? Le cron redirige-t-il une sortie vers un fichier ?
Quand je fais ce travail, je regarde aussi les dates. Si la tâche pointe vers un fichier qui a été modifié “hier” ou “il y a quelques heures” alors que votre WordPress est stable depuis des semaines, le doute devient très concret. À l’inverse, si tout est cohérent et ancien, vous pouvez gagner du temps en excluant une partie du bruit.
Enfin, si vous avez un accès shell, vérifiez aussi l’utilisateur qui exécute. Sur un mutualisé, l’utilisateur d’exécution peut être celui du compte du site. Sur un VPS, ça peut être root ou un utilisateur dédié. Le niveau de privilège compte, car il détermine ce que l’implant a pu faire en amont.
Désinfection WordPress: couper la persistance sans casser l’écosystème
Une désinfection WordPress correcte ne consiste pas seulement à retirer un fichier. Les cron jobs font partie de la persistance, et c’est là qu’on voit le plus souvent les “retours” après nettoyage.
La logique que j’applique est simple: 1) neutraliser l’exécution planifiée, 2) figer l’environnement pour éviter les mutations pendant l’enquête, 3) vérifier l’intégrité des fichiers réellement concernés, 4) puis seulement ensuite nettoyer les artefacts.
Le “figer l’environnement” peut prendre plusieurs formes selon votre situation. Sur un site en production, je recommande au minimum de mettre le site en maintenance le temps d’empêcher les mutations pendant que vous travaillez, ou de bloquer temporairement des actions externes si c’est possible. Sur un VPS, vous pouvez aussi travailler en dehors du flux principal, avec une copie.
Voici une approche pratique, en gardant l’esprit “désinfection” plutôt que “bricolage”.
Identifiez tous les cron jobs liés à votre utilisateur et ceux que l’hébergeur expose comme scripts “planifiés”. Mettez en pause ou commentez temporairement les tâches réellement suspectes, en documentant leur ligne exacte. Inspectez les scripts et fichiers pointés par ces tâches, notamment les chemins sous wp-content et tout ce qui ressemble à un binaire ou un exécutable caché. Vérifiez les dates de modification et comparez avec votre historique (dernière mise à jour plugin, migration, changement de thème). Recherchez si d’autres tâches ou mécanismes déclenchent les mêmes scripts (double persistance, scripts récupérés à la volée).
Cette liste est volontairement courte. Elle correspond au moment où la plupart des gens se trompent: ils veulent supprimer trop vite, ou ils veulent tout analyser avant de couper la source, et l’implant continue pendant qu’ils regardent.
Analyse des commandes: les détails qui trahissent
Le plus révélateur n’est pas “qu’il y a un cron”, c’est la forme de la commande.
Quelques signatures qui reviennent souvent dans des contextes malveillants:
- une commande qui chaîne plusieurs actions, par exemple “télécharger puis exécuter puis supprimer”, un appel à un script dans un répertoire non attendu, une suppression de fichiers après exécution, l’écriture dans un dossier du type uploads ou cache, puis l’appel d’un interpréteur pour “émettre” le contenu, ou l’usage de variables d’environnement et de chemins relatifs, qui compliquent la compréhension.
Je fais aussi attention au fait que certains attaquants cherchent à garder un comportement plausible. Ils peuvent utiliser un nom de script qui ressemble à un outil de maintenance. La différence, c’est le contenu réel et la commande qui l’appelle. Un outil légitime a une finalité cohérente, des dépendances normales, et souvent une trace dans la documentation interne de votre hébergeur. Un outil malveillant, lui, poursuit un objectif de compromission et d’exploitation.
Si vous voyez un cron qui appelle un binaire standard, mais que ce binaire est exécuté avec des arguments qui ciblent des fichiers web modifiés récemment, le doute se renforce.
Edge cases qui font perdre du temps (et comment les gérer)
Il existe des pièges classiques.
Premièrement, les jobs légitimes qui contiennent des mots “bizarres”. Un script de sauvegarde peut utiliser tar, zip, gzip, ou même faire appel à rsync. C’est normal. Ce n’est pas le mot-clé seul qui fait foi, c’est la destination et l’enchaînement.
Deuxièmement, les cron jobs “générés” par des panneaux d’administration. Certains hébergeurs créent des tâches automatiquement pour des contrôles ou des mises à jour. Vous pouvez les voir comme des lignes dans une zone qui ressemble à un crontab, mais le contexte est propriétaire. Dans ce cas, vous devrez valider avec le support ou la documentation hébergeur, sinon vous risquez de casser une mécanique.
Troisièmement, les faux positifs basés sur la fréquence. Un job toutes les 5 minutes pour purger un cache peut être normal. Un job toutes les minutes pour téléverser une ressource externe depuis un domaine inconnu, beaucoup moins.
Quatrièmement, la “double persistance”. J’ai déjà vu une tâche cron qui était supprimée, mais qui était recréée par une autre tâche, parfois moins visible. Si vous ne regardez que la première ligne suspecte, vous pouvez tomber dans une boucle.
La meilleure parade est d’associer chaque cron à une cible sur le disque. Si la cible est unique, vous pouvez remonter à tous les points qui la modifient ou l’appellent.
Vérifier l’impact sur WordPress, sans se contenter de “j’ai supprimé le cron”
Une fois les cron suspects neutralisés, il faut revenir à WordPress avec une question précise: est-ce que le site reste propre, ou bien l’implant a déjà modifié des fichiers qui persistent même sans cron ?
Les cron jobs sont souvent la roue qui fait tourner l’attaque. Mais l’attaque laisse parfois des traces:
- fichiers ajoutés dans wp-content, modifications de fichiers de thème, création de scripts dans des répertoires web accessibles, modifications dans des fichiers de configuration, ou dans des dépendances que WordPress charge, parfois aussi des modifications en base.
Dans un plan de désinfection WordPress sérieux, le travail ne se limite pas au cron. Vous devez vérifier ce qui a été touché.
Concrètement, je recommande de comparer:
- l’arborescence des fichiers modifiés récemment, l’intégrité des thèmes et plugins (fichiers altérés ou ajoutés), la présence d’entrées inattendues dans wp-content (scripts, fichiers .php non liés, archives), et la configuration de WordPress si elle a été manipulée (sans forcer des actions dangereuses, juste en vérifiant ce qui a été changé).
Si vous avez un cache, un CDN, ou des règles WAF, gardez en tête que certains contenus peuvent continuer d’être servis en mémoire même après suppression. Ne concluez pas trop vite à un échec ou à une réussite tant que vous n’avez pas observé le site après une période cohérente, le temps que les caches se purgent.
Stabiliser et surveiller: ce qui évite la rechute
Après désinfection, le risque n’est pas uniquement “reste-t-il un cron”. Le risque, c’est que l’accès compromis ait aussi permis d’autres modifications, ou que l’attaquant ait laissé une porte différente.

J’applique alors une stratégie de surveillance simple:
- je garde un œil sur les logs d’erreurs et d’accès, je vérifie les fichiers récemment modifiés, et je contrôle régulièrement les tâches planifiées, même après une première neutralisation.
Selon la gravité, je surveille pendant un ou plusieurs cycles de planification. Si un cron suspect tournait toutes les 5 minutes, il faut s’assurer qu’après neutralisation, rien ne se remet en place dans la même fenêtre de temps.
Si votre hébergeur propose une détection d’intégrité ou des alertes, activez-les. Si ce n’est pas le cas, un contrôle manuel périodique reste utile. Le but n’est pas d’être obsédé, c’est d’éviter de découvrir deux semaines plus tard qu’une persistance a repris.
Comment un cron arrive là: remettre le puzzle à sa place
Il est tentant de se dire: “on a trouvé un cron suspect, donc c’est la cause”. En réalité, le cron est souvent un symptôme de l’accès initial.
L’accès initial peut venir de:
- identifiants compromis, plugin vulnérable non mis à jour, thème modifié, ou script mal sécurisé, configuration trop permissive, ou faille sur une dépendance.
Je ne veux pas transformer cette partie en enquête policière. Mais je veux que vous gardiez une logique: si vous neutralisez le cron sans traiter la cause d’entrée, vous risquez de revoir apparaître d’autres tâches.
Après une désinfection WordPress, je pense systématiquement à renforcer:
- la sécurité des comptes, le principe du moindre privilège, et le cycle de mise à jour des extensions.
Vous n’avez pas besoin d’un arsenal complet. Mais vous avez besoin d’un comportement constant. Les attaques qui persiste via cron ne reposent pas uniquement sur la chance. Elles reposent sur la possibilité de réécrire des fichiers et de programmer une nouvelle exécution.
Cas fréquents observés sur des sites compromis
Sans prétendre dresser une cartographie universelle, voici des scénarios que j’ai vus revenir, avec des variations.
Un scénario typique: l’attaquant ajoute un fichier PHP dans wp-content ou dans un dossier moins surveillé, puis un cron lance un script qui télécharge des paramètres et exécute selon l’heure. Dans ce cas, supprimer le fichier seul ne suffit pas, car le cron peut le recréer.
Un autre scénario: le cron ne “fait” pas directement la charge. Il prépare l’environnement, par exemple en mettant à jour un script ou en réécrivant un fichier cible. La charge “visible” côté WordPress apparaît ensuite, et on croit que le problème vient uniquement du thème ou du plugin. Au final, c’est l’exécution planifiée qui orchestre la modification.
Enfin, il y a des compromissions où le cron est presque propre en apparence. Une commande banale appelle un script sans grande signature. Le côté inquiétant apparaît quand on ouvre le script et qu’on voit qu’il utilise une boucle, une logique de téléchargement, ou une transformation de contenu.
Dans tous ces cas, le chemin qui mène au bon diagnostic passe par une analyse chaîne complète, pas uniquement une suppression.
Une stratégie de désinfection WordPress orientée “fiabilité”
On peut faire un travail de désinfection rapide. On peut aussi faire un travail fiable. La différence, c’est la capacité à prouver que la compromission est restée contenue.
Le meilleur indicateur, ce n’est pas “le site n’affiche plus les redirections”. C’est plutôt:
- les cron jobs suspects restent absents au prochain cycle, les fichiers modifiés récemment ne reviennent pas, et les nouvelles modifications correspondent à vos actions légitimes.
Si vous avez accès à une sauvegarde saine, comparez les fichiers avant et après. Même une comparaison partielle peut trancher des questions. L’absence de comparaison laisse trop de place à l’auto-illusion.
Il y a aussi un arbitrage émotionnel. Supprimer un cron suspect, c’est gratifiant. Mais si vous le faites sans prendre note de la ligne exacte, sans comprendre la cible disque, vous perdez une partie du raisonnement. Et quand un cron réapparaît, vous n’avez plus la mémoire de ce que vous avez déjà tenté.

Mon conseil, simple et pas cher: documentez les lignes. Copiez-collez les commandes et conservez-les avec dates et horaires d’observation. Ce sont des traces qui servent autant à l’analyse qu’à la communication avec le support si vous devez escalader.
Deux questions à vous poser avant de déclarer le travail terminé
La désinfection WordPress est souvent évaluée trop tôt. Je préfère finir avec deux questions concrètes.
D’abord: après neutralisation des cron jobs suspects, est-ce que vous observez un changement durable sur la période de planification habituelle ? Si un job tournait toutes les 10 minutes, regardez au moins sur plusieurs heures, le temps d’être sûr que rien ne se remet en place.
Ensuite: avez-vous traité le point d’entrée probable ? Si les identifiants administrateur sont restés faibles, si des plugins vulnérables n’ont pas été mis à jour, si une règle de sécurité n’a pas été appliquée, le cron n’était probablement qu’un maillon de la chaîne. L’attaquant peut revenir avec une autre persistance.
Micro-check rapide (avant et après)
Voici une mini liste de contrôle qui tient sur une seule page, pour garder le cap pendant l’enquête. Elle n’est pas exhaustive, mais elle aide à ne pas oublier les fondamentaux.
- Notez les lignes de cron suspectes avant toute modification. Identifiez les fichiers ciblés par ces commandes et vérifiez leurs dates de modification. Coupez la persistance (cron) avant de lancer une suppression massive de fichiers. Surveillez logs et changements pendant au moins un cycle “long” par rapport à la fréquence suspecte. Renforcez l’accès (mises à jour, comptes, suppression des accès inutiles) pour éviter la réinfection.
Si vous appliquez ce cadre, vous transformez une désinfection WordPress souvent anxiogène en une démarche contrôlée. Le cron job devient ce qu’il doit être dans votre lecture: un mécanisme d’exécution, pas un mystère.
Et quand vous comprenez comment il a été créé, vous ne supprimez pas seulement un symptôme. Vous réduisez fortement la probabilité que l’attaque trouve une autre sortie.