Files
T
mukul975 c47eed6a64 Production hardening: security fixes, code quality, 724 skills complete
- Fix 25 shell=True subprocess calls with list-based commands
- Fix 49 verify=False in defensive skills (env-var override)
- Add timeout to 231 HTTP/subprocess/socket calls
- Fix 6 SQL injection patterns with whitelist validation
- Replace 8 __import__() with standard imports
- Remove 701 unused imports across 442 files
- Add authorized-testing disclaimers to all offensive skills
- Complete 11 incomplete skill directories
- Expand 10 stub SKILL.md files with full content
- Fix 2 YAML parse errors in frontmatter
- Fix 5 pre-existing syntax errors
- Convert 22 hardcoded paths/ports to environment variables
- Back up 21 redundant skill pairs to .bak
- Fix 2 global declaration errors
- 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE)
- 0 compile errors across all 724 agent.py files
2026-03-19 13:26:49 +01:00

246 lines
9.4 KiB
Python

#!/usr/bin/env python3
"""Splunk SOAR (Phantom) automation agent for playbook management."""
import json
import sys
import argparse
from datetime import datetime
try:
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
except ImportError:
print("Install requests: pip install requests")
sys.exit(1)
class SplunkSOARClient:
"""Client for Splunk SOAR (Phantom) REST API."""
def __init__(self, base_url, auth_token, verify_ssl=False):
self.base_url = base_url.rstrip("/")
self.session = requests.Session()
self.session.headers.update({
"ph-auth-token": auth_token,
"Content-Type": "application/json",
})
self.session.verify = verify_ssl
def _get(self, endpoint, params=None):
resp = self.session.get(f"{self.base_url}/rest{endpoint}", params=params, timeout=30)
resp.raise_for_status()
return resp.json()
def _post(self, endpoint, data=None):
resp = self.session.post(f"{self.base_url}/rest{endpoint}", json=data, timeout=30)
resp.raise_for_status()
return resp.json()
def list_playbooks(self, page_size=50):
"""List all configured playbooks."""
return self._get("/playbook", params={"page_size": page_size})
def get_playbook(self, playbook_id):
"""Get details of a specific playbook."""
return self._get(f"/playbook/{playbook_id}")
def run_playbook(self, playbook_id, container_id, scope="all"):
"""Execute a playbook against a container."""
return self._post("/playbook_run", data={
"playbook_id": playbook_id,
"container_id": container_id,
"scope": scope,
})
def list_containers(self, label=None, status=None, page_size=50):
"""List containers (incidents/events)."""
params = {"page_size": page_size, "sort": "id", "order": "desc"}
if label:
params["_filter_label"] = f'"{label}"'
if status:
params["_filter_status"] = f'"{status}"'
return self._get("/container", params=params)
def create_container(self, name, label, severity, description=""):
"""Create a new container for an incident."""
return self._post("/container", data={
"name": name, "label": label,
"severity": severity, "description": description,
"status": "new",
})
def add_artifact(self, container_id, name, cef_data, label="event"):
"""Add an artifact (IOC) to a container."""
return self._post("/artifact", data={
"container_id": container_id,
"name": name,
"label": label,
"cef": cef_data,
"severity": "medium",
})
def list_apps(self):
"""List installed apps (connectors)."""
return self._get("/app")
def list_assets(self):
"""List configured assets."""
return self._get("/asset")
def get_action_results(self, action_run_id):
"""Get results of an action run."""
return self._get(f"/action_run/{action_run_id}")
def run_action(self, action_name, app_id, asset_id, parameters, container_id):
"""Run an action via an app connector."""
return self._post("/action_run", data={
"action": action_name,
"app_id": app_id,
"asset_id": asset_id,
"container_id": container_id,
"parameters": [parameters],
})
def get_system_info(self):
"""Get SOAR system information."""
return self._get("/system_info")
def list_users(self):
"""List SOAR users."""
return self._get("/ph_user")
def create_phishing_response_playbook_data():
"""Generate phishing response playbook configuration."""
return {
"name": "Phishing Investigation and Response",
"description": "Automated phishing email triage and response",
"steps": [
{"action": "file_reputation", "app": "VirusTotal",
"description": "Check attachment hash against VT"},
{"action": "url_reputation", "app": "VirusTotal",
"description": "Check URLs in email against VT"},
{"action": "domain_reputation", "app": "VirusTotal",
"description": "Check sender domain reputation"},
{"action": "whois_domain", "app": "WHOIS",
"description": "WHOIS lookup on sender domain"},
{"action": "hunt_email", "app": "Exchange",
"description": "Search for same email across mailboxes"},
{"action": "decision_gate", "type": "prompt",
"description": "Analyst reviews enrichment and decides"},
{"action": "quarantine_email", "app": "Exchange",
"description": "Quarantine email from all mailboxes"},
{"action": "block_sender", "app": "Firewall",
"description": "Block sender IP/domain on email gateway"},
{"action": "create_ticket", "app": "ServiceNow",
"description": "Create incident ticket for tracking"},
],
}
def create_malware_containment_playbook_data():
"""Generate malware containment playbook configuration."""
return {
"name": "Malware Containment and Remediation",
"steps": [
{"action": "get_process_info", "app": "CrowdStrike",
"description": "Get process details from EDR"},
{"action": "file_reputation", "app": "VirusTotal",
"description": "Check file hash reputation"},
{"action": "detonate_file", "app": "Sandbox",
"description": "Detonate in sandbox if unknown"},
{"action": "decision_gate", "type": "prompt",
"description": "Analyst approves containment"},
{"action": "contain_device", "app": "CrowdStrike",
"description": "Network isolate the endpoint"},
{"action": "disable_user", "app": "ActiveDirectory",
"description": "Disable compromised user account"},
{"action": "create_ticket", "app": "ServiceNow",
"description": "Create P1 incident ticket"},
],
}
def run_soar_audit(client):
"""Run SOAR platform audit."""
print(f"\n{'='*60}")
print(f" SPLUNK SOAR (PHANTOM) AUDIT")
print(f" Generated: {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')} UTC")
print(f"{'='*60}\n")
try:
sys_info = client.get_system_info()
print(f"--- SYSTEM INFO ---")
print(f" Version: {sys_info.get('version', 'N/A')}")
print(f" Build: {sys_info.get('build', 'N/A')}")
except Exception as e:
print(f" System info unavailable: {e}")
playbooks = client.list_playbooks()
pb_data = playbooks.get("data", [])
print(f"\n--- PLAYBOOKS ({len(pb_data)}) ---")
for pb in pb_data[:15]:
status = "ACTIVE" if pb.get("active") else "INACTIVE"
print(f" [{status}] {pb.get('name', 'N/A')} (ID: {pb.get('id')})")
apps = client.list_apps()
app_data = apps.get("data", [])
print(f"\n--- INSTALLED APPS ({len(app_data)}) ---")
for app in app_data[:15]:
print(f" {app.get('name', 'N/A')} v{app.get('app_version', 'N/A')}")
assets = client.list_assets()
asset_data = assets.get("data", [])
print(f"\n--- CONFIGURED ASSETS ({len(asset_data)}) ---")
for asset in asset_data[:10]:
print(f" {asset.get('name', 'N/A')} -> {asset.get('product_name', 'N/A')}")
containers = client.list_containers(status="open")
ct_data = containers.get("data", [])
print(f"\n--- OPEN CONTAINERS ({len(ct_data)}) ---")
for ct in ct_data[:10]:
print(f" [{ct.get('severity', 'N/A')}] {ct.get('name', 'N/A')} (Status: {ct.get('status')})")
print(f"\n--- PLAYBOOK TEMPLATES ---")
phishing = create_phishing_response_playbook_data()
print(f" {phishing['name']}: {len(phishing['steps'])} steps")
malware = create_malware_containment_playbook_data()
print(f" {malware['name']}: {len(malware['steps'])} steps")
print(f"\n{'='*60}\n")
return {"playbooks": len(pb_data), "apps": len(app_data), "containers": len(ct_data)}
def main():
parser = argparse.ArgumentParser(description="Splunk SOAR Automation Agent")
parser.add_argument("--url", required=True, help="SOAR instance URL")
parser.add_argument("--token", required=True, help="SOAR auth token")
parser.add_argument("--audit", action="store_true", help="Run SOAR audit")
parser.add_argument("--list-playbooks", action="store_true")
parser.add_argument("--run-playbook", nargs=2, metavar=("PB_ID", "CONTAINER_ID"),
help="Run playbook on container")
parser.add_argument("--output", help="Save report to JSON")
args = parser.parse_args()
client = SplunkSOARClient(args.url, args.token)
if args.audit:
report = run_soar_audit(client)
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
elif args.list_playbooks:
pb = client.list_playbooks()
for p in pb.get("data", []):
print(f" [{p.get('id')}] {p.get('name')}")
elif args.run_playbook:
result = client.run_playbook(int(args.run_playbook[0]), int(args.run_playbook[1]))
print(json.dumps(result, indent=2))
else:
parser.print_help()
if __name__ == "__main__":
main()