Tools · Linux command line for security · 24 / 28
How to list every cron job on a Linux system and spot malicious ones
Find system and user crontabs, cron.d drop-ins, anacron, and at jobs, and recognize the patterns attackers use for persistence.
All the places cron hides
System-wide jobs live in /etc/crontab, files in /etc/cron.d/, and scripts in /etc/cron.hourly, daily, weekly, and monthly. Each user can have a personal crontab stored under /var/spool/cron/crontabs (Debian) or /var/spool/cron (RHEL), edited with crontab -e and listed with crontab -l -u user. One-off jobs from at live in /var/spool/cron/atjobs or similar, listed with atq.
An audit that only checks root’s crontab misses most of these.
sudo cat /etc/crontab; sudo ls -la /etc/cron.d /etc/cron.*ly for u in $(cut -d: -f1 /etc/passwd); do sudo crontab -l -u "$u" 2>/dev/null | sed "s/^/$u: /"; done sudo atq
Patterns that should worry you
Jobs that download and execute, such as curl or wget piped to sh, are a classic sign. So are jobs running every minute from /tmp or /dev/shm, base64-decoded commands, reverse connections to external addresses, and jobs owned by service accounts like www-data that should not schedule anything.
Also check timestamps. A file in /etc/cron.d created at the same time as a suspicious login is a strong lead.
Lab: plant a harmless persistence job
As a lab user, add a crontab line that runs a script from /tmp every minute and appends the date to a file. Then search for it from root using the loop above, and also find cron.d files changed recently with find -mmin. Check the journal for the cron daemon’s execution lines.
Remove the job with crontab -r -u user. In a real case, preserve the crontab and the script first.
echo '* * * * * /tmp/.u.sh >> /tmp/.u.log 2>&1' | crontab - sudo find /etc/cron* /var/spool/cron -type f -mmin -60 -ls journalctl -u cron --since "10 min ago" | tail crontab -r
Defensive controls
/etc/cron.allow restricts which users can create crontabs. Include only accounts that need it. Watch cron directories with auditd or a file integrity tool so new jobs generate an event.
systemd timers are cron’s modern counterpart and need the same audit, covered in the next tutorial.
Diagram
Where scheduled jobs live
Check every location, not just root’s crontab.
- /etc/crontab and /etc/cron.d/
System jobs with a user field.
- /etc/cron.{hourly,daily,...}
Scripts run by run-parts.
- /var/spool/cron/
Per-user crontabs.
- at queue
One-time jobs listed by atq.
- systemd timers
The modern equivalent.
Check yourself
1. Where are per-user crontabs stored on Debian?
2. Which crontab entry is most suspicious?
3. Which file limits who may create crontabs?