4P3X/attacks
0
1import asyncio2import uuid3import random4from datetime import datetime5from typing import Optional6from fastapi import FastAPI, BackgroundTasks, HTTPException7from fastapi.responses import HTMLResponse8from fastapi.middleware.cors import CORSMiddleware9from pydantic import BaseModel10import aiohttp11 12app = FastAPI(title="Concurrent Request Runner")13 14app.add_middleware(15 CORSMiddleware,16 allow_origins=["*"],17 allow_methods=["*"],18 allow_headers=["*"],19)20 21# ── In-memory job store ──────────────────────────────────────────────────────22JOBS: dict[str, dict] = {}23 24USER_AGENTS = [25 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",26 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",27 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",28 "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)",29 "Mozilla/5.0 (iPad; CPU OS 14_0 like Mac OS X)",30]31FAKE_IPS = [f"192.168.{random.randint(0,255)}.{i}" for i in range(2, 100)]32 33 34# ── Schemas ──────────────────────────────────────────────────────────────────35class JobRequest(BaseModel):36 url: str37 num_requests: int = 8038 concurrency: int = 2039 40 41# ── Background worker ────────────────────────────────────────────────────────42async def run_job(job_id: str, url: str, num_requests: int, concurrency: int):43 job = JOBS[job_id]44 job["status"] = "running"45 job["started_at"] = datetime.utcnow().isoformat()46 47 sem = asyncio.Semaphore(concurrency)48 results = {"200": 0, "error": 0, "other": 0}49 50 async def make_request(session: aiohttp.ClientSession, idx: int):51 if job["status"] == "cancelled":52 return53 async with sem:54 ip = random.choice(FAKE_IPS)55 ua = random.choice(USER_AGENTS)56 headers = {57 "User-Agent": ua,58 "X-Forwarded-For": ip,59 "X-Real-IP": ip,60 }61 entry = {62 "idx": idx,63 "ip": ip,64 "ua": ua[:40],65 "status": None,66 "error": None,67 "ts": datetime.utcnow().isoformat(),68 }69 try:70 async with session.get(71 url, headers=headers, timeout=aiohttp.ClientTimeout(total=10)72 ) as resp:73 entry["status"] = resp.status74 if resp.status == 200:75 results["200"] += 176 else:77 results["other"] += 178 except Exception as e:79 entry["error"] = str(e)[:80]80 results["error"] += 181 finally:82 job["logs"].append(entry)83 job["done"] += 184 job["results"] = dict(results)85 86 async with aiohttp.ClientSession() as session:87 tasks = [make_request(session, i) for i in range(num_requests)]88 await asyncio.gather(*tasks)89 90 if job["status"] != "cancelled":91 job["status"] = "done"92 job["finished_at"] = datetime.utcnow().isoformat()93 94 95# ── API endpoints ────────────────────────────────────────────────────────────96@app.post("/jobs")97async def create_job(req: JobRequest):98 job_id = str(uuid.uuid4())[:8]99 JOBS[job_id] = {100 "id": job_id,101 "url": req.url,102 "num_requests": req.num_requests,103 "concurrency": req.concurrency,104 "status": "pending",105 "done": 0,106 "results": {"200": 0, "error": 0, "other": 0},107 "logs": [],108 "created_at": datetime.utcnow().isoformat(),109 "started_at": None,110 "finished_at": None,111 }112 # Fire-and-forget: survives page navigation113 asyncio.create_task(run_job(job_id, req.url, req.num_requests, req.concurrency))114 return {"job_id": job_id}115 116 117@app.get("/jobs")118async def list_jobs():119 return list(JOBS.values())120 121 122@app.get("/jobs/{job_id}")123async def get_job(job_id: str):124 job = JOBS.get(job_id)125 if not job:126 raise HTTPException(404, "Job not found")127 return job128 129 130@app.delete("/jobs/{job_id}")131async def cancel_job(job_id: str):132 job = JOBS.get(job_id)133 if not job:134 raise HTTPException(404, "Job not found")135 job["status"] = "cancelled"136 return {"cancelled": True}137 138 139# ── Dashboard UI ─────────────────────────────────────────────────────────────140@app.get("/", response_class=HTMLResponse)141async def dashboard():142 with open("dashboard.html") as f:143 return f.read()