""" Endpoints pour l'analyse des attaques par force brute sur les formulaires """ from fastapi import APIRouter, HTTPException, Query from ..database import db router = APIRouter(prefix="/api/bruteforce", tags=["bruteforce"]) @router.get("/targets") async def get_bruteforce_targets(): """Liste des hôtes ciblés par brute-force, triés par total_hits DESC.""" try: sql = """ SELECT host, uniq(src_ip) AS unique_ips, sum(hits) AS total_hits, sum(query_params_count) AS total_params, groupArray(3)(ja4) AS top_ja4s FROM mabase_prod.view_form_bruteforce_detected GROUP BY host ORDER BY total_hits DESC """ result = db.query(sql) items = [] for row in result.result_rows: host = str(row[0]) unique_ips = int(row[1]) total_hits = int(row[2]) total_params= int(row[3]) top_ja4s = [str(j) for j in (row[4] or [])] attack_type = ( "credential_stuffing" if total_hits > 0 and total_params / total_hits > 0.5 else "enumeration" ) items.append({ "host": host, "unique_ips": unique_ips, "total_hits": total_hits, "total_params":total_params, "attack_type": attack_type, "top_ja4s": top_ja4s, }) return {"items": items, "total": len(items)} except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/attackers") async def get_bruteforce_attackers(limit: int = Query(50, ge=1, le=500)): """Top IPs attaquantes triées par total_hits DESC.""" try: sql = """ SELECT src_ip AS ip, uniq(host) AS distinct_hosts, sum(hits) AS total_hits, sum(query_params_count) AS total_params, argMax(ja4, hits) AS ja4 FROM mabase_prod.view_form_bruteforce_detected GROUP BY src_ip ORDER BY total_hits DESC LIMIT %(limit)s """ result = db.query(sql, {"limit": limit}) items = [] for row in result.result_rows: items.append({ "ip": str(row[0]), "distinct_hosts":int(row[1]), "total_hits": int(row[2]), "total_params": int(row[3]), "ja4": str(row[4]), }) return {"items": items, "total": len(items)} except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/timeline") async def get_bruteforce_timeline(): """Hits par heure (dernières 72h) depuis agg_host_ip_ja4_1h.""" try: sql = """ SELECT toHour(window_start) AS hour, sum(hits) AS hits, uniq(replaceRegexpAll(toString(src_ip), '^::ffff:', '')) AS ips FROM mabase_prod.agg_host_ip_ja4_1h WHERE window_start >= now() - INTERVAL 72 HOUR GROUP BY hour ORDER BY hour ASC """ result = db.query(sql) hours = [] for row in result.result_rows: hours.append({ "hour": int(row[0]), "hits": int(row[1]), "ips": int(row[2]), }) return {"hours": hours} except Exception as e: raise HTTPException(status_code=500, detail=str(e))