mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-16 12:45:17 +03:00
Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills
Complete skill folder anatomy across all cybersecurity skills: - scripts/agent.py: 80-150 line Python agents using real libraries (impacket, boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.) - references/api-reference.md: real API documentation with method signatures - LICENSE: MIT license for all skill folders
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for monitoring and managing Microsoft Defender for Cloud security posture."""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import sys
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def run_az_command(args_list):
|
||||
"""Execute an Azure CLI command and return parsed JSON output."""
|
||||
cmd = ["az"] + args_list + ["--output", "json"]
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
|
||||
if result.returncode != 0:
|
||||
print(f" [-] Error: {result.stderr.strip()}")
|
||||
return None
|
||||
return json.loads(result.stdout) if result.stdout.strip() else None
|
||||
except (subprocess.TimeoutExpired, json.JSONDecodeError) as e:
|
||||
print(f" [-] Command failed: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def get_defender_plans():
|
||||
"""List all Defender for Cloud pricing plans and their status."""
|
||||
print("[*] Checking Defender for Cloud plan status...")
|
||||
plans = run_az_command(["security", "pricing", "list"])
|
||||
if not plans:
|
||||
return []
|
||||
enabled = []
|
||||
for plan in plans:
|
||||
tier = plan.get("pricingTier", "Free")
|
||||
name = plan.get("name", "Unknown")
|
||||
sub_plan = plan.get("subPlan", "")
|
||||
status = "ENABLED" if tier == "Standard" else "FREE"
|
||||
indicator = "[+]" if tier == "Standard" else "[-]"
|
||||
sub_info = f" ({sub_plan})" if sub_plan else ""
|
||||
print(f" {indicator} {name}: {status}{sub_info}")
|
||||
if tier == "Standard":
|
||||
enabled.append({"name": name, "tier": tier, "subPlan": sub_plan})
|
||||
print(f"[*] {len(enabled)} plans enabled out of {len(plans)} total")
|
||||
return enabled
|
||||
|
||||
|
||||
def get_secure_score():
|
||||
"""Retrieve the current Secure Score across subscriptions."""
|
||||
print("\n[*] Fetching Secure Score...")
|
||||
scores = run_az_command(["security", "secure-score", "list"])
|
||||
if not scores:
|
||||
return {}
|
||||
for score in scores:
|
||||
current = score.get("current", 0)
|
||||
maximum = score.get("max", 0)
|
||||
pct = round((current / maximum * 100), 1) if maximum > 0 else 0
|
||||
print(f" Score: {current}/{maximum} ({pct}%)")
|
||||
return scores
|
||||
|
||||
|
||||
def get_security_assessments(severity_filter=None):
|
||||
"""List security assessments and their health status."""
|
||||
print("\n[*] Fetching security assessments...")
|
||||
assessments = run_az_command(["security", "assessment", "list"])
|
||||
if not assessments:
|
||||
return []
|
||||
unhealthy = []
|
||||
for a in assessments:
|
||||
props = a.get("properties", {})
|
||||
status = props.get("status", {}).get("code", "")
|
||||
if status == "Unhealthy":
|
||||
sev = props.get("metadata", {}).get("severity", "Unknown")
|
||||
display = props.get("displayName", "Unknown")
|
||||
if severity_filter and sev.lower() != severity_filter.lower():
|
||||
continue
|
||||
unhealthy.append({"name": display, "severity": sev, "status": status})
|
||||
print(f" [{sev.upper()}] {display}")
|
||||
print(f"[*] {len(unhealthy)} unhealthy assessments found")
|
||||
return unhealthy
|
||||
|
||||
|
||||
def get_security_alerts(days=7):
|
||||
"""Retrieve recent security alerts from Defender for Cloud."""
|
||||
print(f"\n[*] Fetching security alerts (last {days} days)...")
|
||||
alerts = run_az_command(["security", "alert", "list"])
|
||||
if not alerts:
|
||||
return []
|
||||
severity_counts = {"High": 0, "Medium": 0, "Low": 0, "Informational": 0}
|
||||
active_alerts = []
|
||||
for alert in alerts:
|
||||
props = alert.get("properties", {})
|
||||
status = props.get("status", "")
|
||||
if status in ("Active", "InProgress"):
|
||||
sev = props.get("severity", "Unknown")
|
||||
severity_counts[sev] = severity_counts.get(sev, 0) + 1
|
||||
active_alerts.append({
|
||||
"name": props.get("alertDisplayName", "Unknown"),
|
||||
"severity": sev,
|
||||
"status": status,
|
||||
"timestamp": props.get("timeGeneratedUtc", ""),
|
||||
})
|
||||
for sev, count in severity_counts.items():
|
||||
if count > 0:
|
||||
print(f" [{sev}] {count} alerts")
|
||||
return active_alerts
|
||||
|
||||
|
||||
def check_security_contacts():
|
||||
"""Verify security contact configuration for alert notifications."""
|
||||
print("\n[*] Checking security contact configuration...")
|
||||
contacts = run_az_command(["security", "contact", "list"])
|
||||
if not contacts:
|
||||
print(" [!] No security contacts configured")
|
||||
return False
|
||||
for contact in contacts:
|
||||
email = contact.get("email", "Not set")
|
||||
alerts = contact.get("alertNotifications", "off")
|
||||
print(f" Email: {email} | Alert notifications: {alerts}")
|
||||
return True
|
||||
|
||||
|
||||
def check_auto_provisioning():
|
||||
"""Check auto-provisioning settings for security agents."""
|
||||
print("\n[*] Checking auto-provisioning settings...")
|
||||
settings = run_az_command(["security", "auto-provisioning-setting", "list"])
|
||||
if not settings:
|
||||
return []
|
||||
for s in settings:
|
||||
name = s.get("name", "Unknown")
|
||||
auto_prov = s.get("autoProvision", "Off")
|
||||
indicator = "[+]" if auto_prov == "On" else "[-]"
|
||||
print(f" {indicator} {name}: {auto_prov}")
|
||||
return settings
|
||||
|
||||
|
||||
def generate_posture_report(output_path):
|
||||
"""Generate a comprehensive security posture report."""
|
||||
print("[*] Generating security posture report...")
|
||||
report = {
|
||||
"report_date": datetime.now().isoformat(),
|
||||
"defender_plans": get_defender_plans(),
|
||||
"secure_score": get_secure_score(),
|
||||
"unhealthy_assessments": get_security_assessments(),
|
||||
"active_alerts": get_security_alerts(),
|
||||
"contacts_configured": check_security_contacts(),
|
||||
"auto_provisioning": check_auto_provisioning(),
|
||||
}
|
||||
with open(output_path, "w") as f:
|
||||
json.dump(report, f, indent=2, default=str)
|
||||
print(f"\n[*] Report saved to {output_path}")
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Microsoft Defender for Cloud Security Agent")
|
||||
parser.add_argument("action", choices=["plans", "score", "assessments", "alerts",
|
||||
"contacts", "auto-provision", "full-report"])
|
||||
parser.add_argument("--severity", choices=["high", "medium", "low"], help="Filter by severity")
|
||||
parser.add_argument("--days", type=int, default=7, help="Alert lookback in days")
|
||||
parser.add_argument("-o", "--output", default="defender_report.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.action == "plans":
|
||||
get_defender_plans()
|
||||
elif args.action == "score":
|
||||
get_secure_score()
|
||||
elif args.action == "assessments":
|
||||
get_security_assessments(args.severity)
|
||||
elif args.action == "alerts":
|
||||
get_security_alerts(args.days)
|
||||
elif args.action == "contacts":
|
||||
check_security_contacts()
|
||||
elif args.action == "auto-provision":
|
||||
check_auto_provisioning()
|
||||
elif args.action == "full-report":
|
||||
generate_posture_report(args.output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user