Exploiting Wildcards On Linux/Unix
An anonymous reader writes: DefenseCode researcher Leon Juranic found security issues related to using wildcards in Unix commands. The topic has been talked about in the past on the Full Disclosure mailing list, where some people saw this more as a feature than as a bug. There are clearly a number of potential security issues surrounding this, so Mr. Juranic provided five actual exploitation examples that stress the risks accompanying the practice of using the * wildcard with Linux/Unix commands. The issue can be manifested by using specific options in chown, tar, rsync etc. By using specially crafted filenames, an attacker can inject arbitrary arguments to shell commands run by other users — root as well.
Who does NOT use -- in their scripts, if they're safety conscious?
rm -i -- *
Problem solved?
Normal programs should stop processing options after a (standalone) "--" and take everything following it as regular parameters. getopt and similar libraries handle this automatically.
I really wouldn't class the "use of wildcards" as a security risk - the security risk is the developer that doesn't know what he's doing. /" as root immediately afterwards?
Would command line handling be a security risk, if someone would add a --superuser-rm option to his code and execute "rm -rf
posting the answer to this useless story that was posted to FD
Date: Thu, 26 Jun 2014 12:55:42 -0700
From: Michal Zalewski
> We wanted to inform all major *nix distributions via our responsible
> disclosure policy about this problem before posting it
I'm not sure how to put it mildly, but I think you might have been
scooped on this some 1-2 decades ago...
Off the top of my head, there's a rant about this behavior in "The
Unix-Haters Handbook", and there are several highly detailed articles
by David Wheeler published over the years (e.g.,
http://www.dwheeler.com/essays/filenames-in-shell.html).
Yup, it's a counterintuitive behavior that leads to security problems. /mz
The odds of changing the semantics at this point are very slim. Other
operating systems have their own idiosyncrasies in this area - for
example, Windows it not a lot better with parameter splitting and
special filenames.
If it were a Microsoft Issue, this would be so a bug and not a feature.
Linux/Unix are an old design of an OS. There are some designs in its main way of doing things that do not work in today's much more secure environment.
Things have been upgraded Telnet replaced with SSH, hacks on FTP to make it more secure. But the underpinning is still there. Back in the day where computers needed to do things.
If something is so important that you feel the need to post it on the internet... It probably isn't that important.
drop tables *
After years of using command line programs daily I never heard of -- before today. It was never brought up in school, nor did I see any specific thread / blog post on the subject. So to answer your question, I don't. I've never heard about that before. Where did you learn about that ?
So why would the expected method not be the default? This is exactly how security problems are born.
While the paper is an interesting writeup, there's nothing really new in there. A colleague used to exploit the same issue "for good," by touching a file named "-i" in directories he deemed important. Obviously, one could undo that by touching a file named "--". For users, I'd usually recommend always using ./* instead of just *, as well as directory/. instead of just directory
The root issue boils down to user supplied input not being checked.
Is the wildcard expanded by the shell in PowerShell?
Really, this is well-known, non-surprising and will not happen to anybody with a security mind-set. Of course it will happen in practice. But there are quite a few other variants of code injection (which this basically is) that the same people will get wrong. Complete input sanitisation is mandatory if you need security. I mean, even very early Perl-based CGI mechanisms added taint-checking specifically for things like this. If people cannot be bothered to find out how to pass parameters from an untrusted source securely, then they cannot be bothered to write secure software.
The fix is not to change the commands. The fix is to exchange people that mess things this elementary up against people that actually understand security. Sorry, you cannot have developers that are cheap and competent at the same time and even less so when security is important.
Most ACs are not even worth the keystrokes to insult them. Be generically insulted by this and ignored otherwise.
I remember reading about this in the 1991 release of "Practical Internet and Unix Security," from O'Reilly back in 1991. I'm pretty sure they even gave examples. They also laid out a number of suggestions to mitigate risk, including not specifying the current path, ".", in the root user's path so they must explicitly type the location of an executable script, and so on.
They also pointed out that some well-behaved shells eliminate certain ease-of-use-but-exploitable features when it detects that a privileged user is running it, and even on systems where that's not the standard, the default .bashrc or equivalent files often set up aliases for common commands that disable features like wildcard matching, or color codes (which could be used if you're very tricky, to match a filename color to the background color of the screen, among other things), the path restriction listed above, and many many others.
It's really hard to secure shell accounts on systems, no matter how you try. Is this article just proof that the current generation of unix admins is rediscovering this? Should I be shaking my fist and telling the kids to get off my lawn? This was old news 2 over decades ago.
Why are you using wildcards in a script processing publicly-accessible directories in the first place?
I never do what you suggest.
I have never written a script that needed "rm -i" for one thing.
But even ignoring that, I never remove "*" in a script. If I have a bunch of temporary files, I will create a temporary directory (TMP="/dev/shm/tmp_delete_me.$$.${RANDOM}") and put them in there. I then "rm -rf $TMP" (the temporary directory).
I have needed to use wildcards with some files before, but I usually do have more than just a "*" in there. For example, "rm -f *.stub" is more common.
The article reveals a deep lack of thought. It might just as well have been headlined, "exploiting command lines". I mean, for goodness sake, this is a deliberate and oft-needed, oft-used feature. If you can't handle it then stop using computers because you lack the necessary skills.
-- david newall
Also, normal programs should stop processing options after encountering the first non-option argument. GNU tools often seem to stray from this convention for whatever reason, probably in order to stay compatible with some flavors of UNIX.
Typical Linux user reaction: "you're holding it wrong!"
At least Microsoft takes these things seriously.
I understand why this works and I understand the need to sanitize user input, but this is dumb. Even if there are workarounds. It's obvious what the intent of "tar cf archive.tar *" is suppose to be, it shouldn't be treating file names as additional arguments. Anyone actively using this "feature" for anything legitimate is dumb too.
This seems very similar to the whole "we need some other language than C" argument. Sure, you *can* make secure code with zero overflow vulnerabilities, but damn near all software has them. You can only blame the user/coder for so long for doing something "wrong", but when 90%+ people are doing it "wrong" then you probably need to change how the thing works.
This is not an exploit, it's basic stuff any first year sysadmin should know. You know... quoting, ./, --, -i, -inum, IFS, etc. The author's stupid Linux 'ls' doesn't even order lexicographically correct. And dashes at the end of filename arguments are not interpreted as dashopts, that's not even posix.
If you want to learn unix and blog your newfound knowledge, great... just don't try to call it an exploit or secadv, you'll just make yourself look stupid.
Systems where user data can accidentally get mixed in control commands are dangerous. In addition to this shell trick, another example would be HTML, where you have to be careful to not let raw HTML data through your guestbook messages so that visitors can't inject HTML into the messages.
With competent and careful system administrators you can avoid problems, but it's still kind of a fragile design in my opinion.
WILDCARD Bitches! Yeeeeeeehaw!!
.
Wake up. Not everyone is a developer. Not everyone has even 2 minutes of unix philosophy.
My Users are scientists, and they get to trash their home space here. These types of issues are most likely to happen when they are writing a script and it makes files for what should have been options.
My job isn't to teach them unix, it's to keep them happy and productive. They make mistakes, I clean them up and help them through the frustration of things going wrong.
This would seem a problem with universal implications, and one that largely depends on local access by the malefactor.
Er.. most of the exploits are only possible if one is root and/or the directory is writable for some other user (e.g. leon in this case).
Since one is root, one can do anything anyway so why bother with all this misdirection? If someone leaves world writable directories lying around (especially without the sticky bit set), then they deserve everything they get. Or is this some kind of "trap the (completely) unwary sysadmin" wake up call? If I see some strange named file (especially if I know I didn't put it there) I would investigate very, very carefully what is going on. I can't be alone in this - surely?
While that is indeed the solution, it is also true that it is too easy to forget. Perhaps one could modify all commands to require the use of the "--" separator, or to warn if it's not present, at least if some environment variable is set. That could be very helpful for people trying to write more secure code.
"the security risk is the developer that doesn't know what he's doing."
Not the hacker who does know what he is doing.
Unpacking 'shar' archives via 'sh' considered dangerous.
This is because the linux commands do not respect what the manual says:
man rm...
rm [OPTION]... FILE...
but in realitiy it's rather:
rm [OTION|FILE]...
whereas on other unix systems it works as expected, first the options, then the arguments
HP-UX
rm *
rm: DIR1 directory
Solaris
rm *
rm: DIR1 directory
So screw the GNU tools, they mess things up for the "old unix sysadmins"
Here is a nice linux/unix trap:
x=a
y="rm z"
f=$x $y
So you expect f to contain: a rm z
not really...
z: No such file or directory
so the rm actually was executed
a=$x is an environment variable attribution, so $y becomes an executed command...
And that one works on any unix/linux
Recently patched in chkrootkit (CVE-2014-0476)
Atari rules... ermm... ruled.
Nop, you can not just use --. because many commands do not understand --
Here is an article by dwheeler (a frequent slashdotter; often cited for his technique countering the trusting trust problem) about filenames.
http://www.dwheeler.com/essays...
I believe he is mostly right. We should move to file systems that do not allow "stupid" names and be done with it.
This doesn't solve the problem completely, but handles most cases of abuse. Remember, in Unix you can have a pipe in a filename. So the wildcard could activate a pipe to a script that ignores your initial input and executes nasty things.
After years of using command line programs daily I never heard of -- before today. It was never brought up in school, nor did I see any specific thread / blog post on the subject. So to answer your question, I don't. I've never heard about that before. Where did you learn about that ?
RFM
Anything can be put in a context such that it's not a security risk. For example, Heartbleed isn't a security risk unless you expose it to untrustworthy people.
But that's just it -- developers aren't trustworthy in this scenario. I cut my teeth on Unix decades ago and I didn't know of the "--" feature. And even then, not everything uses getopt. If I can't figure out how to use a feature securely, directly or through software others have created, then for me it's insecure. And it sounds like for most people who use wildcards it's insecure, too.
...so wouldn't it be more accurate to to say that computers, like bull-dozers, can be dangerous in the hands of malicious, ill-informed, inattentive, or incompetent users? If you know of any of these archetypes, try to make them smarter, but don't allow them root privileges to anything taller than an ankle-high weed. Give them some locked-down version of Windows, without admin privileges, lots of monitoring tools and features. Consider helmets, knee-pads and child safety locks.
At least Microsoft takes these things seriously.
Was this supposed to be a joke, FUD, or BS ?
Who's the writer? Some "security" guy that recently got a shell somewhere?
Any Unix admin professional is already familiar with this.
It's a pain? Not for me. Practicality hugely overcomes danger IMHO, but it's impossible to change right now.
Is a basic feature of how unix shells work, and there's no way to change it. Is like complaining about the rain.
Maybe someone invents something new and makes it popular.... Good luck with that.
Let me check my dictionary for the defintion of idiot:
1. n: A user, especially super user, who uses * as an agument without first checking to see what * expands into.
2. n: A user who leaves his directories world writeable so others can put random garbage in them.
The one line summary for this story is bad things happen to people who use a command without knowing what the command does.
Don Dugger
"Censeo Toto nos in Kansa esse decisse." - D. Gale
First they came for our Shell.
Then they came for our Emacs.
Now they have come for our *.
No, I shall stand! They will not take our noble asterisk.
Is this REALLY an important issue? Are quick and dirty shell scripts really a security risk? Who runs them other than the person who wrote them or other sysadmins?
Anything sophisticated enough for someone to put into production is probably written in Perl or something to give it a better user interface. In decades, I have never used wildcards in Perl for any kind of file processing. I get lists of files form the system, but if you can't trust the system's directory listing facility, then you're already hosed.
I'm encouraged that this is the only thing security researchers can come up with. Linux must be really secure now.
I remember reading about this in the 1991 release of "Practical Internet and Unix Security," from O'Reilly back in 1991. I'm pretty sure they even gave examples. They also laid out a number of suggestions to mitigate risk, including not specifying the current path, ".", in the root user's path so they must explicitly type the location of an executable script, and so on.
They also pointed out that some well-behaved shells eliminate certain ease-of-use-but-exploitable features when it detects that a privileged user is running it, and even on systems where that's not the standard, the default .bashrc or equivalent files often set up aliases for common commands that disable features like wildcard matching, or color codes (which could be used if you're very tricky, to match a filename color to the background color of the screen, among other things), the path restriction listed above, and many many others.
It's really hard to secure shell accounts on systems, no matter how you try. Is this article just proof that the current generation of unix admins is rediscovering this? Should I be shaking my fist and telling the kids to get off my lawn? This was old news 2 over decades ago.
Probably because anybody who's used the various Bourne-style shells for a while
considers it a feature, not a bug. This is a case where the Principle of Least
Surprise comes up with different answers for novice users and for experts:
"What? A * can expand into an unintended command argument?" "Yeah, what *else*
would it do - the shell is just globbing, it doesn't know for sure what the
command will do with the parameter".
Who asked for this feature? Can anyone give me a legitimate use case for "tar cf archive.tar *" evaluating as
tar cf archive.tar admin.php ado.php --checkpoint=1 "--checkpoint-action=exec=sh shell.sh"
instead of
tar cf archive.tar "./admin.php" "./ado.php" "./--checkpoint=1" "./--checkpoint-action=exec=sh shell.sh"
Jesus Christ, get off yourself already.
Back in '83, a friend challenged me to remove a file name "-rf *, without causing collateral damage.
General Relativity: Space-time tells matter where to go; Matter tells space-time what shape to be.
Article should be called 'Exploiting wildcards on GNU'.
All of the examples in the original document work because GNU software can intersperse options and filenames freely. None of those exploits would work in BSD userland, for example.
Knowledge is power; knowledge shared is power lost.
If computers were conceived to execute user commands, then why is a command for matching file and dictionary names returning them in such a form that they become executable parameters, when they could easily be explicit filenames by adding ./ at the beginning?
Is making what should be basic and safe housekeeping functions like chmod * and tar * dangerous really something you actually want in Linux?
News for nerds, stuff that mattered two decades ago.
>My Users are scientists, and they get to trash their home space here. These types of issues are most likely to happen when *they are writing a script* and it makes files for what should have been options.
>*My job isn't to teach them unix*, it's to keep them happy and productive. They make mistakes, I clean them up and help them through the frustration of things going wrong.
Hi! I want to program computer thing but dont u dare try toi tgech me how i shot unix
Because a lot of options take a filename as an argument, such as the "-o" option of any compiler or linker. How do you pass one of those without it getting expanded as a wildcard?
The real bug here is the same as in SQL injection attacks: A failure to safely distinguish between program and data!
I.e. when doing chown usr:grp *.php, the wildcard globbing should escape any special letters, particularly including white space and wild card characters.
This is the same idea as when you use prepare(... ?,?) on any sql statement with replaceable parameters, then execute() with the relevant dynamic values.
Terje
"almost all programming can be viewed as an exercise in caching"
Because, since the mainframe days, a new and unforeseen computer/user pairing had evolved. For emphasis, I'll say it again, evolved; never designed from the ground up. Smaller cheaper, but nonetheless ever more powerful, computers became available to a class of consumers spanning the general population, now networked to many other such computer/user pairs. These general-population consumers find themselves operating systems far beyond their ability (or time, inclination, etc.) to understand and safely control except as mediated by a deceptively enabling and presumed (to the user) protective interfaces. The problem is that computers are mechanisms designed to automate and execute instructions. That's what they are; and, networks are necessarily designed to facilitate communication. That's what they do. Yet, underlying system architectures and interfaces, though enabling, never evolved commensurately to the task of satisfactory trade-offs between function and security for ubiquitous employment in a general population. I have no idea what the solution is, but I suspect that we need to do some fundamental rethinking of secure architectures and user interfaces. Architectures need to more safely isolate data and logical functionality, and interfaces need to more safely mediate users interaction with devices. I confidently assert that the current architectures simply can't be secured, no matter how much junk is kludged to the task. Prove me wrong, please.
And so you found the proper inode and removed it that way?
As may times DOS/Windows has been burned by bad design (Explorer hiding extension yet action dependent on extension being a big one) the lack of functionality helps it here. The * is not interpreted by the shell, but by the app. It sees a *, and does a library call to do the glob. So there's no chance of it being interpreted as a flag. My guess is that DOS was so restricted in memory, that executing a glob may have blown the stack, much like we use xargs on UNIX when a fileglob is too much.
Great suggestion, and much better than the one in the discussion thread linked from the summary about refusing to expand names starting with -. I don't think your suggestion would break anything, and it would eliminate the problem. It should be the default.
After years of using command line programs daily I never heard of -- before today. It was never brought up in school, nor did I see any specific thread / blog post on the subject. So to answer your question, I don't. I've never heard about that before. Where did you learn about that ?
man bash:
"-- A -- signals the end of options and disables further option processing. Any arguments after the -- are treated as filenames and arguments."
use ./* instead of * always
all problems solved forever
I'm glad that people are learning about this problem. Sadly, it's not new, it's been known for decades. CERT’s “Secure Coding” item MSC09-C (Character Encoding — Use Subset of ASCII for Safety) specifically discusses the vulnerabilities due to filenames. The Common Weakness Enumeration (CWE) includes 3 weaknesses related to filenames (CWE 78, CWE 73, and CWE 116), all of which are in the 2009 CWE/SANS Top 25 Most Dangerous Programming Errors. My freely-available book on writing secure software has a whole section about filenames. And so on.
We need to fix the problems with Unix/Linux filenames, not just keep rediscovering them. In particular, ensuring that filenames had no control characters, no leading dashes, and used UTF-8 encoding would simplify developing correct programs. Most people writing software already follow these rules. We don't need to make it easy for attackers.
- David A. Wheeler (see my Secure Programming HOWTO)
The -- end of options option is a GNU getopt extension. It is, if memory serves me correctly, not part of any standard. This means that program that were not compiled with glibc, or programs that do not use getopt/getopt_long, may or may not honor it.
Even by simply looking at the man page, it is easy to spot programs that don't use getopt. Any program that accept multi-letter options with one minus sign is, obviously, not using getopt (e.g. gcc, find).
Then there is git. Git uses -- to mean "no revisions after this point. Any remaining argument must be a file name". This is almost, but not quite, what -- means for getopt. I don't even know what underlying parsing engine they are using (could be getopt with the "no options after first argument" option set).
The "./*" feature is a more global workaround, if it is applicable.
Shachar
And not everybody has any business writing security-critical code. You are asking for the illiterate to be allowed and encouraged to write poetry. That cannot ever work.
Most ACs are not even worth the keystrokes to insult them. Be generically insulted by this and ignored otherwise.
Aces are high, deuces are wild and the sky is the limit.
Place your bets.
You have noting to contribute but could not keep your mouth shut?
Most ACs are not even worth the keystrokes to insult them. Be generically insulted by this and ignored otherwise.
Yeah, by not giving people a commandline worth anything in the first place. But you are right: MS realizes their customers are incompetent, immature whiners that would blame MS is they used MS products to shoot themselves in the foot. So the function to shoot anything was removed.
Most ACs are not even worth the keystrokes to insult them. Be generically insulted by this and ignored otherwise.
I have no idea what the solution is, but I suspect that we need to do some fundamental rethinking of secure architectures and user interfaces. Architectures need to more safely isolate data and logical functionality, and interfaces need to more safely mediate users interaction with devices. I confidently assert that the current architectures simply can't be secured, no matter how much junk is kludged to the task. Prove me wrong, please.
On the other hand this specific issue could be easily solved by * prefixing all filenames with ./
So far I've not heard of anything that would break, and it's silly arguing that this specific problem is part of required functionality and not something that can/should be fixed when it appears to have such a simple solution.
Yes, there is a workaround you can use, if you know about it and remember it every time, to enable the safe behaviour. That does *not* count as 'problem solved'. To solve the problem, the safe behaviour needs to be the default, with the funky and unsafe behaviour of treating filenames as extra switches being the one you have to enable specially. Really - what are the odds that the user or programmer *intends* for a file called --foo to be treated as an option specifier when they expand a wildcard? Conceptually the fix is not hard. Each element in argv gets an associated flag saying whether it is a filename - and if it is marked as a filename, getopt() or whatever does not treat it as an option specifier even if it begins with the - character. Alternatively, filenames beginning - could simply be disallowed.
-- Ed Avis ed@membled.com
you are not precise on one point
In unix world, this long known issue was only about the first filename. Typically with classig usage of tar, the first file is your archive, and all others are just filenames. unix/bsd treat them as filenames.
Now comes GNU getopt and "suddenly" decides that from now on it would be cool to have options anywhere on the command line. Result is that in GNU-world, tar is now vulnerable (and many many other commands) which had had no issue at all previously.
I would really like that getopt changes back to "if we see filenames, then consider being after --" or rather: stop parsing options if you find a parameter which does not match any option. That's the last one. Just stop there, do not continue. Leave the rest as it is.
Atari rules... ermm... ruled.