"""
Security Audit Scenarios — Ground truth network definitions.
Each scenario defines a simulated corporate network with hosts, services,
endpoints, and vulnerabilities. The agent must discover these through
tool calls.
"""
from typing import Any, Dict, List
def get_scenario(scenario_id: str) -> Dict[str, Any]:
"""Get a scenario by ID.
The 3 fixed IDs (easy/medium/hard) use legacy definitions for backward
compatibility with existing tests and evaluator. Any other ID triggers
the procedural generator, producing a unique scenario from a deterministic
seed derived from the ID string.
"""
_LEGACY = {"easy": _scenario_easy, "medium": _scenario_medium, "hard": _scenario_hard}
if scenario_id in _LEGACY:
return _LEGACY[scenario_id]()
# Dynamic scenario generation for custom IDs
try:
from .generator import generate_scenario
except ImportError:
from server.generator import generate_scenario
return generate_scenario(scenario_id)
def list_scenarios() -> List[Dict[str, str]]:
"""List all available scenarios with descriptions."""
return [
{
"id": "easy",
"name": "Startup Web App Audit",
"description": "Basic security audit of a small startup's web application. 2 hosts, 3 known vulnerabilities.",
"difficulty": "easy",
"max_steps": 30,
},
{
"id": "medium",
"name": "E-commerce Platform Audit",
"description": "Security compliance audit of an e-commerce platform. 4 hosts, 6 vulnerabilities including chained attacks.",
"difficulty": "medium",
"max_steps": 50,
},
{
"id": "hard",
"name": "Enterprise SOC2 Pre-Audit",
"description": "Full-scope pre-SOC2 audit of enterprise infrastructure. 6 hosts, 10 vulnerabilities, honeypots, and time pressure.",
"difficulty": "hard",
"max_steps": 60,
},
]
def _scenario_easy() -> Dict[str, Any]:
return {
"id": "easy",
"name": "Startup Web App Audit",
"company": "QuickLaunch SaaS Inc.",
"compliance_context": "Pre-launch security review",
"target_network": "10.0.1.0/24",
"max_steps": 30,
"briefing": (
"You are conducting a pre-launch security audit for QuickLaunch SaaS Inc. "
"Target network: 10.0.1.0/24. The company runs a simple web application "
"with a backend database. Identify all security vulnerabilities, assess "
"their severity, and submit structured findings."
),
"hosts": {
"10.0.1.10": {
"hostname": "web-app-01",
"os": "Ubuntu 20.04 LTS",
"role": "Web Application Server",
},
"10.0.1.20": {
"hostname": "db-server-01",
"os": "Ubuntu 18.04 LTS",
"role": "Database Server",
},
},
"ports": {
"10.0.1.10": [
{"port": 22, "service": "ssh", "version": "OpenSSH 8.2p1", "state": "open"},
{"port": 80, "service": "http", "version": "Apache 2.4.41", "state": "open"},
{"port": 443, "service": "https", "version": "Apache 2.4.41", "state": "open"},
],
"10.0.1.20": [
{"port": 22, "service": "ssh", "version": "OpenSSH 7.6p1", "state": "open"},
{"port": 3306, "service": "mysql", "version": "MySQL 5.7.28", "state": "open"},
],
},
"web_endpoints": {
"10.0.1.10": [
{"path": "/", "method": "GET", "description": "Homepage"},
{"path": "/api/login", "method": "POST", "description": "User login endpoint", "params": ["username", "password"]},
{"path": "/api/search", "method": "GET", "description": "Product search", "params": ["query"]},
{"path": "/admin", "method": "GET", "description": "Admin panel"},
{"path": "/api/users", "method": "GET", "description": "User listing API"},
],
},
"vulnerabilities": [
{
"id": "VULN-E001",
"host": "10.0.1.10",
"endpoint": "/api/login",
"type": "SQL Injection",
"cwe": "CWE-89",
"owasp": "A03:2021 - Injection",
"cvss": 9.8,
"severity": "Critical",
"evidence": "Parameter 'username' vulnerable: ' OR 1=1-- bypasses authentication. MySQL error exposed in response.",
"remediation": "Use parameterized queries or prepared statements for all database operations.",
"discoverable_by": ["test_injection"],
"compliance_controls": ["Input Validation", "Secure Coding"],
},
{
"id": "VULN-E002",
"host": "10.0.1.10",
"endpoint": "/admin",
"type": "Broken Authentication",
"cwe": "CWE-798",
"owasp": "A07:2021 - Identification and Authentication Failures",
"cvss": 8.1,
"severity": "High",
"evidence": "Admin panel accessible with default credentials admin:admin123. No account lockout after failed attempts.",
"remediation": "Change default credentials immediately. Implement account lockout and MFA.",
"discoverable_by": ["test_auth"],
"compliance_controls": ["Authentication", "Credential Management"],
},
{
"id": "VULN-E003",
"host": "10.0.1.20",
"endpoint": None,
"type": "Security Misconfiguration",
"cwe": "CWE-200",
"owasp": "A05:2021 - Security Misconfiguration",
"cvss": 9.1,
"severity": "Critical",
"evidence": "MySQL port 3306 is accessible from the public internet. No firewall rules restricting access. Remote root login enabled.",
"remediation": "Restrict MySQL access to application server IPs only using firewall rules. Disable remote root login.",
"discoverable_by": ["network_scan", "test_config"],
"compliance_controls": ["Network Security", "Access Control"],
},
],
"honeypots": [],
}
def _scenario_medium() -> Dict[str, Any]:
return {
"id": "medium",
"name": "E-commerce Platform Audit",
"company": "ShopFast Commerce Ltd.",
"compliance_context": "PCI-DSS compliance assessment",
"target_network": "10.0.2.0/24",
"max_steps": 50,
"briefing": (
"You are conducting a PCI-DSS compliance security audit for ShopFast Commerce Ltd. "
"Target network: 10.0.2.0/24. The company operates an e-commerce platform with "
"a web frontend, REST API, CI/CD pipeline, and internal database. Some vulnerabilities "
"may require discovering one system to find others. Submit all findings with "
"severity ratings and compliance framework references."
),
"hosts": {
"10.0.2.10": {
"hostname": "web-frontend",
"os": "Ubuntu 22.04 LTS",
"role": "Web Frontend + API Server",
},
"10.0.2.20": {
"hostname": "api-backend",
"os": "Ubuntu 20.04 LTS",
"role": "REST API Backend",
},
"10.0.2.30": {
"hostname": "ci-jenkins",
"os": "Ubuntu 20.04 LTS",
"role": "CI/CD Server (Jenkins)",
"hidden_until": ["VULN-M001"],
},
"10.0.2.40": {
"hostname": "db-primary",
"os": "Ubuntu 20.04 LTS",
"role": "PostgreSQL Database",
"hidden_until": ["VULN-M001"],
},
},
"ports": {
"10.0.2.10": [
{"port": 22, "service": "ssh", "version": "OpenSSH 8.9p1", "state": "open"},
{"port": 80, "service": "http", "version": "nginx 1.18.0", "state": "open"},
{"port": 443, "service": "https", "version": "nginx 1.18.0", "state": "open"},
],
"10.0.2.20": [
{"port": 22, "service": "ssh", "version": "OpenSSH 8.2p1", "state": "open"},
{"port": 8080, "service": "http", "version": "Express.js 4.17.1 (Node.js)", "state": "open"},
],
"10.0.2.30": [
{"port": 22, "service": "ssh", "version": "OpenSSH 8.2p1", "state": "open"},
{"port": 8080, "service": "http", "version": "Jenkins 2.235.1", "state": "open"},
],
"10.0.2.40": [
{"port": 22, "service": "ssh", "version": "OpenSSH 8.2p1", "state": "open"},
{"port": 5432, "service": "postgresql", "version": "PostgreSQL 13.4", "state": "open"},
],
},
"web_endpoints": {
"10.0.2.10": [
{"path": "/", "method": "GET", "description": "Store homepage"},
{"path": "/login", "method": "POST", "description": "User login", "params": ["email", "password"]},
{"path": "/api/products", "method": "GET", "description": "Product listing"},
{"path": "/api/upload/image", "method": "POST", "description": "Product image upload", "params": ["image_url"]},
{"path": "/static/js/app.bundle.js", "method": "GET", "description": "Frontend JavaScript bundle"},
],
"10.0.2.20": [
{"path": "/api/v1/orders", "method": "GET", "description": "Order listing"},
{"path": "/api/v1/orders/{id}", "method": "GET", "description": "Order details by ID", "params": ["id"]},
{"path": "/api/v1/users/profile", "method": "GET", "description": "User profile"},
{"path": "/api/v1/payment/process", "method": "POST", "description": "Payment processing"},
],
"10.0.2.30": [
{"path": "/", "method": "GET", "description": "Jenkins dashboard"},
{"path": "/script", "method": "GET", "description": "Groovy script console"},
{"path": "/manage", "method": "GET", "description": "Jenkins management"},
],
},
"vulnerabilities": [
{
"id": "VULN-M001",
"host": "10.0.2.10",
"endpoint": "/api/upload/image",
"type": "Server-Side Request Forgery (SSRF)",
"cwe": "CWE-918",
"owasp": "A10:2021 - Server-Side Request Forgery",
"cvss": 8.6,
"severity": "High",
"evidence": "The image_url parameter accepts internal URLs. Requesting image_url=http://10.0.2.30:8080 returns Jenkins dashboard HTML. Can be used to scan internal network.",
"remediation": "Validate and whitelist allowed URL schemes and domains. Block requests to private IP ranges.",
"discoverable_by": ["test_injection"],
"compliance_controls": ["PCI-DSS 6.5.9 — SSRF", "PCI-DSS 6.5.1 — Injection Flaws"],
},
{
"id": "VULN-M002",
"host": "10.0.2.20",
"endpoint": "/api/v1/orders/{id}",
"type": "Broken Access Control (IDOR)",
"cwe": "CWE-639",
"owasp": "A01:2021 - Broken Access Control",
"cvss": 7.5,
"severity": "High",
"evidence": "Changing the order ID parameter to another user's order ID returns their order details including PII and payment info. No authorization check on resource ownership.",
"remediation": "Implement proper authorization checks. Verify the authenticated user owns the requested resource.",
"discoverable_by": ["test_auth"],
"compliance_controls": ["PCI-DSS 6.5.8 — Improper Access Control", "PCI-DSS 7.1 — Need to Know"],
},
{
"id": "VULN-M003",
"host": "10.0.2.10",
"endpoint": "/static/js/app.bundle.js",
"type": "Sensitive Data Exposure",
"cwe": "CWE-798",
"owasp": "A02:2021 - Cryptographic Failures",
"cvss": 7.8,
"severity": "High",
"evidence": "Hardcoded API key found in JavaScript bundle: STRIPE_SECRET_KEY=sk_live_EXAMPLE_REDACTED_KEY_HERE. Also contains internal API URLs.",
"remediation": "Remove hardcoded secrets from client-side code. Use environment variables and server-side proxies for API keys.",
"discoverable_by": ["check_secrets"],
"compliance_controls": ["PCI-DSS 6.5.3 — Insecure Cryptographic Storage", "PCI-DSS 3.4 — Render PAN Unreadable"],
},
{
"id": "VULN-M004",
"host": "10.0.2.30",
"endpoint": "/script",
"type": "Security Misconfiguration",
"cwe": "CWE-306",
"owasp": "A05:2021 - Security Misconfiguration",
"cvss": 9.9,
"severity": "Critical",
"evidence": "Jenkins Groovy script console accessible without authentication. Allows arbitrary command execution on the CI/CD server. Full RCE via: 'cmd'.execute().text",
"remediation": "Enable authentication on Jenkins. Restrict script console access to admin users. Place Jenkins behind VPN.",
"discoverable_by": ["test_auth", "test_config"],
"requires_found": ["VULN-M001"],
"compliance_controls": ["PCI-DSS 2.1 — Default Passwords", "PCI-DSS 6.5.10 — Broken Auth/Session"],
},
{
"id": "VULN-M005",
"host": "10.0.2.40",
"endpoint": None,
"type": "Weak Credentials",
"cwe": "CWE-521",
"owasp": "A07:2021 - Identification and Authentication Failures",
"cvss": 8.2,
"severity": "High",
"evidence": "PostgreSQL accepts connections with weak credentials: dbuser/dbpass123. Password found via brute force. No connection rate limiting.",
"remediation": "Enforce strong password policy. Restrict database access to application IPs. Use certificate-based authentication.",
"discoverable_by": ["test_auth"],
"requires_found": ["VULN-M003"],
"compliance_controls": ["PCI-DSS 8.2.1 — Unique User ID", "PCI-DSS 8.2.3 — Password Complexity"],
},
{
"id": "VULN-M006",
"host": "10.0.2.10",
"endpoint": "/",
"type": "Cryptographic Failures",
"cwe": "CWE-326",
"owasp": "A02:2021 - Cryptographic Failures",
"cvss": 5.3,
"severity": "Medium",
"evidence": "Server supports TLS 1.0 and TLS 1.1 which are deprecated. Weak cipher suites detected: TLS_RSA_WITH_3DES_EDE_CBC_SHA.",
"remediation": "Disable TLS 1.0 and 1.1. Configure server to support only TLS 1.2+ with strong cipher suites.",
"discoverable_by": ["test_crypto"],
"compliance_controls": ["PCI-DSS 4.1 — Strong Cryptography", "PCI-DSS 2.2.3 — Secure Protocols"],
},
],
"honeypots": [],
}
def _scenario_hard() -> Dict[str, Any]:
return {
"id": "hard",
"name": "Enterprise SOC2 Pre-Audit",
"company": "FinSecure Corp.",
"compliance_context": "SOC2 Type II pre-assessment",
"target_network": "10.0.3.0/24",
"max_steps": 60,
"briefing": (
"You are conducting a comprehensive SOC2 Type II pre-assessment for FinSecure Corp., "
"a financial services company. Target network: 10.0.3.0/24. The infrastructure includes "
"web applications, APIs, internal services, file storage, and a mail server. "
"WARNING: Some services may be honeypots — false positive findings will be penalized. "
"Conduct a thorough but careful audit. Map all findings to OWASP and CWE classifications."
),
"hosts": {
"10.0.3.10": {
"hostname": "web-portal",
"os": "Ubuntu 22.04 LTS",
"role": "Customer Portal",
},
"10.0.3.20": {
"hostname": "api-gateway",
"os": "Ubuntu 22.04 LTS",
"role": "API Gateway",
},
"10.0.3.30": {
"hostname": "internal-app",
"os": "Ubuntu 20.04 LTS",
"role": "Internal Application Server",
"hidden_until": ["VULN-H001"],
},
"10.0.3.40": {
"hostname": "file-server",
"os": "Windows Server 2019",
"role": "File Storage Server",
"hidden_until": ["VULN-H001"],
},
"10.0.3.50": {
"hostname": "mail-server",
"os": "Ubuntu 20.04 LTS",
"role": "Email Server",
"hidden_until": ["VULN-H001"],
},
"10.0.3.99": {
"hostname": "staging-app-02",
"os": "Ubuntu 22.04 LTS",
"role": "Staging Application Server",
"is_honeypot": True,
},
},
"ports": {
"10.0.3.10": [
{"port": 22, "service": "ssh", "version": "OpenSSH 8.9p1", "state": "open"},
{"port": 443, "service": "https", "version": "nginx 1.22.0", "state": "open"},
],
"10.0.3.20": [
{"port": 22, "service": "ssh", "version": "OpenSSH 8.9p1", "state": "open"},
{"port": 8443, "service": "https", "version": "Kong Gateway 3.4", "state": "open"},
],
"10.0.3.30": [
{"port": 22, "service": "ssh", "version": "OpenSSH 8.2p1", "state": "open"},
{"port": 8080, "service": "http", "version": "Apache Tomcat 9.0.31", "state": "open"},
{"port": 5000, "service": "http", "version": "Flask 2.0.1", "state": "open"},
],
"10.0.3.40": [
{"port": 445, "service": "microsoft-ds", "version": "Windows Server 2019 SMB", "state": "open"},
{"port": 3389, "service": "ms-wbt-server", "version": "Microsoft RDP", "state": "open"},
{"port": 21, "service": "ftp", "version": "FileZilla 0.9.60", "state": "open"},
],
"10.0.3.50": [
{"port": 25, "service": "smtp", "version": "Postfix 3.4.13", "state": "open"},
{"port": 143, "service": "imap", "version": "Dovecot 2.3.13", "state": "open"},
{"port": 993, "service": "imaps", "version": "Dovecot 2.3.13", "state": "open"},
],
"10.0.3.99": [
{"port": 22, "service": "ssh", "version": "OpenSSH 8.9p1", "state": "open"},
{"port": 443, "service": "https", "version": "nginx 1.22.0", "state": "open"},
{"port": 8080, "service": "http", "version": "Apache Tomcat 9.0.65", "state": "open"},
],
},
"web_endpoints": {
"10.0.3.10": [
{"path": "/", "method": "GET", "description": "Customer portal homepage"},
{"path": "/login", "method": "POST", "description": "Customer login", "params": ["email", "password"]},
{"path": "/dashboard", "method": "GET", "description": "Customer dashboard"},
{"path": "/support/ticket", "method": "POST", "description": "Create support ticket", "params": ["subject", "message"]},
{"path": "/profile/update", "method": "PUT", "description": "Update user profile", "params": ["name", "email", "phone"]},
],
"10.0.3.20": [
{"path": "/api/v2/accounts", "method": "GET", "description": "Account listing"},
{"path": "/api/v2/accounts/{id}", "method": "GET", "description": "Account details"},
{"path": "/api/v2/transfer", "method": "POST", "description": "Fund transfer", "params": ["from_account", "to_account", "amount"]},
{"path": "/api/v2/statements", "method": "GET", "description": "Account statements"},
],
"10.0.3.30": [
{"path": "/", "method": "GET", "description": "Internal app dashboard"},
{"path": "/admin/users", "method": "GET", "description": "User management"},
{"path": "/reports/generate", "method": "POST", "description": "Generate report", "params": ["template", "date_range"]},
{"path": "/upload", "method": "POST", "description": "File upload", "params": ["file"]},
],
},
"vulnerabilities": [
{
"id": "VULN-H001",
"host": "10.0.3.10",
"endpoint": "/support/ticket",
"type": "Stored XSS",
"cwe": "CWE-79",
"owasp": "A03:2021 - Injection",
"cvss": 6.1,
"severity": "Medium",
"evidence": "The 'message' field in support tickets does not sanitize HTML. Payload is stored and rendered to support agents.",
"remediation": "Sanitize all user input. Use output encoding. Implement Content-Security-Policy headers.",
"discoverable_by": ["test_xss"],
"compliance_controls": ["CC6.1 — Logical Access Security", "CC7.2 — System Monitoring"],
},
{
"id": "VULN-H002",
"host": "10.0.3.20",
"endpoint": "/api/v2/accounts/{id}",
"type": "Broken Access Control (BOLA)",
"cwe": "CWE-639",
"owasp": "A01:2021 - Broken Access Control",
"cvss": 7.5,
"severity": "High",
"evidence": "Enumerating account IDs (sequential integers) returns other customers' account details including balance, transaction history, and PII.",
"remediation": "Use UUIDs instead of sequential IDs. Implement authorization checks verifying account ownership.",
"discoverable_by": ["test_auth"],
"compliance_controls": ["CC6.1 — Logical Access Security", "CC6.3 — Role-Based Access"],
},
{
"id": "VULN-H003",
"host": "10.0.3.20",
"endpoint": "/api/v2/transfer",
"type": "Business Logic Flaw",
"cwe": "CWE-362",
"owasp": "A04:2021 - Insecure Design",
"cvss": 8.1,
"severity": "High",
"evidence": "Race condition in transfer endpoint. Sending multiple concurrent transfer requests allows double-spending — balance check and deduction are not atomic.",
"remediation": "Implement database-level locking on balance operations. Use idempotency keys for transfer requests.",
"discoverable_by": ["test_injection"],
"requires_found": ["VULN-H002"],
"compliance_controls": ["CC8.1 — Change Management", "PI1.1 — Processing Integrity"],
},
{
"id": "VULN-H004",
"host": "10.0.3.30",
"endpoint": "/reports/generate",
"type": "Server-Side Template Injection (SSTI)",
"cwe": "CWE-1336",
"owasp": "A03:2021 - Injection",
"cvss": 9.8,
"severity": "Critical",
"evidence": "The 'template' parameter is processed by Jinja2 without sandboxing. Payload {{7*7}} returns 49. Full RCE possible via __import__('os').popen('id').read().",
"remediation": "Use Jinja2 SandboxedEnvironment. Never pass user input directly as template content.",
"discoverable_by": ["test_injection"],
"compliance_controls": ["CC6.6 — System Boundaries", "CC6.1 — Logical Access Security"],
},
{
"id": "VULN-H005",
"host": "10.0.3.30",
"endpoint": "/upload",
"type": "Unrestricted File Upload",
"cwe": "CWE-434",
"owasp": "A04:2021 - Insecure Design",
"cvss": 8.8,
"severity": "High",
"evidence": "File upload accepts .php and .jsp files without validation. Uploaded files are accessible at /uploads/ and are executed by the server.",
"remediation": "Whitelist allowed file types. Store uploads outside webroot. Rename files with random UUIDs.",
"discoverable_by": ["test_config"],
"requires_found": ["VULN-H004"],
"compliance_controls": ["CC6.6 — System Boundaries", "CC7.2 — System Monitoring"],
},
{
"id": "VULN-H006",
"host": "10.0.3.40",
"endpoint": None,
"type": "Weak Credentials",
"cwe": "CWE-521",
"owasp": "A07:2021 - Identification and Authentication Failures",
"cvss": 8.5,
"severity": "High",
"evidence": "FTP server accepts anonymous login. SMB share 'Documents' accessible with guest credentials. Contains sensitive financial reports and employee data.",
"remediation": "Disable anonymous FTP access. Require authentication for all SMB shares. Implement least privilege access.",
"discoverable_by": ["test_auth"],
"compliance_controls": ["CC6.1 — Logical Access Security", "CC6.2 — Prior to Access"],
},
{
"id": "VULN-H007",
"host": "10.0.3.40",
"endpoint": None,
"type": "Missing Encryption",
"cwe": "CWE-319",
"owasp": "A02:2021 - Cryptographic Failures",
"cvss": 6.5,
"severity": "Medium",
"evidence": "FTP service (port 21) transfers data in plaintext. Sensitive files including financial reports are transmitted without encryption.",
"remediation": "Replace FTP with SFTP or FTPS. Enforce TLS for all file transfers.",
"discoverable_by": ["test_crypto"],
"requires_found": ["VULN-H006"],
"compliance_controls": ["CC6.7 — Restrict Data Transmission", "C1.1 — Confidentiality Commitments"],
},
{
"id": "VULN-H008",
"host": "10.0.3.50",
"endpoint": None,
"type": "Email Security Misconfiguration",
"cwe": "CWE-345",
"owasp": "A05:2021 - Security Misconfiguration",
"cvss": 5.8,
"severity": "Medium",
"evidence": "SMTP server allows open relay from internal network. No SPF, DKIM, or DMARC records configured. Susceptible to email spoofing.",
"remediation": "Configure SPF, DKIM, and DMARC records. Restrict SMTP relay to authenticated users only.",
"discoverable_by": ["test_config"],
"compliance_controls": ["CC6.6 — System Boundaries", "CC7.1 — Detect Changes"],
},
{
"id": "VULN-H009",
"host": "10.0.3.30",
"endpoint": None,
"type": "Vulnerable Component",
"cwe": "CWE-1035",
"owasp": "A06:2021 - Vulnerable and Outdated Components",
"cvss": 9.8,
"severity": "Critical",
"evidence": "Apache Tomcat 9.0.31 is vulnerable to CVE-2020-1938 (GhostCat). AJP connector on port 8009 allows file read and potential RCE.",
"remediation": "Upgrade Tomcat to latest version. Disable AJP connector if not needed. Restrict AJP access to localhost.",
"discoverable_by": ["vulnerability_scan"],
"compliance_controls": ["CC7.1 — Detect Changes", "CC8.1 — Change Management"],
},
{
"id": "VULN-H010",
"host": "10.0.3.10",
"endpoint": "/login",
"type": "Missing Rate Limiting",
"cwe": "CWE-307",
"owasp": "A07:2021 - Identification and Authentication Failures",
"cvss": 7.3,
"severity": "High",
"evidence": "Login endpoint allows unlimited authentication attempts. No CAPTCHA, no account lockout, no rate limiting detected after 1000+ requests.",
"remediation": "Implement rate limiting (e.g., 5 attempts per minute). Add account lockout after 10 failed attempts. Deploy CAPTCHA.",
"discoverable_by": ["test_auth"],
"compliance_controls": ["CC6.1 — Logical Access Security", "CC6.8 — Prevent Unauthorized Access"],
},
],
"honeypots": ["10.0.3.99"],
}