Anything that modifies the operation of some utility can be used to attack. The next section is about environment variables, here we look at option flags.
A typical program invocation looks like
foo -l -s file1 file2 .... Interesting things
happen when files have names starting with a dash.
Some totally misguided people like to have all files
in their home directory, and add a file
as a protection against
rm *. Yecch.
Some Unix-type systems supported setuid shell scripts.
If the script starts with
#! /bin/sh and is called
foo, the result of the invocation
was equivalent to that of
/bin/sh foo args, so that
the shell would execute the commands in the script
args. But now, what if you call the script
-c (maybe by making a link or a symlink)? The command
/bin/sh -c args is executed. The shell will do
the commands given in
args and does not look at the
script at all. This was the end of the suid shell scripts.
In 1994 it was discovered that on all AIX and all Linux systems
login -froot would give an immediate root shell
rlogin host -l -froot a remote root).
Indeed, on a trusted network, the
server would do
login -p -h -f user in case
had already been authenticated by the client, and
login -p -h user otherwise. Thus, the
means: no further authentication required. But, the option parser
login was willing to parse
(And old bugs never die: in 2007 Solaris was found to have precisely
the same vulnerability when login was invoked via telnet.)
In 2004 it was noticed that opening a
where the hostname starts with a dash causes the hostname
to be interpreted as
telnet option. Several browsers
have such flaws. For example, Opera on Windows when given
telnet://-ffilename will overwrite the file
(in the Opera directory) with the connection log, and Opera on Linux
telnet://-nfilename will overwrite
in the user's home directory.
On a GNU system one can prevent most of such misinterpretations
by using a
-- separator between options and filenames.
Unix scripts are very bad at handling filenames with embedded spaces. This is just laziness of the authors - it has always been true that a filename could contain arbitrary bytes except for NUL and slash.
cron scripts contain stuff like
find / -type f -name core +mtime 7 -print | xargs rm
to remove old core files, or old temporary files in
or so. Let us try.
% cd /tmp % mkdir -p " /etc/passwd " % touch " /etc/passwd "/core % find . -type f -name core -print | xargs rm rm: cannot remove `./': Is a directory rm: cannot remove `/etc/passwd': Permission denied rm: cannot remove `/core': No such file or directoryOK, so if this command is run by root we can delete arbitrary files by using filenames that end in a space (or are just a single space).
A more careful script would have
find . -type f -name core -print0 | xargs -0 rm.