Demo / server /tasks.py
Ajayyy00
Initial commit of CyberSOC upgraded RLVR environment
57e71f8
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
"""
Deterministic task definitions for CyberSOCEnv.
Each task defines a fixed attack chain, network layout, and expected
containment actions. No randomness — every run of the same task_id
produces identical initial state.
Tasks:
- easy: Single ransomware endpoint on the corporate subnet.
- medium: Multi-stage lateral movement (phishing -> cred theft -> 3 subnets).
- hard: APT + ransomware with C2, exfiltration, and executive pressure.
"""
from __future__ import annotations
from typing import Any, Dict, List
# =============================================================================
# Network Topology Builder (deterministic, 500-node)
# =============================================================================
def _build_subnet(
name: str,
role: str,
prefix: str,
ip_base: str,
count: int,
start_idx: int,
criticality: float,
default_ports: List[int],
default_procs: List[str],
) -> List[Dict[str, Any]]:
"""Build a list of host dicts for a subnet."""
hosts = []
for i in range(count):
idx = start_idx + i
hosts.append({
"hostname": f"{prefix}-{idx:03d}",
"ip_address": f"{ip_base}.{idx}",
"subnet": name,
"role": role,
"status": "online",
"running_processes": list(default_procs),
"open_ports": list(default_ports),
"criticality": criticality,
})
return hosts
def build_network() -> Dict[str, List[Dict[str, Any]]]:
"""Build the deterministic enterprise network (~50 active hosts).
Reduced from 400 to ~50 nodes for GRPO training throughput (target ≥8 eps/min).
Host indices are chosen to cover all hand-crafted task references (WS-042, WS-088,
DEV-033, FIN-008, FIN-012, SRV-002..SRV-015, EXEC-003) plus a small buffer for
procedural generation and lateral pivot targets. The README still describes a
"500-node enterprise" — the simulation covers the same topology, but only
materializes the operationally relevant hosts.
Returns:
Dict mapping subnet name -> list of host dicts.
"""
network: Dict[str, List[Dict[str, Any]]] = {}
# Corporate: WS-001..WS-005 (buffer) + WS-015..WS-020 (covers WS-017)
# + WS-040..WS-045 (covers WS-042) + WS-085..WS-090 (covers WS-088)
corporate: List[Dict[str, Any]] = []
for start, count in [(1, 5), (15, 6), (40, 6), (85, 6)]:
corporate.extend(_build_subnet(
name="corporate", role="corporate", prefix="WS",
ip_base="10.1.1", count=count, start_idx=start,
criticality=0.3,
default_ports=[135, 445, 3389],
default_procs=["outlook.exe", "chrome.exe", "explorer.exe"],
))
network["corporate"] = corporate # 23 hosts
# Engineering: DEV-001..DEV-005 + DEV-030..DEV-036 (covers DEV-033)
engineering: List[Dict[str, Any]] = []
for start, count in [(1, 5), (30, 7)]:
engineering.extend(_build_subnet(
name="engineering", role="engineering", prefix="DEV",
ip_base="10.2.1", count=count, start_idx=start,
criticality=0.5,
default_ports=[22, 443, 8080, 3389],
default_procs=["vscode.exe", "python.exe", "docker.exe", "git.exe"],
))
network["engineering"] = engineering # 12 hosts
# Finance: FIN-001..FIN-005 + FIN-008..FIN-014 (covers FIN-008, FIN-012)
finance: List[Dict[str, Any]] = []
for start, count in [(1, 5), (8, 7)]:
finance.extend(_build_subnet(
name="finance", role="finance", prefix="FIN",
ip_base="10.3.1", count=count, start_idx=start,
criticality=0.8,
default_ports=[443, 1433, 3389],
default_procs=["excel.exe", "sap.exe", "sqlcmd.exe"],
))
network["finance"] = finance # 12 hosts
# DMZ: DMZ-001..DMZ-003 (no tasks reference DMZ hosts)
network["dmz"] = _build_subnet(
name="dmz", role="dmz", prefix="DMZ",
ip_base="10.4.1", count=3, start_idx=1,
criticality=0.6,
default_ports=[80, 443, 8443],
default_procs=["nginx", "node", "java"],
) # 3 hosts
# Datacenter: SRV-001..SRV-020 (covers SRV-002, SRV-005, SRV-010, SRV-015)
network["datacenter"] = _build_subnet(
name="datacenter", role="datacenter", prefix="SRV",
ip_base="10.5.1", count=20, start_idx=1,
criticality=0.9,
default_ports=[22, 443, 5432, 6379, 9200],
default_procs=["postgres", "redis-server", "elasticsearch", "kubelet"],
) # 20 hosts
# Executive: EXEC-001..EXEC-005 (covers EXEC-003)
network["executive"] = _build_subnet(
name="executive", role="executive", prefix="EXEC",
ip_base="10.6.1", count=5, start_idx=1,
criticality=1.0,
default_ports=[443, 3389],
default_procs=["outlook.exe", "teams.exe", "chrome.exe"],
) # 5 hosts
return network # Total: ~75 hosts
# =============================================================================
# Attack Chain Definitions
# =============================================================================
TASKS: Dict[str, Dict[str, Any]] = {
# ----- EASY: Single ransomware endpoint -----
"easy": {
"description": "Ransomware detected on a single corporate workstation. Isolate and contain.",
"max_steps": 15,
"initial_business_impact": 0.05,
"impact_per_step": 0.02, # Impact grows slowly per step
"attack_chain": [
{
"threat_id": "T-EASY-001",
"threat_type": "ransomware",
"phase": "execution",
"compromised_hosts": ["WS-042"],
"malicious_processes": ["cryptolocker.exe"],
"c2_servers": [],
"iocs": {
"hashes": ["e99a18c428cb38d5f260853678922e03"],
"ips": [],
"domains": [],
},
"lateral_targets": [],
"exfil_targets": [],
},
],
"initial_alerts": [
{
"alert_id": "ALERT-E001",
"timestamp": "2025-01-15T09:23:17Z",
"source_host": "WS-042",
"severity": "critical",
"threat_type": "ransomware",
"description": "EDR detected file encryption activity on WS-042. Process 'cryptolocker.exe' is encrypting files in C:\\Users\\jsmith\\Documents.",
"ioc_indicators": ["e99a18c428cb38d5f260853678922e03"],
"subnet": "corporate",
"is_acknowledged": False,
},
{
"alert_id": "ALERT-E002",
"timestamp": "2025-01-15T09:23:45Z",
"source_host": "WS-042",
"severity": "high",
"threat_type": "ransomware",
"description": "Anomalous file system activity: 147 files renamed with .locked extension in 28 seconds.",
"ioc_indicators": [],
"subnet": "corporate",
"is_acknowledged": False,
},
],
# Optimal containment: kill process, run forensics, block hash, submit plan
"optimal_actions": ["kill_process", "run_forensics", "block_ioc", "submit_containment_plan"],
"containment_requirements": {
"must_kill": [{"hostname": "WS-042", "process": "cryptolocker.exe"}],
"must_block_iocs": ["e99a18c428cb38d5f260853678922e03"],
"must_forensics": ["WS-042"],
"must_not_isolate": ["finance", "engineering", "datacenter"], # Unnecessary isolation = downtime
},
},
# ----- MEDIUM: Multi-stage lateral movement -----
"medium": {
"description": "Phishing attack led to credential theft and lateral movement across 3 subnets.",
"max_steps": 25,
"initial_business_impact": 0.10,
"impact_per_step": 0.03,
"attack_chain": [
{
"threat_id": "T-MED-001",
"threat_type": "phishing",
"phase": "initial_access",
"compromised_hosts": ["WS-017"],
"malicious_processes": ["powershell.exe"],
"c2_servers": [],
"iocs": {
"hashes": ["d41d8cd98f00b204e9800998ecf8427e"],
"ips": [],
"domains": ["evil-login.example.com"],
},
"lateral_targets": [],
"exfil_targets": [],
},
{
"threat_id": "T-MED-002",
"threat_type": "credential_theft",
"phase": "credential_access",
"compromised_hosts": ["WS-017"],
"malicious_processes": ["mimikatz.exe"],
"c2_servers": [],
"iocs": {
"hashes": ["aabbccdd11223344eeff5566778899aa"],
"ips": [],
"domains": [],
},
"lateral_targets": ["DEV-033", "FIN-012"],
"exfil_targets": [],
},
{
"threat_id": "T-MED-003",
"threat_type": "lateral_movement",
"phase": "lateral_movement",
"compromised_hosts": ["DEV-033", "FIN-012"],
"malicious_processes": ["svchost_backdoor.exe"],
"c2_servers": [],
"iocs": {
"hashes": ["112233445566778899aabbccddeeff00"],
"ips": ["203.0.113.50"],
"domains": [],
},
"lateral_targets": ["SRV-005"],
"exfil_targets": [],
},
],
"initial_alerts": [
{
"alert_id": "ALERT-M001",
"timestamp": "2025-01-15T08:15:00Z",
"source_host": "WS-017",
"severity": "medium",
"threat_type": "phishing",
"description": "User clicked suspicious link in email. PowerShell execution detected downloading payload from evil-login.example.com.",
"ioc_indicators": ["evil-login.example.com"],
"subnet": "corporate",
"is_acknowledged": False,
},
{
"alert_id": "ALERT-M002",
"timestamp": "2025-01-15T08:32:00Z",
"source_host": "WS-017",
"severity": "high",
"threat_type": "credential_theft",
"description": "LSASS memory access detected — possible credential dumping via Mimikatz.",
"ioc_indicators": ["aabbccdd11223344eeff5566778899aa"],
"subnet": "corporate",
"is_acknowledged": False,
},
{
"alert_id": "ALERT-M003",
"timestamp": "2025-01-15T09:05:00Z",
"source_host": "DEV-033",
"severity": "high",
"threat_type": "lateral_movement",
"description": "Suspicious RDP login from WS-017 using admin credentials. New process svchost_backdoor.exe spawned.",
"ioc_indicators": ["203.0.113.50", "112233445566778899aabbccddeeff00"],
"subnet": "engineering",
"is_acknowledged": False,
},
{
"alert_id": "ALERT-M004",
"timestamp": "2025-01-15T09:12:00Z",
"source_host": "FIN-012",
"severity": "critical",
"threat_type": "lateral_movement",
"description": "Unauthorized access to FIN-012 from compromised credentials. Backdoor process active.",
"ioc_indicators": ["112233445566778899aabbccddeeff00"],
"subnet": "finance",
"is_acknowledged": False,
},
],
"optimal_actions": [
"query_host", "run_forensics", "kill_process", "block_ioc",
"isolate_segment", "run_forensics", "submit_containment_plan",
],
"containment_requirements": {
"must_kill": [
{"hostname": "WS-017", "process": "powershell.exe"},
{"hostname": "WS-017", "process": "mimikatz.exe"},
{"hostname": "DEV-033", "process": "svchost_backdoor.exe"},
{"hostname": "FIN-012", "process": "svchost_backdoor.exe"},
],
"must_block_iocs": [
"evil-login.example.com",
"203.0.113.50",
"d41d8cd98f00b204e9800998ecf8427e",
"aabbccdd11223344eeff5566778899aa",
"112233445566778899aabbccddeeff00",
],
"must_forensics": ["WS-017", "DEV-033", "FIN-012"],
"must_not_isolate": ["executive", "datacenter"],
},
},
# ----- HARD: APT + Ransomware, C2, exfiltration, executive pressure -----
"hard": {
"description": "Advanced Persistent Threat with active C2 comms, data exfiltration in progress, and ransomware deployment imminent. Board is watching — minimize downtime.",
"max_steps": 30,
"initial_business_impact": 0.20,
"impact_per_step": 0.04,
"attack_chain": [
{
"threat_id": "T-HARD-001",
"threat_type": "phishing",
"phase": "initial_access",
"compromised_hosts": ["EXEC-003"],
"malicious_processes": ["outlook_macro.exe"],
"c2_servers": ["198.51.100.77"],
"iocs": {
"hashes": ["deadbeef0123456789abcdef01234567"],
"ips": ["198.51.100.77"],
"domains": ["cdn-update.malware-c2.net"],
},
"lateral_targets": ["WS-088"],
"exfil_targets": [],
},
{
"threat_id": "T-HARD-002",
"threat_type": "c2_communication",
"phase": "command_and_control",
"compromised_hosts": ["EXEC-003", "WS-088"],
"malicious_processes": ["svchost_c2.exe"],
"c2_servers": ["198.51.100.77"],
"iocs": {
"hashes": ["cafebabe9876543210fedcba98765432"],
"ips": ["198.51.100.77"],
"domains": ["cdn-update.malware-c2.net", "exfil.malware-c2.net"],
},
"lateral_targets": ["SRV-002", "FIN-008"],
"exfil_targets": [],
},
{
"threat_id": "T-HARD-003",
"threat_type": "privilege_escalation",
"phase": "privilege_escalation",
"compromised_hosts": ["SRV-002"],
"malicious_processes": ["exploit_kernel.exe"],
"c2_servers": ["198.51.100.77"],
"iocs": {
"hashes": ["1122334455667788aabbccddeeff0011"],
"ips": ["198.51.100.77"],
"domains": [],
},
"lateral_targets": ["SRV-010", "SRV-015"],
"exfil_targets": ["SRV-002"],
},
{
"threat_id": "T-HARD-004",
"threat_type": "data_exfiltration",
"phase": "exfiltration",
"compromised_hosts": ["SRV-002", "FIN-008"],
"malicious_processes": ["data_pump.exe"],
"c2_servers": ["198.51.100.77"],
"iocs": {
"hashes": ["ffeeddccbbaa99887766554433221100"],
"ips": ["198.51.100.77", "203.0.113.99"],
"domains": ["exfil.malware-c2.net"],
},
"lateral_targets": [],
"exfil_targets": ["SRV-002", "FIN-008"],
},
{
"threat_id": "T-HARD-005",
"threat_type": "ransomware",
"phase": "impact",
"compromised_hosts": ["SRV-010", "SRV-015"],
"malicious_processes": ["blackcat_ransom.exe"],
"c2_servers": [],
"iocs": {
"hashes": ["aabb0011ccdd2233eeff4455667788"],
"ips": [],
"domains": [],
},
"lateral_targets": [],
"exfil_targets": [],
},
],
"initial_alerts": [
{
"alert_id": "ALERT-H001",
"timestamp": "2025-01-15T06:00:00Z",
"source_host": "EXEC-003",
"severity": "medium",
"threat_type": "phishing",
"description": "Executive VP opened macro-enabled document. Outbound connection to cdn-update.malware-c2.net detected.",
"ioc_indicators": ["cdn-update.malware-c2.net", "198.51.100.77"],
"subnet": "executive",
"is_acknowledged": False,
},
{
"alert_id": "ALERT-H002",
"timestamp": "2025-01-15T06:45:00Z",
"source_host": "WS-088",
"severity": "high",
"threat_type": "c2_communication",
"description": "Periodic beaconing detected to 198.51.100.77 every 60 seconds. Encrypted payload exchange observed.",
"ioc_indicators": ["198.51.100.77", "cafebabe9876543210fedcba98765432"],
"subnet": "corporate",
"is_acknowledged": False,
},
{
"alert_id": "ALERT-H003",
"timestamp": "2025-01-15T07:30:00Z",
"source_host": "SRV-002",
"severity": "critical",
"threat_type": "privilege_escalation",
"description": "Kernel exploit attempt on SRV-002 (database server). Process exploit_kernel.exe gained SYSTEM privileges.",
"ioc_indicators": ["1122334455667788aabbccddeeff0011"],
"subnet": "datacenter",
"is_acknowledged": False,
},
{
"alert_id": "ALERT-H004",
"timestamp": "2025-01-15T08:00:00Z",
"source_host": "SRV-002",
"severity": "critical",
"threat_type": "data_exfiltration",
"description": "Large data transfer (2.3 GB) to external IP 203.0.113.99 from database server SRV-002. Possible exfiltration of customer PII.",
"ioc_indicators": ["203.0.113.99", "exfil.malware-c2.net"],
"subnet": "datacenter",
"is_acknowledged": False,
},
{
"alert_id": "ALERT-H005",
"timestamp": "2025-01-15T08:10:00Z",
"source_host": "FIN-008",
"severity": "critical",
"threat_type": "data_exfiltration",
"description": "Financial records being staged for exfiltration on FIN-008. Process data_pump.exe accessing sensitive directories.",
"ioc_indicators": ["ffeeddccbbaa99887766554433221100"],
"subnet": "finance",
"is_acknowledged": False,
},
{
"alert_id": "ALERT-H006",
"timestamp": "2025-01-15T08:30:00Z",
"source_host": "SRV-010",
"severity": "critical",
"threat_type": "ransomware",
"description": "BlackCat ransomware deployment detected on SRV-010! File encryption starting on production storage.",
"ioc_indicators": ["aabb0011ccdd2233eeff4455667788"],
"subnet": "datacenter",
"is_acknowledged": False,
},
],
"optimal_actions": [
"block_ioc", "kill_process", "run_forensics", "isolate_segment",
"kill_process", "block_ioc", "run_forensics", "kill_process",
"submit_containment_plan",
],
"containment_requirements": {
"must_kill": [
{"hostname": "EXEC-003", "process": "outlook_macro.exe"},
{"hostname": "EXEC-003", "process": "svchost_c2.exe"},
{"hostname": "WS-088", "process": "svchost_c2.exe"},
{"hostname": "SRV-002", "process": "exploit_kernel.exe"},
{"hostname": "SRV-002", "process": "data_pump.exe"},
{"hostname": "FIN-008", "process": "data_pump.exe"},
{"hostname": "SRV-010", "process": "blackcat_ransom.exe"},
{"hostname": "SRV-015", "process": "blackcat_ransom.exe"},
],
"must_block_iocs": [
"198.51.100.77",
"203.0.113.99",
"cdn-update.malware-c2.net",
"exfil.malware-c2.net",
"deadbeef0123456789abcdef01234567",
"cafebabe9876543210fedcba98765432",
],
"must_forensics": ["EXEC-003", "WS-088", "SRV-002", "FIN-008", "SRV-010"],
"must_not_isolate": [], # In APT scenario, any isolation decision is valid
},
},
}
def get_task(task_id: str) -> Dict[str, Any]:
"""Retrieve a task definition by ID.
Supports:
- 'easy', 'medium', 'hard': Hand-crafted curated benchmarks
- 'gen_0001' through 'gen_1000': Procedurally generated scenarios
- Any other string: Generated on-the-fly via seeded procedural generation
Args:
task_id: Task identifier string.
Returns:
Task definition dict.
"""
# Check hand-crafted tasks first
if task_id in TASKS:
return TASKS[task_id]
# Fall back to procedural generation
try:
from .task_generator import generate_task
except ImportError:
from server.task_generator import generate_task
return generate_task(task_id)