Cron, anacron, at y timers de systemd en Linux
Artefactos de tareas programadas en Linux (crontabs, sellos de anacron, trabajos at, timers de systemd) que revelan persistencia y prueban ejecuciones.
- Ubicación
- /var/spool/cron/
- Prueba
- Qué comandos se programaron, con qué cuenta, y cuándo los lanzó por última vez cron, anacron o un timer
- Marcas de tiempo
- mtime/ctime de los archivos; hora de syslog o del journal para las ejecuciones; sellos de anacron como fecha local YYYYMMDD
- Acceso
- root para todos los directorios de spool; cualquier usuario para su propio crontab con crontab -l
- Retención
- Hasta su borrado; las evidencias de ejecución siguen la rotación de syslog/journal
- Adquisición
- UAC, Velociraptor, cp -a, journalctl
Herramientas
Comparar todas las herramientas- VelociraptorPlataforma · código abierto
- UACCLI · código abierto
- grep / zgrepCLI · incluido en Linux
- systemctlCLI · incluido en Linux
Qué es
Linux tiene cuatro planificadores que se solapan. cron (Vixie cron en Debian y Ubuntu, cronie en la familia RHEL) ejecuta trabajos recurrentes a partir de tablas del sistema y de cada usuario. anacron ejecuta trabajos diarios, semanales y mensuales en máquinas que no están siempre encendidas, y recuerda la fecha de la última ejecución. at (atd) ejecuta trabajos puntuales. Los timers de systemd son unidades .timer que activan un servicio según un calendario o un plazo monotónico, y hoy se encargan de buena parte del mantenimiento que antes hacía cron.
Los cuatro son archivos planos en disco, lo que los hace fáciles de recoger y fáciles de abusar para un intruso (MITRE ATT&CK T1053.003 cron, T1053.002 at, T1053.006 systemd timers).
Dónde se encuentra
| Artefacto | Debian / Ubuntu | RHEL / Fedora / Rocky / Alma |
|---|---|---|
| Tabla del sistema (con campo de usuario) | /etc/crontab | /etc/crontab |
| Tablas del sistema adicionales | /etc/cron.d/* | /etc/cron.d/* (incluye 0hourly) |
| Directorios de scripts de run-parts | /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly | igual |
| Crontabs de usuario (sin campo de usuario) | /var/spool/cron/crontabs/<user> | /var/spool/cron/<user> |
| Configuración de anacron | /etc/anacrontab | /etc/anacrontab |
| Sellos de última ejecución de anacron | /var/spool/anacron/<job-id> | /var/spool/anacron/<job-id> |
| Trabajos at | /var/spool/cron/atjobs/ (más atspool/) | /var/spool/at/ (más .SEQ) |
| Control de acceso | /etc/cron.allow, /etc/cron.deny, /etc/at.allow, /etc/at.deny | igual |
| Unidades timer | *.timer en las rutas de unidades de systemd (ver unidades systemd) | igual |
| Sellos de timers persistentes | /var/lib/systemd/timers/stamp-<name>.timer | igual |
Timers transitorios (systemd-run --on-*) | /run/systemd/transient/, /run/user/<uid>/systemd/transient/ | igual |
| Log de ejecución | Líneas CRON[pid] en /var/log/syslog o en el journal | /var/log/cron o el journal |
En RHEL, /etc/cron.d/0hourly ejecuta /etc/cron.hourly, y un script de ese directorio lanza anacron, que a su vez se ocupa de los directorios diario, semanal y mensual. En Debian, /etc/crontab llama a run-parts para esos directorios salvo que anacron esté instalado.
Qué prueba
- Persistencia programada: qué comando está configurado para ejecutarse, con qué frecuencia y (en las tablas del sistema) con qué usuario. Los crontabs de usuario se ejecutan como el propietario del archivo.
- Ejecución: una línea de log
CMDprueba que cron lanzó el comando en ese minuto. No prueba que el comando tuviera éxito. - Última ejecución periódica: un sello de anacron registra la última fecha en que se ejecutó un trabajo; el mtime del sello de un timer registra el último disparo de un timer
Persistent=true. - Quién editó un crontab: las líneas
crontab[pid]: (user) BEGIN EDIT / REPLACE / END EDITdel log. - Lo que no prueba: la mera presencia de un archivo de trabajo no demuestra que llegara a ejecutarse (el demonio puede estar desactivado o el archivo ignorado; el cron de Debian omite los nombres de
/etc/cron.dque contienen un punto).
Campos clave
| Elemento | Significado |
|---|---|
m h dom mon dow | Los cinco campos de programación de cada línea de crontab |
| campo de usuario | Sexto campo, solo en /etc/crontab y /etc/cron.d/* |
@reboot, @hourly, @daily ... | Programaciones abreviadas; @reboot es una de las favoritas para la persistencia |
MAILTO, SHELL, PATH, CRON_TZ | Líneas de entorno dentro de un crontab; CRON_TZ (cronie) cambia la zona horaria de la programación |
anacrontab period delay job-identifier command | Días entre ejecuciones, retardo en minutos, nombre del archivo de sello, comando |
START_HOURS_RANGE, RANDOM_DELAY | Ventana de ejecución y variación aleatoria de anacron |
| archivo de trabajo at | Script de shell: entorno capturado, cd al directorio de trabajo original y el comando al final |
.timer OnCalendar=, OnBootSec=, OnActiveSec=, OnUnitActiveSec= | Disparador de calendario o monotónico |
.timer Unit=, Persistent= | Unidad activada (por defecto, el .service con el mismo nombre base); recuperación tras un periodo apagado |
Marcas de tiempo
- Los crontabs y los archivos de trabajo solo tienen las marcas de tiempo del sistema de archivos. Como
crontabreescribe el archivo de spool, su mtime es la hora de la última instalación. En Debian, un archivo instalado concrontabempieza con una cabeceraDO NOT EDIT THIS FILEque indica el archivo temporal y la fecha de instalación; un archivo de spool sin esa cabecera probablemente se escribió directamente. - Los sellos de anacron contienen la fecha de la última ejecución como
YYYYMMDD(sin hora), en hora local. - Los archivos de sello de los timers están vacíos; la información es el mtime del archivo.
- Las líneas de log siguen el formato syslog (ver syslog y auth.log); las entradas del journal guardan microsegundos desde la época 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
Retención
Los crontabs, los trabajos at pendientes, los timers y los sellos de anacron persisten hasta que se borran. Anacron nunca borra sus propios sellos, así que los sellos obsoletos pueden revelar trabajos que después se eliminaron de /etc/anacrontab. Los timers transitorios bajo /run se pierden al reiniciar. Las evidencias de ejecución (líneas CMD, mensajes de arranque de unidades) duran solo lo que permitan la rotación de syslog o los límites de tamaño del journal.
Adquisición
UAC recoge /etc completo y /var/spool/cron, /var/spool/anacron y /var/spool/at mediante su artefacto de planificadores de tareas; su artefacto de systemd añade los directorios de unidades y los timers transitorios. En un host en vivo también guarda 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
El artefacto Linux.Sys.Crontab de Velociraptor analiza los crontabs y enumera los scripts de run-parts.
Análisis
Los crontabs son texto: elimine los comentarios y lea cada línea.
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*
Para los timers, lea cada .timer y la unidad que activa, y después busque en el journal los mensajes de arranque correspondientes.
Consejos para la investigación
- Ordene todos los archivos de planificación por ctime, no por mtime;
touchpuede retrasar el mtime, pero no el ctime. - Un script nuevo depositado en
/etc/cron.dailyno requiere editar ningún crontab y solo genera la líneaCMDgenérica derun-parts, así que revise el contenido de los directorios, no solo las tablas. - Las programaciones muy frecuentes (
* * * * *),@reboot,curl/wgetredirigidos a una shell, bloques en base64 y rutas en/tmp,/dev/shmo directorios ocultos son indicadores clásicos. Ver /tmp y /dev/shm. - Una edición de crontab sin la línea de log
crontab[pid]correspondiente sugiere que el archivo de spool se escribió directamente. - Las cuentas de servicio (
www-data,apache,postgres) rara vez tienen crontab; si aparece uno tras el compromiso de un servidor web, es una pista sólida. Correlacione con los logs del servidor web. - Los timers de usuario en
~/.config/systemd/usersolo se ejecutan mientras el usuario tiene sesión iniciada, salvo que esté activado el lingering (/var/lib/systemd/linger/<user>). - Vincule cada trabajo con su ejecución mediante las entradas del journal o de syslog y, cuando existan, los registros EXECVE de auditd.