openenv-cloudsoc / debug_cloudsoc.py
OpenEnv Contributor
Initial commit: OpenEnv-CloudSOC benchmark environment
115612d
Raw
History Blame Contribute Delete
12.4 kB
#!/usr/bin/env python
"""
Debug Script for OpenEnv-CloudSOC
==================================
Interactive debugging and exploration tool
Usage:
python debug_cloudsoc.py [--task easy|medium|hard] [--seed 42]
"""
import json
import sys
from cloud_soc_env import CloudSOCEnv, InstanceState
def print_section(title):
"""Print a formatted section header"""
print(f"\n{'='*60}")
print(f" {title}")
print(f"{'='*60}\n")
def explore_environment(task="easy", seed=42):
"""Interactively explore the environment"""
print_section(f"CloudSOC Environment: {task.upper()}")
env = CloudSOCEnv(task=task, seed=seed)
obs, info = env.reset()
print(f"Scenario: {env.scenario['name']}")
print(f"Description: {env.scenario['description']}")
print(f"Max Steps: {env.max_steps}")
print(f"Difficulty Multiplier: {env.scenario['difficulty_multiplier']}")
print()
# =========================================================================
# SECTION: INITIAL STATE
# =========================================================================
print_section("Initial Cloud State")
# Instances
print(f"EC2 Instances ({len(env.state.instances)}):")
for iid, inst in env.state.instances.items():
print(f" {iid}")
print(f" State: {inst.state.value}")
print(f" Compromised: {inst.is_compromised}")
print(f" Roles: {inst.attached_roles}")
print(f" Has Snapshot: {inst.has_forensic_snapshot}")
print()
# IAM Roles
print(f"IAM Roles ({len(env.state.roles)}):")
for name, role in env.state.roles.items():
print(f" {name}")
print(f" Policies: {', '.join(role.policies[:2])}...")
print(f" Compromised: {role.is_compromised}")
print(f" Detached: {role.is_detached}")
print(f" Has Backdoor: {role.has_backdoor}")
print()
# S3 Buckets
print(f"S3 Buckets ({len(env.state.buckets)}):")
for name, bucket in env.state.buckets.items():
print(f" {name}")
print(f" Public: {bucket.is_public}")
print(f" Contains Credentials: {bucket.contains_credentials}")
print(f" Public Access Blocked: {bucket.public_access_blocked}")
print()
# =========================================================================
# SECTION: ALERTS AND LOGS
# =========================================================================
print_section("Security Alerts and Indicators")
print(f"SOC Alerts ({len(env.state.alerts)}):")
for i, alert in enumerate(env.state.alerts[:5], 1):
print(f" [{i}] {alert.alert_id}: {alert.title}")
print(f" Severity: {alert.severity} | Source: {alert.source}")
print(f" True Positive: {alert.is_true_positive}")
print()
print(f"CloudWatch Logs ({len(env.state.logs)} total):")
# Categorize logs
attack_logs = [log for log in env.state.logs if log.is_attack_indicator]
red_herrings = [log for log in env.state.logs if log.is_red_herring]
noise = [log for log in env.state.logs if log.is_noise]
print(f" Attack Indicators: {len(attack_logs)}")
for log in attack_logs[:3]:
print(f" [{log.timestamp}] {log.message}")
print()
print(f" Red Herrings: {len(red_herrings)}")
for log in red_herrings[:2]:
print(f" [{log.timestamp}] {log.message}")
print()
print(f" Noise: {len(noise)}")
print(f" (Normal operational logs and benign activity)")
print()
# =========================================================================
# SECTION: INCIDENT RESPONSE OBJECTIVES
# =========================================================================
print_section("Incident Response Objectives")
print(f"Phase Weights:")
for phase, weight in env.scenario["phase_weights"].items():
print(f" {phase}: {weight:.0%}")
print()
print(f"Required Flags ({len(env.scenario['required_flags'])} to discover):")
for flag in env.scenario["required_flags"]:
print(f" • {flag}")
print()
print(f"Ground Truth Timeline:")
for i, event in enumerate(env.scenario["ground_truth_timeline"], 1):
print(f" {i}. {event}")
print()
if "mitre_techniques" in env.scenario:
print(f"MITRE ATT&CK Techniques:")
for tech in env.scenario["mitre_techniques"]:
print(f" • {tech}")
print()
# =========================================================================
# SECTION: INTERACTIVE TOOL TESTING
# =========================================================================
print_section("Interactive Tool Testing")
test_sequence = [
("Get SOC Alerts", "aws.soc.get_alerts", {}),
("Query CloudWatch Basic", "aws.cloudwatch.query_basic", {"log_group": "/aws/ec2"}),
("Describe EC2 Instances", "aws.ec2.describe", {}),
("Check S3 Bucket Policy", "aws.s3.get_bucket_policy", {"bucket_name": "company-backup-2024"}),
]
print("Executing test sequence...\n")
total_reward = 0
for i, (description, tool, args) in enumerate(test_sequence, 1):
action = json.dumps({
"thought": f"Test: {description}",
"tool": tool,
"args": args
})
obs, reward, term, trunc, info = env.step(action)
total_reward += reward
print(f"Step {i}: {description}")
print(f" Tool: {tool}")
print(f" Reward: {reward:+.2f}")
print(f" Cumulative: {total_reward:+.2f}")
if info.get("last_action_error"):
print(f" Error: {info['last_action_error']}")
print()
# =========================================================================
# SECTION: PROGRESS TRACKING
# =========================================================================
print_section("Progress Tracking")
print(f"Discovered Flags: {len(env.state.discovered_flags)}/{len(env.scenario['required_flags'])}")
if env.state.discovered_flags:
for flag in env.state.discovered_flags:
print(f" ✓ {flag}")
print()
print(f"Tool Usage Analytics:")
for tool, count in sorted(env.tool_usage.items(), key=lambda x: x[1], reverse=True):
print(f" {tool}: {count} calls")
print()
print(f"Resource Costs:")
print(f" Query Costs: {env.query_costs:.2f}")
print(f" Total Reward: {total_reward:.2f}")
print()
print(f"Phase Scores:")
for phase, score in env.phase_scores.items():
print(f" {phase}: {score:.2f}")
print()
# =========================================================================
# SECTION: FINAL SCORING
# =========================================================================
print_section("Final Scoring Breakdown")
final_scores = env.calculate_final_score()
for key, value in final_scores.items():
if key == "weighted_total":
print(f"\n{'FINAL SCORE': ^40} {value:.3f}")
else:
print(f" {key:20s}: {value:.3f}")
print()
# =========================================================================
# SECTION: SYSTEM PROMPT PREVIEW
# =========================================================================
print_section("LLM System Prompt (Preview)")
prompt = env.get_system_prompt()
lines = prompt.split('\n')
print('\n'.join(lines[:30]))
print(f"\n... ({len(lines)} lines total)\n")
env.close()
def test_preconditions(task="easy", seed=42):
"""Test action precondition checking"""
print_section("Testing Action Preconditions")
env = CloudSOCEnv(task=task, seed=seed)
env.reset()
# Find a compromised instance
instance_id = None
for iid, inst in env.state.instances.items():
if inst.is_compromised:
instance_id = iid
break
if not instance_id:
print("No compromised instance found!")
return
print(f"Using instance: {instance_id}")
print()
# TEST 1: Isolate without snapshot
print("TEST 1: Try to isolate without snapshot")
print("-" * 40)
action = json.dumps({
"thought": "Isolate instance",
"tool": "aws.ec2.isolate",
"args": {"instance_id": instance_id}
})
obs, reward, term, trunc, info = env.step(action)
print(f"Reward: {reward}")
print(f"Error: {info['last_action_error']}")
print(f"Instance still has snapshot: {not env.state.instances[instance_id].has_forensic_snapshot}")
print()
# Reset for next test
env = CloudSOCEnv(task=task, seed=seed)
env.reset()
# TEST 2: Snapshot then isolate
print("TEST 2: Snapshot followed by isolate (should succeed)")
print("-" * 40)
# Step 1: Snapshot
action = json.dumps({
"thought": "Create forensic snapshot",
"tool": "aws.ec2.snapshot",
"args": {"instance_id": instance_id}
})
obs, reward1, term1, trunc1, info1 = env.step(action)
print(f"Snapshot: reward={reward1}, error={info1['last_action_error']}")
# Step 2: Isolate
action = json.dumps({
"thought": "Isolate instance",
"tool": "aws.ec2.isolate",
"args": {"instance_id": instance_id}
})
obs, reward2, term2, trunc2, info2 = env.step(action)
print(f"Isolate: reward={reward2}, error={info2['last_action_error']}")
print(f"Instance state: {env.state.instances[instance_id].state.value}")
print()
env.close()
def test_adversarial_trap(task="easy", seed=42):
"""Test adversarial trap - terminating compromised instance"""
print_section("Testing Adversarial Trap: Instance Termination")
env = CloudSOCEnv(task=task, seed=seed)
env.reset()
# Find a compromised instance
instance_id = None
for iid, inst in env.state.instances.items():
if inst.is_compromised:
instance_id = iid
break
if not instance_id:
print("No compromised instance found!")
return
print(f"Compromised instance: {instance_id}")
print()
print("Attempting to terminate compromised instance...")
print("-" * 40)
action = json.dumps({
"thought": "Terminate the compromised instance",
"tool": "aws.ec2.terminate",
"args": {"instance_id": instance_id}
})
obs, reward, term, trunc, info = env.step(action)
print(f"Reward: {reward} (EXPECTED: -1.0)")
print(f"Terminated: {term} (EXPECTED: true)")
print(f"Error: {info['last_action_error']}")
print(f"Instance state: {env.state.instances[instance_id].state.value}")
print()
if reward == -1.0 and term:
print("✓ ADVERSARIAL TRAP TRIGGERED!")
print(" The agent made a critical error by destroying forensic evidence.")
else:
print("✗ Trap not triggered as expected")
env.close()
def main():
"""Main debug menu"""
if len(sys.argv) > 1 and sys.argv[1] == "--quick":
explore_environment(task="easy", seed=42)
return
while True:
print("\n" + "="*60)
print(" CloudSOC Debug Menu")
print("="*60)
print("\n1. Explore Environment (Easy)")
print("2. Explore Environment (Medium)")
print("3. Explore Environment (Hard)")
print("4. Test Preconditions")
print("5. Test Adversarial Trap")
print("6. Exit")
choice = input("\nSelect option (1-6): ").strip()
if choice == "1":
explore_environment(task="easy", seed=42)
elif choice == "2":
explore_environment(task="medium", seed=42)
elif choice == "3":
explore_environment(task="hard", seed=42)
elif choice == "4":
test_preconditions(task="easy", seed=42)
elif choice == "5":
test_adversarial_trap(task="easy", seed=42)
elif choice == "6":
print("\nGoodbye!")
break
else:
print("Invalid option!")
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "--quick":
explore_environment(task="easy", seed=42)
else:
main()