mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-05 23:38:57 +03:00
c21af3347e
- Add scripts/agent.py and references/api-reference.md to all remaining skills - Update all 648 LICENSE files: copyright now reads 'Mahipal' - Add implementing-security-monitoring-with-datadog (new skill with full anatomy) - All 649 skills now have: SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
142 lines
4.8 KiB
Python
142 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Palo Alto Prisma Access zero trust deployment audit agent."""
|
|
|
|
import json
|
|
import sys
|
|
import argparse
|
|
from datetime import datetime
|
|
|
|
try:
|
|
import requests
|
|
except ImportError:
|
|
print("Install: pip install requests")
|
|
sys.exit(1)
|
|
|
|
|
|
class PrismaAccessClient:
|
|
"""Client for Prisma Access Cloud Management API."""
|
|
|
|
def __init__(self, tsg_id, client_id, client_secret):
|
|
self.base_url = "https://api.sase.paloaltonetworks.com"
|
|
self.tsg_id = tsg_id
|
|
self.token = self._authenticate(client_id, client_secret)
|
|
|
|
def _authenticate(self, client_id, client_secret):
|
|
resp = requests.post(
|
|
"https://auth.apps.paloaltonetworks.com/oauth2/access_token",
|
|
data={
|
|
"grant_type": "client_credentials",
|
|
"scope": f"tsg_id:{self.tsg_id}",
|
|
},
|
|
auth=(client_id, client_secret),
|
|
timeout=15,
|
|
)
|
|
resp.raise_for_status()
|
|
return resp.json()["access_token"]
|
|
|
|
def _get(self, path, params=None):
|
|
headers = {"Authorization": f"Bearer {self.token}"}
|
|
resp = requests.get(f"{self.base_url}{path}", headers=headers,
|
|
params=params, timeout=15)
|
|
resp.raise_for_status()
|
|
return resp.json()
|
|
|
|
def list_remote_networks(self):
|
|
return self._get("/sse/config/v1/remote-networks").get("data", [])
|
|
|
|
def list_service_connections(self):
|
|
return self._get("/sse/config/v1/service-connections").get("data", [])
|
|
|
|
def list_ike_gateways(self):
|
|
return self._get("/sse/config/v1/ike-gateways").get("data", [])
|
|
|
|
def list_security_rules(self):
|
|
return self._get("/sse/config/v1/security-rules").get("data", [])
|
|
|
|
def list_hip_profiles(self):
|
|
return self._get("/sse/config/v1/hip-profiles").get("data", [])
|
|
|
|
def get_mobile_users_config(self):
|
|
return self._get("/sse/config/v1/mobile-agent/global-settings").get("data", {})
|
|
|
|
|
|
def audit_security_rules(rules):
|
|
"""Check for overly permissive security rules."""
|
|
findings = []
|
|
for rule in rules:
|
|
if rule.get("action") == "allow":
|
|
src = rule.get("source", [])
|
|
dst = rule.get("destination", [])
|
|
if "any" in src and "any" in dst:
|
|
findings.append({
|
|
"rule": rule.get("name", ""),
|
|
"issue": "Allow-any-to-any rule detected",
|
|
"severity": "HIGH",
|
|
})
|
|
if not rule.get("log_end", False):
|
|
findings.append({
|
|
"rule": rule.get("name", ""),
|
|
"issue": "Logging not enabled on rule",
|
|
"severity": "MEDIUM",
|
|
})
|
|
return findings
|
|
|
|
|
|
def run_audit(tsg_id, client_id, client_secret):
|
|
"""Execute Prisma Access zero trust audit."""
|
|
print(f"\n{'='*60}")
|
|
print(f" PRISMA ACCESS ZERO TRUST AUDIT")
|
|
print(f" Generated: {datetime.utcnow().isoformat()} UTC")
|
|
print(f"{'='*60}\n")
|
|
|
|
client = PrismaAccessClient(tsg_id, client_id, client_secret)
|
|
report = {}
|
|
|
|
networks = client.list_remote_networks()
|
|
report["remote_networks"] = len(networks)
|
|
print(f"--- REMOTE NETWORKS ({len(networks)}) ---")
|
|
for n in networks[:10]:
|
|
print(f" {n.get('name', '')}: region={n.get('region', '')}")
|
|
|
|
connections = client.list_service_connections()
|
|
report["service_connections"] = len(connections)
|
|
print(f"\n--- SERVICE CONNECTIONS ({len(connections)}) ---")
|
|
for c in connections[:10]:
|
|
print(f" {c.get('name', '')}: {c.get('ipsec_tunnel', '')}")
|
|
|
|
rules = client.list_security_rules()
|
|
findings = audit_security_rules(rules)
|
|
report["security_rules"] = len(rules)
|
|
report["findings"] = findings
|
|
print(f"\n--- SECURITY RULES ({len(rules)}) ---")
|
|
print(f" Findings: {len(findings)}")
|
|
for f in findings[:10]:
|
|
print(f" [{f['severity']}] {f['rule']}: {f['issue']}")
|
|
|
|
hip = client.list_hip_profiles()
|
|
report["hip_profiles"] = len(hip)
|
|
print(f"\n--- HIP PROFILES ({len(hip)}) ---")
|
|
for h in hip[:5]:
|
|
print(f" {h.get('name', '')}")
|
|
|
|
return report
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Prisma Access Zero Trust Audit")
|
|
parser.add_argument("--tsg-id", required=True, help="Tenant Service Group ID")
|
|
parser.add_argument("--client-id", required=True, help="OAuth client ID")
|
|
parser.add_argument("--client-secret", required=True, help="OAuth client secret")
|
|
parser.add_argument("--output", help="Save report to JSON file")
|
|
args = parser.parse_args()
|
|
|
|
report = run_audit(args.tsg_id, args.client_id, args.client_secret)
|
|
if args.output:
|
|
with open(args.output, "w") as f:
|
|
json.dump(report, f, indent=2, default=str)
|
|
print(f"\n[+] Report saved to {args.output}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|