Cron, anacron, at et timers systemd : planification
Artefacts de planification Linux (crontabs, horodatages anacron, tâches at, timers systemd) qui révèlent la persistance planifiée et prouvent les exécutions.
- Emplacement
- /var/spool/cron/
- Prouve
- Quelles commandes étaient planifiées, par quel compte, et quand cron, anacron ou un timer les a lancées pour la dernière fois
- Horodatages
- mtime/ctime des fichiers ; heure syslog ou journal pour les exécutions ; horodatages anacron en date locale AAAAMMJJ
- Accès
- root pour tous les répertoires de spool ; tout utilisateur pour sa propre crontab via crontab -l
- Rétention
- Jusqu'à suppression ; les preuves d'exécution suivent la rotation de syslog/du journal
- Collecte
- UAC, Velociraptor, cp -a, journalctl
Outils
Comparer tous les outils- VelociraptorPlateforme · open source
- UACCLI · open source
- grep / zgrepCLI · intégré à Linux
- systemctlCLI · intégré à Linux
Ce que c'est
Linux dispose de quatre planificateurs qui se recoupent. cron (Vixie cron sous Debian et Ubuntu, cronie dans la famille RHEL) exécute des tâches récurrentes depuis des tables système et par utilisateur. anacron exécute les tâches quotidiennes, hebdomadaires et mensuelles sur les machines qui ne tournent pas en permanence, et mémorise la date de dernière exécution. at (atd) exécute des tâches ponctuelles. Les timers systemd sont des unités .timer qui activent un service selon un calendrier ou un délai monotone, et assurent désormais une bonne partie de la maintenance autrefois confiée à cron.
Tous les quatre reposent sur de simples fichiers sur disque, faciles à collecter et faciles à détourner pour un intrus (MITRE ATT&CK T1053.003 cron, T1053.002 at, T1053.006 timers systemd).
Où il se trouve
| Artefact | Debian / Ubuntu | RHEL / Fedora / Rocky / Alma |
|---|---|---|
| Table système (avec champ utilisateur) | /etc/crontab | /etc/crontab |
| Tables système additionnelles | /etc/cron.d/* | /etc/cron.d/* (dont 0hourly) |
| Répertoires de scripts run-parts | /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly | identique |
| Crontabs utilisateur (sans champ utilisateur) | /var/spool/cron/crontabs/<user> | /var/spool/cron/<user> |
| Configuration anacron | /etc/anacrontab | /etc/anacrontab |
| Horodatages de dernière exécution anacron | /var/spool/anacron/<job-id> | /var/spool/anacron/<job-id> |
| Tâches at | /var/spool/cron/atjobs/ (plus atspool/) | /var/spool/at/ (plus .SEQ) |
| Contrôle d'accès | /etc/cron.allow, /etc/cron.deny, /etc/at.allow, /etc/at.deny | identique |
| Unités timer | *.timer dans les chemins d'unités systemd (voir unités systemd) | identique |
| Horodatages des timers persistants | /var/lib/systemd/timers/stamp-<name>.timer | identique |
Timers transitoires (systemd-run --on-*) | /run/systemd/transient/, /run/user/<uid>/systemd/transient/ | identique |
| Journal d'exécution | Lignes CRON[pid] dans /var/log/syslog ou le journal | /var/log/cron ou le journal |
Sous RHEL, /etc/cron.d/0hourly exécute /etc/cron.hourly, où un script lance anacron, qui gère ensuite les répertoires daily, weekly et monthly. Sous Debian, /etc/crontab appelle run-parts pour ces répertoires, sauf si anacron est installé.
Ce qu'il prouve
- Persistance planifiée : quelle commande doit s'exécuter, à quelle fréquence et (pour les tables système) sous quel utilisateur. Les crontabs utilisateur s'exécutent sous le propriétaire du fichier.
- Exécution : une ligne de journal
CMDprouve que cron a lancé la commande à cette minute. Elle ne prouve pas que la commande a réussi. - Dernière exécution périodique : un horodatage anacron enregistre la dernière date d'exécution d'une tâche ; le mtime d'un fichier stamp de timer enregistre le dernier déclenchement d'un timer
Persistent=true. - Qui a modifié une crontab : les lignes
crontab[pid]: (user) BEGIN EDIT / REPLACE / END EDITdu journal. - Non prouvé : la seule présence d'un fichier de tâche ne montre pas qu'il a été exécuté (le démon peut être désactivé, ou le fichier ignoré ; le cron de Debian ignore les noms de
/etc/cron.dcontenant un point).
Champs clés
| Élément | Signification |
|---|---|
m h dom mon dow | Les cinq champs de planification de chaque ligne de crontab |
| champ utilisateur | Sixième champ, uniquement dans /etc/crontab et /etc/cron.d/* |
@reboot, @hourly, @daily ... | Planifications abrégées ; @reboot est une favorite pour la persistance |
MAILTO, SHELL, PATH, CRON_TZ | Lignes d'environnement dans une crontab ; CRON_TZ (cronie) change le fuseau horaire de la planification |
anacrontab period delay job-identifier command | Jours entre deux exécutions, délai en minutes, nom du fichier d'horodatage, commande |
START_HOURS_RANGE, RANDOM_DELAY | Fenêtre d'exécution et décalage aléatoire d'anacron |
| fichier de tâche at | Script shell : environnement capturé, cd vers le répertoire de travail d'origine, commande à la fin |
.timer OnCalendar=, OnBootSec=, OnActiveSec=, OnUnitActiveSec= | Déclencheur calendaire ou monotone |
.timer Unit=, Persistent= | Unité activée (par défaut : le .service de même nom de base) ; rattrapage après une période d'arrêt |
Horodatages
- Les crontabs et fichiers de tâches ne portent que des horodatages du système de fichiers. Comme
crontabréécrit le fichier de spool, son mtime correspond à la dernière installation. Sous Debian, un fichier installé parcrontabcommence par un en-têteDO NOT EDIT THIS FILEqui nomme le fichier temporaire et la date d'installation ; un fichier de spool sans cet en-tête a probablement été écrit directement. - Les horodatages anacron contiennent la date de dernière exécution au format
YYYYMMDD(sans heure), en heure locale. - Les fichiers stamp des timers sont vides ; l'information réside dans le mtime du fichier.
- Les lignes de journal suivent le format syslog (voir syslog et auth.log) ; les entrées du journal systemd stockent des microsecondes depuis l'epoch Unix en UTC.
stat -c '%y %z %n' /mnt/evidence/var/lib/systemd/timers/stamp-*.timer
cat /mnt/evidence/var/spool/anacron/cron.daily # e.g. 20260927
Rétention
Les crontabs, les tâches at en attente, les timers et les horodatages anacron persistent jusqu'à leur suppression. Anacron ne supprime jamais ses propres horodatages : des fichiers périmés peuvent donc révéler des tâches retirées depuis de /etc/anacrontab. Les timers transitoires sous /run sont perdus au redémarrage. Les preuves d'exécution (lignes CMD, messages de démarrage d'unités) ne durent que ce que permettent la rotation de syslog ou les limites de taille du journal.
Collecte
UAC collecte /etc en entier ainsi que /var/spool/cron, /var/spool/anacron et /var/spool/at via son artefact de planification de tâches ; son artefact systemd ajoute les répertoires d'unités et les timers transitoires. Sur un hôte live, il enregistre aussi systemctl list-timers --all.
# dead box, read-only mount
tar -C /mnt/evidence -czf sched.tgz etc/crontab etc/cron.* etc/anacrontab \
var/spool/cron var/spool/anacron var/spool/at var/lib/systemd/timers 2>/dev/null
# live
systemctl list-timers --all # NEXT, LEFT, LAST, PASSED, UNIT, ACTIVATES
journalctl -D /mnt/evidence/var/log/journal SYSLOG_IDENTIFIER=CRON -o short-iso # CROND on RHEL
L'artefact Velociraptor Linux.Sys.Crontab analyse les crontabs et liste les scripts run-parts.
Analyse
Les crontabs sont du texte : retirez les commentaires et lisez chaque ligne.
grep -HvE '^\s*(#|$)' /mnt/evidence/etc/crontab /mnt/evidence/etc/cron.d/* \
/mnt/evidence/var/spool/cron/crontabs/* /mnt/evidence/var/spool/cron/* 2>/dev/null
tail -n 5 /mnt/evidence/var/spool/cron/atjobs/* /mnt/evidence/var/spool/at/a* 2>/dev/null
grep -hE 'CRON\[|CROND\[|crontab\[' /mnt/evidence/var/log/syslog* /mnt/evidence/var/log/cron*
Pour les timers, lisez chaque .timer et l'unité qu'il active, puis recherchez les messages de démarrage correspondants dans le journal.
Conseils d'investigation
- Triez tous les fichiers de planification par ctime, pas par mtime ;
touchpeut antidater le mtime mais pas le ctime. - Un nouveau script déposé dans
/etc/cron.dailyne nécessite aucune modification de crontab et ne produit que la ligneCMDgénérique derun-parts: examinez le contenu des répertoires, pas seulement les tables. - Les planifications fréquentes (
* * * * *),@reboot,curl/wgetredirigés vers un shell, les blocs base64 et les chemins dans/tmp,/dev/shmou des répertoires cachés sont des indicateurs classiques. Voir /tmp et /dev/shm. - Une modification de crontab sans ligne de journal
crontab[pid]correspondante suggère que le fichier de spool a été écrit directement. - Les comptes de service (
www-data,apache,postgres) ont rarement des crontabs ; l'apparition d'une crontab après la compromission d'un site web est une piste sérieuse. Corrélez avec les journaux du serveur web. - Les timers utilisateur sous
~/.config/systemd/userne s'exécutent que pendant que l'utilisateur est connecté, sauf si le lingering est activé (/var/lib/systemd/linger/<user>). - Reliez chaque tâche à son exécution grâce aux entrées du journal ou de syslog et, si disponibles, aux enregistrements EXECVE d'auditd.