Quand un site WordPress “revient” après une désinfection, le problème est rarement une simple histoire de fichier infecté une fois pour toutes. Le scénario classique ressemble à ça : vous nettoyez, vous remettez le cœur du site à plat, puis quelques heures ou jours plus tard, des pages changent, des redirections apparaissent, ou des utilisateurs reçoivent des messages bizarres. Le site semble même parfois reprendre du service “tout seul”, comme s’il avait une mémoire de l’infection.

Dans cette mécanique, les tâches planifiées via cron jouent un rôle central. Elles peuvent servir de persistance: re-télécharger un chargeur, réinjecter un webshell, rétablir des scripts d’admin, ou modifier des fichiers à intervalles réguliers. Et comme cron tourne sans interface graphique, il laisse moins de traces visibles qu’un script lancé à la main. C’est précisément pour ça qu’un audit ciblé des tâches cron est souvent l’étape qui fait la différence lors d’une désinfection WordPress sérieuse.
Comprendre ce que “cron suspect” veut vraiment dire
Sur un hébergement WordPress, vous pouvez rencontrer deux mondes qui se ressemblent sans être identiques.
Le premier, c’est cron côté serveur (Linux), avec un planificateur système qui exécute des commandes à des heures précises, ou selon des intervalles. Ici, l’attaque vise souvent à ajouter une ligne cron qui appelle un script malveillant, parfois en s’appuyant sur des chemins tordus, des variables d’environnement, ou des scripts déposés dans des répertoires inattendus.
Le second, c’est WordPress lui-même avec wp-cron. Techniquement, wp-cron est déclenché par les visites, il simule des tâches planifiées. Une infection peut pousser des comportements en déclenchant wp-cron ou en abusant d’actions internes, mais wp-cron n’explique pas à lui seul les “reboots” réguliers du site après nettoyage si la persistance est réellement au niveau serveur. En pratique, si vous suspectez une persistance forte, vous commencez par regarder cron système.
La question n’est pas “cron est-il dangereux ?”. La bonne question est: “Est-ce que votre site a des tâches planifiées qui n’ont aucune raison d’exister, ou qui exécutent autre chose que ce que le site et l’équipe attendent ?”
Signaux d’alerte qui doivent vous pousser vers cron
Avant de courir vers le système, j’aime bien rassembler des indices. Ils ne sont pas des preuves à eux seuls, mais ils orientent la recherche et évitent de perdre des heures à “tout inspecter”.
Par exemple, si vous constatez l’un de ces comportements, l’hypothèse cron suspect devient prioritaire :
- Des fichiers qui réapparaissent après suppression, surtout dans des emplacements inhabituels (racine du site, sous-dossiers d’assets, thèmes et plugins “custom”). Des appels réseau répétitifs à des moments réguliers, visibles dans des logs applicatifs ou dans le trafic serveur. Des redirections vers des domaines externes qui reviennent selon un rythme plutôt stable (par heure, toutes les X minutes). Des tentatives d’écriture dans la base de données à répétition, avec des schémas qui ne ressemblent pas à des mises à jour normales.
Un détail que j’ai vu plusieurs fois sur des sites déjà “nettoyés” : une équipe supprime le fichier malveillant, mais oublie le déclencheur. Le fichier ne tient pas longtemps, mais la ligne cron reste. Résultat, l’attaque se contente de reposer au prochain cycle en recréant le fichier ou en appelant un autre maillon.
Où regarder, concrètement, côté serveur
L’audit cron ne consiste pas à lire un fichier au hasard. Il faut comprendre où peuvent se cacher les entrées.
Selon la configuration d’hébergement, les tâches planifiées existent souvent dans plusieurs endroits: les crontabs de l’utilisateur (via crontab -l), les fichiers dans /etc/cron.*, et parfois des entrées dans des répertoires de configuration spécifiques. Sur certains hébergeurs, il y a aussi une couche de gestion qui écrit des fichiers automatiquement. D’où l’importance de comparer avec ce que vous savez être légitime pour le site.
Mon approche est toujours la même: je commence par les “sources probables” pour un WordPress hébergé de manière classique, puis j’approfondis seulement si je trouve quelque chose d’anormal.
Crontab des utilisateurs
La première piste, c’est la crontab associée à l’utilisateur qui exécute le site (souvent l’utilisateur du compte hébergement, parfois www-data sur des environnements Debian, mais pas toujours).
Selon les accès dont vous disposez, vous pouvez:
- lister la crontab de l’utilisateur de l’application, lister les crontabs des autres utilisateurs si vous avez les droits, vérifier aussi les fichiers /var/spool/cron ou équivalents si votre environnement le permet.
Ce que je cherche dans les lignes, c’est moins le fait qu’il y ait une tâche (il y en a toujours), et plus ce qui est exécuté. Une tâche cron “saine” appelle typiquement des scripts internes clairs, dans des chemins attendus, avec des commandes lisibles. Une tâche suspecte appelle quelque chose de chargé depuis l’extérieur, exécute un binaire opaque, lance un interpréteur avec une commande tordue, ou manipule des fichiers hors de portée.
Répertoires de cron système
Ensuite, je vérifie les systèmes “périodiques” des répertoires /etc/cron.daily, /etc/cron.hourly, /etc/cron.weekly et /etc/cron.monthly. Même si elles servent souvent à l’administration de l’hôte, certaines infections s’y glissent quand elles gagnent suffisamment de contrôle.
La clé, c’est la provenance: est-ce que les scripts de ces répertoires correspondent à ce que l’hébergeur installe normalement, ou est-ce qu’il y a un fichier ajouté récemment, avec un nom qui n’a aucune logique pour votre stack ?
Comment repérer une ligne cron suspecte (sans tomber dans la paranoïa)
Les malwares n’écrivent pas tous la même ligne, mais ils partagent des comportements.
Je surveille en particulier :
- L’utilisation d’outils “d’exfiltration” ou de “téléchargement” dans les commandes cron, par exemple curl, wget, base64 décodé à la volée, ou des combinaisons du type “télécharger, rendre exécutable, lancer”. Des chemins qui ne ressemblent pas à vos dossiers WordPress, comme un script dans un répertoire temporaire, ou dans un emplacement qui n’appartient ni au thème ni aux plugins. Des commandes qui passent par sh -c, bash -c ou des substitutions d’interpréteurs. Ce n’est pas interdit, mais c’est souvent une signature d’obfuscation. Un enchaînement “effacer puis écrire” ou “écrire puis nettoyer” qui vise à laisser peu de traces. Une fréquence trop régulière et trop agressive pour un besoin légitime (par exemple, toutes les minutes sur des tâches qui n’ont rien à voir avec des mises à jour).
Un cas concret que j’ai rencontré : une ligne cron toutes les 5 minutes appelait un script dans un répertoire qui ressemblait à de l’upload, mais qui n’était pas géré par WordPress. Le script re-téléchargeait un fichier PHP avec un nom “banal”, et effaçait l’empreinte de l’ancien. Le nettoyage initial avait retiré le fichier PHP visible, mais la prochaine exécution cron l’avait recréé.
L’importance du contexte utilisateur
Une même commande peut être légitime selon l’utilisateur et selon le dossier de travail.

Par exemple, une tâche exécutée par un compte système de l’hébergeur pour “renouveler un certificat” peut être normale. Mais une tâche identique dans la crontab de l’utilisateur WordPress, ou qui pointe vers les répertoires du site, ne l’est plus. La lecture “ligne par ligne” doit toujours être connectée à votre structure d’hébergement.
Si vous n’êtes pas sûr de qui doit posséder quoi, prenez 15 minutes pour cartographier “quel utilisateur sert WordPress” dans votre environnement. Ensuite seulement, vous interprétez les lignes.
Audit pas à pas: méthode de travail
Je vous propose une méthode pragmatique, orientée résultats. L’idée est de réduire le temps entre “j’ai une suspicion” et “j’ai une action corrective vérifiable”.
1) Lister toutes les sources cron pertinentes
Selon vos droits, vous devez au minimum récupérer:
- les crontabs des utilisateurs pertinents, les scripts présents dans les répertoires cron système, les éventuels jobs additionnels ajoutés par un panneau de contrôle (selon l’hébergeur).
L’objectif à cette étape n’est pas de juger, c’est de collecter. Faites une capture texte, ou un export, et stockez-le en lieu sûr. J’insiste sur la sauvegarde, car sur un incident, on regrette vite de ne pas pouvoir comparer “avant/après”.
2) Filtrer sur les commandes qui exécutent autre chose que l’attendu
Une fois les lignes récupérées, je passe au tri, en me concentrant sur les commandes. Je repère tout ce qui appelle:
- un exécutable non standard, curl, wget, php -r, python -c, ou des sh -c complexes, un script hors des chemins que je connais, des redirections vers /dev/null et des enchaînements qui masquent les sorties.
Il arrive qu’une tâche légitime redirige les sorties, donc ce n’est pas une preuve. Mais en audit, on cherche des “points de départ”.
3) Vérifier l’existence des fichiers et leur date réelle
Quand une ligne cron appelle un script, je vérifie:
- le chemin complet du script, ses permissions, sa date de modification, son contenu (au moins les premières dizaines de lignes et surtout les parties de logique).
Un bon repère: si le script n’existe pas, ou si son origine est claire (créé le jour d’une migration connue), ce n’est pas forcément une menace. En revanche, si la modification est contemporaine d’un pic d’activité suspect, ou si le contenu commence par une obfuscation, on creuse.
4) Lire la commande avec un regard “exécution réelle”
Beaucoup de lignes malveillantes font semblant d’être inoffensives. Le piège, c’est la commande complète après interpolation: variables, substitution de commandes, et concaténation.
Je m’assure de comprendre ce que la commande fait au moment exact où elle s’exécute. Par exemple, si la commande utilise une variable qui pointe vers un fichier dans un dossier temporaire, la menace peut être plus profonde que “juste un téléchargement”.
Une checklist courte pour trier vite
Si vous avez peu de temps, cette mini-checklist aide à décider où investir votre énergie. Elle ne remplace pas l’analyse, mais elle évite de partir dans tous les sens.
- Une ligne cron appelle curl ou wget, ou un binaire de téléchargement, dans le contexte WordPress Une ligne exécute un script situé hors des chemins habituels de votre déploiement Le script ou le fichier appelé a été modifié récemment, autour du moment des symptômes La commande utilise une obfuscation évidente, ou un enchaînement “télécharger, exécuter, supprimer” La fréquence de lancement est trop élevée pour une tâche légitime que vous connaissez
Si deux ou plus de ces points se vérifient, je traite l’ensemble comme suspect.
Casser la persistance sans aggraver la situation
Une désinfection efficace, ce n’est pas juste supprimer. C’est casser la chaîne qui reconstitue la menace.
Quand vous identifiez une entrée cron suspecte, vous avez plusieurs options selon votre environnement et vos droits. Dans l’idéal, vous supprimez la ligne cron et vous archivez les éléments supprimés (les fichiers et scripts) pour analyse. Ensuite seulement, vous nettoyez les artefacts.
Attention aux pièges courants :
1) Supprimer le fichier malveillant sans supprimer le cron. Le site “reviendra” au prochain cycle. 2) Supprimer le cron sans savoir quel mécanisme légitime il cassera. Sur certains sites, un job cron existe pour des tâches de sauvegarde, de purge, ou d’optimisation. Si vous supprimez aveuglément, vous risquez de créer un nouveau problème. 3) Nettoyer uniquement WordPress, sans toucher au système. Si le malware s’exécute au niveau serveur, il peut réinfecter les dossiers WordPress rapidement.
Le bon ordre dépend de ce que vous trouvez. En général, si la persistance est clairement cron, je commence par neutraliser le déclencheur, puis je nettoie ce que le déclencheur réinjectait.
Et si le cron suspect est “wp-cron” ou un plugin ?
Parfois, la persistance ne se trouve pas dans la crontab système, mais dans l’écosystème WordPress. Exemple: un plugin compromis qui programme des actions régulières, ou un thème qui s’accroche à des hooks.
Dans ce cas, votre audit cron doit être élargi vers les mécanismes internes. Vous pouvez vérifier si WordPress est en train de déclencher des actions à répétition sans correspondre à vos attentes. Les traces peuvent être visibles dans des logs applicatifs (si vous avez un minimum de logging), ou via des événements WordPress côté base de données. L’approche la plus robuste reste d’identifier la source du comportement, puis de retirer le code compromis.
Le point important: ne confondez pas “il y a de l’activité de cron” avec “il y a une compromission”. Wp-cron peut être déclenché par des visites, et certaines tâches d’optimisation peuvent sembler périodiques. L’audit doit remonter à la logique qui a été ajoutée, et à partir de là, décider si le code est sain.
Comment vérifier que le nettoyage “tient” sur la durée
Après une désinfection, le plus dur est de conclure que c’est vraiment terminé. J’ai vu des “faux positifs” où une injection était désactivée temporairement, puis revenait après un changement de configuration, ou après une nouvelle exécution planifiée.
Un contrôle sérieux repose sur deux axes: la chronologie et la répétition.
- Chronologie: les symptômes ont-ils cessé au bon moment, juste après la neutralisation du job cron suspect ? Répétition: le comportement ne revient-il pas pendant plusieurs cycles attendus (selon la fréquence de la tâche que vous avez neutralisée) ?
Si une ligne cron suspecte tournait toutes les 5 minutes, attendre seulement une demi-journée peut être insuffisant. Sur une tâche quotidienne, une fenêtre de 24 à 48 heures peut être plus réaliste. Je préfère me donner des marges selon votre niveau de risque, surtout si des actions gardewp.fr dangereuses sont en jeu (webshell, exfiltration, modification de pages publiques).

Exemple d’approche de réponse rapide (avec prudence)
Voici un déroulé que j’utilise quand j’ai une piste cron solide et que je dois agir sans attendre un audit complet.
- Je neutralise d’abord le déclencheur (ligne cron suspecte), sans supprimer tout le reste. Je surveille ensuite les fichiers ciblés: si un script n’est plus exécuté, les “réapparitions” cessent. Je récupère les fichiers qui ont été créés ou modifiés, pour identifier ce qu’ils faisaient (au minimum pour comprendre la logique d’infection). Je retire les artefacts WordPress et système liés à l’infection, en respectant les chemins et les permissions. Je vérifie enfin la cohérence des tâches restantes, pour éviter d’avoir cassé une fonctionnalité légitime.
Cette approche réduit les dégâts et donne une réponse nette: si le symptôme disparaît après neutralisation du cron, vous tenez un morceau du puzzle.
Renforcer après nettoyage: éviter que cron redevienne une autoroute
Une fois l’incident stoppé, la question devient: comment empêcher qu’un nouvel accès obtienne la capacité d’écrire des jobs planifiés ?
Il y a des leviers qui ne sont pas “cosmétiques” :
- Réduire les permissions et limiter ce que l’utilisateur a le droit d’exécuter. Vérifier la gestion des identifiants et l’absence de comptes inconnus dans WordPress, car un compromis WordPress peut servir de marchepied vers le reste. Durcir l’hébergement si vous le pouvez: logs accessibles, alertes de modifications de fichiers sensibles, contrôle d’écriture dans les répertoires clés. Mettre en place une routine d’audit, pas seulement lors d’incidents, par exemple une revue périodique des tâches cron et des scripts appelés.
Je sais que sur beaucoup d’hébergements, les alertes et durcissements avancés ne sont pas toujours disponibles. Dans ce cas, la meilleure alternative reste une discipline opérationnelle: rotation des mots de passe, nettoyage régulier des plugins inutiles, et surveillance des changements.
Cas difficiles: quand la ligne cron n’est pas évidente
Parfois, une tâche malveillante n’affiche rien de clairement “bad”. Elle peut appeler un script “propre” qui, en réalité, prépare une action, télécharge autre chose, ou déclenche une charge utile via des conditions.
Je fais alors deux choses:
1) Je relie la ligne à l’exécutable appelé, et j’examine ce que fait réellement ce script, pas seulement son nom. 2) Je compare les modèles de commandes avec ce que vous aviez déployé. Un script “maison” qui tourne depuis des mois et que vous connaissez est très différent d’un script apparu sans explication.
Si vous devez trancher rapidement et qu’il y a un doute raisonnable, je privilégie la sécurité au détriment du confort: on neutralise la tâche suspecte, puis on rétablit seulement si on a une confirmation qu’elle est légitime.
Ce qu’il faut collecter si vous devez documenter l’incident
Même si vous n’êtes pas dans un contexte réglementaire, documenter aide énormément pour éviter de refaire les mêmes erreurs.
Sans entrer dans une liste longue (et parce que chaque situation est différente), je recommande de garder:
- une copie des lignes cron analysées avant modification, les scripts et fichiers associés à ces lignes, les dates et heures de modification, un résumé des symptômes observés et de quand ils se sont arrêtés, et, si possible, les logs qui montrent la période du pic d’activité.
Cette matière vous sert ensuite à deux niveaux: comprendre l’attaque et prouver que la désinfection WordPress tient dans le temps.
Dernier point: ne pas oublier les autres vecteurs liés au planificateur
Une infection qui abuse de cron n’agit pas seule. Souvent, vous retrouvez aussi une autre piste parallèle: un plugin qui a été modifié, un utilisateur WordPress ajouté, des fichiers PHP inhabituels dans des répertoires de thème ou de uploads, ou des entrées de persistance complémentaires.
Le cron est un déclencheur. C’est rarement le seul problème. Mais c’est un déclencheur qui explique pourquoi “ça revient”.
Si vous faites un audit cron suspect, vous ne cherchez pas seulement à enlever une ligne. Vous cherchez à comprendre comment le site a été rendu autonome. Et quand vous cassez cette autonomie, la désinfection devient beaucoup plus stable.
Pour aller plus loin dans votre audit
Si vous souhaitez, vous pouvez me dire votre contexte, et je peux vous aider à structurer l’audit avec un niveau de prudence adapté:
- type d’hébergement (mutualisé, VPS, cloud, panneau style cPanel ou équivalent), accès disponible (SSH, accès direct aux crontabs, logs applicatifs), symptômes observés (redirections, réapparition de fichiers, pages modifiées, chargements réseau).
Avec ces éléments, je peux vous indiquer quoi regarder en priorité, comment interpréter les signatures de commande, et comment vérifier que la persistance a réellement été neutralisée.