Files
T
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

180 lines
7.0 KiB
Python

#!/usr/bin/env python3
"""AWS Security Hub compliance monitoring agent with automated remediation."""
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_clients(region="us-east-1"):
"""Create Security Hub and S3 clients."""
return (boto3.client("securityhub", region_name=region),
boto3.client("s3", region_name=region))
def get_compliance_findings(hub_client, standard_filter=None, max_results=100):
"""Get failed compliance findings, optionally filtered by standard."""
filters = {
"ComplianceStatus": [{"Value": "FAILED", "Comparison": "EQUALS"}],
"RecordState": [{"Value": "ACTIVE", "Comparison": "EQUALS"}],
"WorkflowStatus": [{"Value": "NEW", "Comparison": "EQUALS"}],
}
if standard_filter:
filters["GeneratorId"] = [{"Value": standard_filter, "Comparison": "PREFIX"}]
try:
resp = hub_client.get_findings(
Filters=filters,
SortCriteria=[{"Field": "SeverityNormalized", "SortOrder": "desc"}],
MaxResults=max_results)
return resp.get("Findings", [])
except ClientError as e:
print(f"[!] Error getting findings: {e}")
return []
def analyze_compliance_gaps(findings):
"""Analyze findings to identify compliance gaps by control and account."""
by_control = Counter()
by_severity = Counter()
by_account = Counter()
control_details = {}
for f in findings:
title = f.get("Title", "Unknown")
severity = f["Severity"]["Label"]
account = f.get("AwsAccountId", "Unknown")
by_control[title] += 1
by_severity[severity] += 1
by_account[account] += 1
if title not in control_details:
control_details[title] = {
"severity": severity,
"generator": f.get("GeneratorId", ""),
"accounts": set(),
"resource_types": set(),
}
control_details[title]["accounts"].add(account)
for r in f.get("Resources", []):
control_details[title]["resource_types"].add(r.get("Type", ""))
for k in control_details:
control_details[k]["accounts"] = list(control_details[k]["accounts"])
control_details[k]["resource_types"] = list(control_details[k]["resource_types"])
return {"by_control": dict(by_control.most_common(20)),
"by_severity": dict(by_severity), "by_account": dict(by_account.most_common(10)),
"control_details": control_details}
def remediate_s3_public_access(s3_client, bucket_name):
"""Block public access on an S3 bucket."""
try:
s3_client.put_public_access_block(
Bucket=bucket_name,
PublicAccessBlockConfiguration={
"BlockPublicAcls": True, "IgnorePublicAcls": True,
"BlockPublicPolicy": True, "RestrictPublicBuckets": True})
return {"bucket": bucket_name, "status": "remediated"}
except ClientError as e:
return {"bucket": bucket_name, "status": "error", "message": str(e)}
def auto_remediate_findings(hub_client, s3_client, findings):
"""Auto-remediate safe-to-fix findings (S3 public access)."""
remediated = []
for f in findings:
title = f.get("Title", "").lower()
if "s3" in title and "public" in title:
for r in f.get("Resources", []):
if r["Type"] == "AwsS3Bucket":
bucket = r["Id"].split(":::")[-1]
result = remediate_s3_public_access(s3_client, bucket)
if result["status"] == "remediated":
hub_client.batch_update_findings(
FindingIdentifiers=[{"Id": f["Id"], "ProductArn": f["ProductArn"]}],
Workflow={"Status": "RESOLVED"},
Note={"Text": "Auto-remediated: public access blocked",
"UpdatedBy": "compliance-agent"})
remediated.append(result)
return remediated
def create_compliance_insight(hub_client, name, group_by_attr, severity_filter=None):
"""Create a custom Security Hub insight for compliance tracking."""
filters = {"ComplianceStatus": [{"Value": "FAILED", "Comparison": "EQUALS"}]}
if severity_filter:
filters["SeverityLabel"] = [{"Value": s, "Comparison": "EQUALS"} for s in severity_filter]
try:
resp = hub_client.create_insight(Name=name, Filters=filters, GroupByAttribute=group_by_attr)
return {"insight_arn": resp["InsightArn"]}
except ClientError as e:
return {"error": str(e)}
def run_compliance_report(region="us-east-1"):
"""Generate full compliance report."""
hub_client, s3_client = get_clients(region)
print(f"\n{'='*60}")
print(f" AWS SECURITY HUB COMPLIANCE REPORT")
print(f" Region: {region}")
print(f" Generated: {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')} UTC")
print(f"{'='*60}\n")
findings = get_compliance_findings(hub_client)
analysis = analyze_compliance_gaps(findings)
print(f"--- FINDINGS BY SEVERITY ---")
for sev in ["CRITICAL", "HIGH", "MEDIUM", "LOW"]:
count = analysis["by_severity"].get(sev, 0)
bar = "#" * min(count, 40)
print(f" {sev:<12} {count:>4} {bar}")
print(f"\n--- TOP FAILED CONTROLS ---")
for control, count in list(analysis["by_control"].items())[:10]:
detail = analysis["control_details"].get(control, {})
acct_count = len(detail.get("accounts", []))
print(f" [{count:3d}] {control[:60]}")
print(f" Severity: {detail.get('severity', 'N/A')} | Accounts: {acct_count}")
print(f"\n--- TOP AFFECTED ACCOUNTS ---")
for acct, count in list(analysis["by_account"].items())[:5]:
print(f" {acct}: {count} failed controls")
print(f"\n Total failed findings: {len(findings)}")
print(f"{'='*60}\n")
return {"findings_count": len(findings), "analysis": analysis}
def main():
parser = argparse.ArgumentParser(description="AWS Security Hub Compliance Agent")
parser.add_argument("--region", default="us-east-1")
parser.add_argument("--audit", action="store_true", help="Run compliance audit")
parser.add_argument("--remediate", action="store_true", help="Auto-remediate safe findings")
parser.add_argument("--output", help="Save report to JSON")
args = parser.parse_args()
if args.audit:
report = run_compliance_report(args.region)
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
elif args.remediate:
hub, s3 = get_clients(args.region)
findings = get_compliance_findings(hub)
results = auto_remediate_findings(hub, s3, findings)
for r in results:
print(f" [{r['status']}] {r.get('bucket', 'unknown')}")
else:
parser.print_help()
if __name__ == "__main__":
main()