Files
mukul975 27c6414ca5 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
2026-03-10 21:02:12 +01:00

182 lines
6.8 KiB
Python

#!/usr/bin/env python3
"""AWS Security Hub CSPM agent using boto3 securityhub client."""
import json
import sys
import argparse
from datetime import datetime
from collections import Counter
try:
import boto3
from botocore.exceptions import ClientError
except ImportError:
print("Install boto3: pip install boto3")
sys.exit(1)
def get_hub_client(region="us-east-1"):
"""Create Security Hub client."""
return boto3.client("securityhub", region_name=region)
def enable_security_hub(client):
"""Enable Security Hub with default standards."""
try:
client.enable_security_hub(EnableDefaultStandards=True,
Tags={"ManagedBy": "security-agent"})
return {"status": "enabled"}
except ClientError as e:
if "already enabled" in str(e).lower():
return {"status": "already_enabled"}
return {"error": str(e)}
def enable_standards(client, standards):
"""Enable specific compliance standards."""
standard_arns = {
"cis": "arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/5.0.0",
"fsbp": "arn:aws:securityhub:{region}::standards/aws-foundational-security-best-practices/v/1.0.0",
"pci": "arn:aws:securityhub:{region}::standards/pci-dss/v/3.2.1",
"nist": "arn:aws:securityhub:{region}::standards/nist-800-53/v/5.0.0",
}
region = client.meta.region_name
requests = []
for s in standards:
if s in standard_arns:
arn = standard_arns[s].replace("{region}", region)
requests.append({"StandardsArn": arn})
if requests:
try:
resp = client.batch_enable_standards(StandardsSubscriptionRequests=requests)
return [{"arn": s["StandardsArn"], "status": s["StandardsStatus"]}
for s in resp.get("StandardsSubscriptions", [])]
except ClientError as e:
return [{"error": str(e)}]
return []
def get_enabled_standards(client):
"""List all enabled security standards and their status."""
try:
resp = client.get_enabled_standards()
return [{"arn": s["StandardsArn"], "status": s["StandardsStatus"]}
for s in resp.get("StandardsSubscriptions", [])]
except ClientError as e:
return [{"error": str(e)}]
def get_findings_summary(client, max_results=100):
"""Retrieve active findings grouped by severity."""
try:
resp = client.get_findings(
Filters={"RecordState": [{"Value": "ACTIVE", "Comparison": "EQUALS"}],
"WorkflowStatus": [{"Value": "NEW", "Comparison": "EQUALS"}]},
SortCriteria=[{"Field": "SeverityNormalized", "SortOrder": "desc"}],
MaxResults=max_results)
findings = resp.get("Findings", [])
severity_counts = Counter(f["Severity"]["Label"] for f in findings)
failed_controls = Counter()
for f in findings:
if f.get("Compliance", {}).get("Status") == "FAILED":
failed_controls[f.get("Title", "Unknown")] += 1
return {"total": len(findings), "by_severity": dict(severity_counts),
"top_failed_controls": dict(failed_controls.most_common(10)),
"findings": findings}
except ClientError as e:
return {"error": str(e)}
def get_compliance_scores(client):
"""Get compliance scores for all enabled standards."""
standards = get_enabled_standards(client)
scores = []
for std in standards:
if "error" in std:
continue
scores.append({"standard": std["arn"].split("/")[-3] if "/" in std["arn"] else std["arn"],
"status": std["status"]})
return scores
def create_custom_insight(client, name, group_by, filters):
"""Create a custom Security Hub insight."""
try:
resp = client.create_insight(Name=name, Filters=filters, GroupByAttribute=group_by)
return {"insight_arn": resp["InsightArn"], "status": "created"}
except ClientError as e:
return {"error": str(e)}
def batch_update_findings(client, finding_ids, workflow_status, note):
"""Update findings workflow status in batch."""
identifiers = [{"Id": fid["Id"], "ProductArn": fid["ProductArn"]} for fid in finding_ids]
try:
client.batch_update_findings(
FindingIdentifiers=identifiers,
Workflow={"Status": workflow_status},
Note={"Text": note, "UpdatedBy": "security-hub-agent"})
return {"updated": len(identifiers), "status": workflow_status}
except ClientError as e:
return {"error": str(e)}
def run_security_hub_audit(region="us-east-1"):
"""Run a full Security Hub audit and print report."""
client = get_hub_client(region)
print(f"\n{'='*60}")
print(f" AWS SECURITY HUB AUDIT REPORT")
print(f" Region: {region}")
print(f" Generated: {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')} UTC")
print(f"{'='*60}\n")
standards = get_enabled_standards(client)
print(f"--- ENABLED STANDARDS ({len(standards)}) ---")
for s in standards:
print(f" {s.get('arn', 'N/A')}: {s.get('status', 'N/A')}")
summary = get_findings_summary(client)
print(f"\n--- FINDINGS SUMMARY ---")
print(f" Total Active: {summary.get('total', 0)}")
for sev, count in summary.get("by_severity", {}).items():
print(f" {sev}: {count}")
print(f"\n--- TOP FAILED CONTROLS ---")
for control, count in summary.get("top_failed_controls", {}).items():
print(f" [{count:3d}] {control[:70]}")
print(f"\n{'='*60}\n")
return {"standards": standards, "findings": summary}
def main():
parser = argparse.ArgumentParser(description="AWS Security Hub Agent")
parser.add_argument("--region", default="us-east-1", help="AWS region")
parser.add_argument("--enable", action="store_true", help="Enable Security Hub")
parser.add_argument("--standards", nargs="+", choices=["cis", "fsbp", "pci", "nist"],
help="Enable specific standards")
parser.add_argument("--audit", action="store_true", help="Run Security Hub audit")
parser.add_argument("--output", help="Save report to JSON")
args = parser.parse_args()
if args.enable:
result = enable_security_hub(get_hub_client(args.region))
print(f"Security Hub: {result}")
if args.standards:
results = enable_standards(get_hub_client(args.region), args.standards)
for r in results:
print(f" Standard: {r}")
if args.audit:
report = run_security_hub_audit(args.region)
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
print(f"[+] Report saved to {args.output}")
if not any([args.enable, args.standards, args.audit]):
parser.print_help()
if __name__ == "__main__":
main()