mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-10 21:24:56 +03:00
163 lines
5.5 KiB
Python
163 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
AWS Macie Data Classification Management Script
|
|
|
|
Automates Macie configuration, job creation, and findings analysis.
|
|
"""
|
|
|
|
import boto3
|
|
import json
|
|
import sys
|
|
from datetime import datetime
|
|
|
|
|
|
def enable_macie(session):
|
|
"""Enable Macie in the current account."""
|
|
client = session.client('macie2')
|
|
try:
|
|
client.enable_macie(status='ENABLED')
|
|
print("[+] Macie enabled successfully")
|
|
except client.exceptions.ConflictException:
|
|
print("[*] Macie is already enabled")
|
|
|
|
# Enable automated discovery
|
|
try:
|
|
client.update_automated_discovery_configuration(status='ENABLED')
|
|
print("[+] Automated discovery enabled")
|
|
except Exception as e:
|
|
print(f"[!] Could not enable automated discovery: {e}")
|
|
|
|
|
|
def create_classification_job(session, bucket_names, account_id, job_name=None):
|
|
"""Create a one-time classification job for specified buckets."""
|
|
client = session.client('macie2')
|
|
|
|
if not job_name:
|
|
job_name = f"scan-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
|
|
|
|
response = client.create_classification_job(
|
|
jobType='ONE_TIME',
|
|
name=job_name,
|
|
s3JobDefinition={
|
|
'bucketDefinitions': [{
|
|
'accountId': account_id,
|
|
'buckets': bucket_names
|
|
}]
|
|
},
|
|
managedDataIdentifierSelector='ALL'
|
|
)
|
|
|
|
job_id = response['jobId']
|
|
print(f"[+] Classification job created: {job_id}")
|
|
return job_id
|
|
|
|
|
|
def list_findings(session, severity=None, max_results=25):
|
|
"""List Macie findings with optional severity filter."""
|
|
client = session.client('macie2')
|
|
|
|
criteria = {}
|
|
if severity:
|
|
criteria['severity.description'] = {'eq': [severity]}
|
|
|
|
response = client.list_findings(
|
|
findingCriteria={'criterion': criteria} if criteria else {},
|
|
sortCriteria={'attributeName': 'updatedAt', 'orderBy': 'DESC'},
|
|
maxResults=max_results
|
|
)
|
|
|
|
finding_ids = response.get('findingIds', [])
|
|
print(f"[+] Found {len(finding_ids)} findings")
|
|
|
|
if finding_ids:
|
|
details = client.get_findings(findingIds=finding_ids[:20])
|
|
for finding in details.get('findings', []):
|
|
severity_desc = finding['severity']['description']
|
|
category = finding.get('category', 'N/A')
|
|
title = finding.get('title', 'N/A')
|
|
bucket = finding.get('resourcesAffected', {}).get('s3Bucket', {}).get('name', 'N/A')
|
|
print(f" [{severity_desc}] {title}")
|
|
print(f" Bucket: {bucket} | Category: {category}")
|
|
|
|
return finding_ids
|
|
|
|
|
|
def get_bucket_statistics(session):
|
|
"""Get Macie statistics for all monitored S3 buckets."""
|
|
client = session.client('macie2')
|
|
|
|
response = client.describe_buckets(
|
|
criteria={},
|
|
maxResults=50
|
|
)
|
|
|
|
buckets = response.get('buckets', [])
|
|
print(f"\n[+] Monitoring {len(buckets)} S3 buckets:")
|
|
print(f"{'Bucket':<40} {'Encryption':<15} {'Public':<10} {'Shared':<10} {'Objects':<10}")
|
|
print("-" * 85)
|
|
|
|
for bucket in buckets:
|
|
name = bucket.get('bucketName', 'N/A')
|
|
encryption = bucket.get('serverSideEncryption', {}).get('type', 'NONE')
|
|
public_access = bucket.get('publicAccess', {}).get('effectivePermission', 'NOT_PUBLIC')
|
|
shared = bucket.get('sharedAccess', 'NOT_SHARED')
|
|
obj_count = bucket.get('objectCount', 0)
|
|
|
|
public_flag = "YES" if public_access == "PUBLIC" else "NO"
|
|
shared_flag = "YES" if shared != "NOT_SHARED" else "NO"
|
|
|
|
print(f"{name:<40} {encryption:<15} {public_flag:<10} {shared_flag:<10} {obj_count:<10}")
|
|
|
|
return buckets
|
|
|
|
|
|
def get_usage_stats(session):
|
|
"""Get Macie usage statistics."""
|
|
client = session.client('macie2')
|
|
|
|
response = client.get_usage_totals()
|
|
usage = response.get('usageTotals', [])
|
|
|
|
print("\n[+] Macie Usage Statistics:")
|
|
for item in usage:
|
|
usage_type = item.get('type', 'N/A')
|
|
amount = item.get('estimatedCost', 0)
|
|
currency = item.get('currency', 'USD')
|
|
print(f" {usage_type}: ${amount:.2f} {currency}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(description="AWS Macie Management")
|
|
parser.add_argument("--enable", action="store_true", help="Enable Macie")
|
|
parser.add_argument("--scan", nargs="+", help="Create scan job for buckets")
|
|
parser.add_argument("--account-id", type=str, help="AWS account ID for scan")
|
|
parser.add_argument("--findings", action="store_true", help="List findings")
|
|
parser.add_argument("--severity", type=str, choices=["Low", "Medium", "High"], help="Filter by severity")
|
|
parser.add_argument("--buckets", action="store_true", help="Show bucket statistics")
|
|
parser.add_argument("--usage", action="store_true", help="Show usage statistics")
|
|
parser.add_argument("--region", type=str, default="us-east-1", help="AWS region")
|
|
parser.add_argument("--profile", type=str, help="AWS profile name")
|
|
|
|
args = parser.parse_args()
|
|
|
|
session_kwargs = {"region_name": args.region}
|
|
if args.profile:
|
|
session_kwargs["profile_name"] = args.profile
|
|
session = boto3.Session(**session_kwargs)
|
|
|
|
if args.enable:
|
|
enable_macie(session)
|
|
if args.scan:
|
|
if not args.account_id:
|
|
sts = session.client('sts')
|
|
args.account_id = sts.get_caller_identity()['Account']
|
|
create_classification_job(session, args.scan, args.account_id)
|
|
if args.findings:
|
|
list_findings(session, severity=args.severity)
|
|
if args.buckets:
|
|
get_bucket_statistics(session)
|
|
if args.usage:
|
|
get_usage_stats(session)
|