Escape Quotes In Shell.
by b0iler :
b0iler@hotmail.com : last update July 17th
2002
Written
for :
http://b0iler.eyeonsecurity.net/ -
my site full of other cool tutorials
http://blacksun.box.sk/ - a legendary site
full of original tutorials
(perl has built in tcsh, so even users
with no shell are effected)
This one is fairly useful to have. Not the
most used trick, but a good one to know. I started researching this after I
found a post by zen-parse on an exploit for x-chat :
http://online.securityfocus.com/archive/1/76874
What is so cool about
this is the use of $IFS (Internal Field Separators) to add a break
(space,tab,newline) inbetween commands. What the $IFS does is determine what the
shell uses to seperate arguments. If $IFS is a space, then a space can be used
to seperate arguments, if it is 46s03 then 46s03 can be used to seperate
arguments.
This is useful for scripts which filter spaces, or where
spaces are not allowed. zen-parse was forced to use this technique because
spaces are not allowed in urls. (they need to be url encoded into %20). It is
also useful when scripts filter spaces from user input that is printed to the
shell. example (using perl -e so you can test at the command line):
perl -e '
chomp($userinput=<STDIN>);
$userinput =~ s/\s//g;
$userinput =~ s/\n//g;
print `echo "$userinput"|cat`;
'
We are just pretending here, actual circumstances will vary. vary so
much that I will just talk about general situations and let you come up with the
exploits by combining the info.
In this case we can execute commands by
"breaking out" of the quotes with a single ", now we are into normal shell place
(no quotes keeping this an argument of echo). So we can use a metacharacter to
stop this command and issue another. A few avaliable are | ; && but
there are many other characters which we can do tricky things at the shell with.
After the ; we will now put the next command we want executed, for this
demonstration I'll do ls. Then lets clean things up with another ". To go along
with the old one we broke out of. So the final value for $userinput is:
";ls"
And if we need to use a space, we simply put a $IFS in
there:
";ls$IFS/etc/"
There is more than just $IFS. Lets just
cut to the chase here. The shell interprets what is sent, so lets just send some
`cmd`. This will execute the command and return the output right there. try this
for $userinput:
blah`ls`bleh
Simple huh. But many times the
arguments sent to the shell are filtered for the ` character. Luckily there is
the lesser used version of `cmd`, which is $(cmd). This does the same thing, but
gives you different characters which may or maynot be filtered. So if ` is
filtered, and $() is not you can use:
blah$(ls)bleh
What if the
classic meta tag filter from various older cgi security papers is implemented to
escape dangerous characters? What then??
perl -e '
chomp($userinput=<STDIN>);
$userinput =~ s/\s//g;
$userinput =~ s/\n//g;
$userinput =~ s/([;&;t>\*\|`&\$!#\(\)\[\]\{\}:'"])/\\$1/g; #or any regex that forgets to filter \
print `echo "$userinput"|cat`;
'
Now we can do what rfp did, and escape the escape this regex puts in..
or we can look for other methods of exploitation. Infact after reading the man
pages for bash I found that bash also support \nnn encoding, where nnn is the
octal value for the ascii character. This will work perfect to evade these
filters and still print any character. do a man ascii to find out the octal
value of the characters you want. I think this should work for $useriput:
blah\140ls\140bleh
You should have guessed it.. 140 is the octal
representation of ` (which as we know executes the command). So this is the same
thing to bash as: blah`ls`bleh.
The reason why it is not getting
filtered by the s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"])/\\$1/g; is because
the regex is looking for `, \140 is not `, it is just the characters \ 1 4 0 in
a string. But when the shell goes to interpret the string sent, it sees this and
interprets it into `. How nice.
Again, just to make it clear. In perl
the string \140 will get by ` filters, because it is not a `. But once it is
interpreted by the shell into a ` it becomes useable. Perl does have the same
\nnn encoding, but "\140" and '\140' are two different things to perl (all
languages). Remember that "$var" gets interpreted, '$var' does not. user input
does not get interpreted automaticly, it is a string (ie. '\140). Hopefully no
one got too confused. Simple idea once you grasp it.
This same theory
allows things like the string '\n' to get sent to the shell and get interpreted
into a newline. Look for other places where you can use this type of stuff.
One pitfall you may have already thought to this is the inability to
break out of '' in the shell. Since nothing is interpreted inside '$userinput'
on the bash end none of our tricks really work. The only one is to hope the
script does not filter for ' so you can get out and do some magic. Or hope that
you can escape the escape in something like s/([badchars])/\\$1/g;
To
escape you would simply put something like \' in the $userinput of the second
example. This will make the \' sent in to the regex to turn out like \\', thus
escaping the escape the regex tries putting on.
That is pretty much all
the tricks I can share. Other things are common sense or need to be figured out
on a situation to situation basis. I would like to point out that whenever an
external program is called from perl with any form of user input spechial
attention needs to be provided to how that program handles data and any spechial
features that program may have.
For example a root exploit in sperl was
released in aug of 2000 [1] because user suppied data was sent to the /bin/mail
command, which has a feature were if you have ~! on line it will call apon the
shell and issue commands. This is the same principale here, only difference is
we are looking at the shell itself and not a "regular" program. Since the shell
is used so often it is a good target for a discussion.
The same logic
here can also be applied to shell scripts, both local and running as CGI.
[1]http://www.securitybugware.org/mUNIXes/4609.html
[-----]
http://b0iler.eyeonsecurity.net/
Is my homepage, full of good tutorials, code, advisories, and other security
related topics. Come and check out the message board some friends and I
have started, many great disscussions to be had there. http://rawt.daemon.sh/wwwboard/
[-----]