The Filename That Runs: Tar Wildcard Injection to Root
The challenge
A finance box at Calderwell runs a backup every hour: it changes into the upload directory and tars everything in it. The directory is writable by the web user, which is how three files that nobody uploaded ended up in it overnight. Two of them are not reports at all. Read the backup job and the directory, and name the exact file an attacker dropped so that the next backup would run their code as root.
What you'll learn
- Explain how the shell expands a glob into separate arguments before a command sees them
- Recognise that tar cannot tell a filename from an option once the shell has split them
- Identify --checkpoint-action as the tar feature that turns a filename into code execution
- See why a writable directory under a privileged glob is itself the vulnerability
- State the safe alternatives (find -exec, explicit file lists, ./ prefix)
Skills tested
Prerequisites
- Basic shell commands (ls, cat)
- What a glob (*) does
How it works
When a shell sees tar czf out.tgz *, it replaces the * with every filename in the directory and passes each as a separate argument. The command never sees a *; it sees a list. If one of those filenames begins with a dash, the command reads it as an option.
GNU tar has an option, --checkpoint-action=exec=..., that runs a command at intervals. So a file named --checkpoint-action=exec=sh run.sh, sitting in the directory, becomes an instruction to tar to execute run.sh. An attacker who can only write files into the directory the privileged job globs over gets their code run as that job's user.
The same trap applies to any cmd * over attacker-controlled contents: chown, chmod, rsync and others all have option-shaped escapes.
Common mistakes
- Naming
run.sh. That is the payload the planted options call, not the file that hijacks tar. tar only runs it because the option file tells it to. - Naming a CSV. The two reports are the ordinary spool contents and are harmless.
- Expecting to run the backup here. The job runs as root on a schedule; you only need to recognise what the next run will do.
- Looking for a SUID binary or a sudo rule. The escalation is entirely in the glob and the filename, nothing else is misconfigured.
How to defend against it
Never let a privileged command glob over a directory others can write.
- Replace the glob with an explicit, prefixed list:
find /srv/upload -maxdepth 1 -type f -print0 | tar --null -T - -czf ..., so filenames can never be read as options. - Or disarm the dash:
tar czf out.tgz -- *or./*so every operand is clearly a path. - Do not run the backup as root over a web-writable spool. Drop privileges, or copy the spool to a staging area the web user cannot touch and back that up.
Full solution
Community stats
Related Daily Hacks
Credited contributors
These hackers reported issues, improved content, and helped harden this page.