mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-13 19:05: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,190 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for auditing AWS S3 bucket permissions using boto3."""
|
||||
|
||||
import os
|
||||
import json
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
|
||||
def get_session(profile=None, region=None):
|
||||
"""Create a boto3 session."""
|
||||
kwargs = {}
|
||||
if profile:
|
||||
kwargs["profile_name"] = profile
|
||||
if region:
|
||||
kwargs["region_name"] = region
|
||||
return boto3.Session(**kwargs)
|
||||
|
||||
|
||||
def list_all_buckets(session):
|
||||
"""List all S3 buckets in the account."""
|
||||
s3 = session.client("s3")
|
||||
response = s3.list_buckets()
|
||||
buckets = []
|
||||
for b in response.get("Buckets", []):
|
||||
loc = s3.get_bucket_location(Bucket=b["Name"])
|
||||
region = loc.get("LocationConstraint") or "us-east-1"
|
||||
buckets.append({"name": b["Name"], "created": str(b["CreationDate"]), "region": region})
|
||||
return buckets
|
||||
|
||||
|
||||
def check_public_access_block(session, bucket_name):
|
||||
"""Check bucket-level public access block settings."""
|
||||
s3 = session.client("s3")
|
||||
try:
|
||||
response = s3.get_public_access_block(Bucket=bucket_name)
|
||||
config = response["PublicAccessBlockConfiguration"]
|
||||
return {
|
||||
"configured": True,
|
||||
"block_public_acls": config.get("BlockPublicAcls", False),
|
||||
"ignore_public_acls": config.get("IgnorePublicAcls", False),
|
||||
"block_public_policy": config.get("BlockPublicPolicy", False),
|
||||
"restrict_public_buckets": config.get("RestrictPublicBuckets", False),
|
||||
}
|
||||
except ClientError:
|
||||
return {"configured": False}
|
||||
|
||||
|
||||
def check_bucket_acl(session, bucket_name):
|
||||
"""Check bucket ACL for public grants."""
|
||||
s3 = session.client("s3")
|
||||
acl = s3.get_bucket_acl(Bucket=bucket_name)
|
||||
public_grants = []
|
||||
public_uris = [
|
||||
"http://acs.amazonaws.com/groups/global/AllUsers",
|
||||
"http://acs.amazonaws.com/groups/global/AuthenticatedUsers",
|
||||
]
|
||||
for grant in acl.get("Grants", []):
|
||||
grantee = grant.get("Grantee", {})
|
||||
if grantee.get("URI") in public_uris:
|
||||
public_grants.append({
|
||||
"grantee": grantee.get("URI"),
|
||||
"permission": grant.get("Permission"),
|
||||
})
|
||||
return public_grants
|
||||
|
||||
|
||||
def check_bucket_policy(session, bucket_name):
|
||||
"""Check bucket policy for wildcard principals."""
|
||||
s3 = session.client("s3")
|
||||
try:
|
||||
policy_str = s3.get_bucket_policy(Bucket=bucket_name)["Policy"]
|
||||
policy = json.loads(policy_str)
|
||||
issues = []
|
||||
for stmt in policy.get("Statement", []):
|
||||
principal = stmt.get("Principal", {})
|
||||
if principal == "*" or principal == {"AWS": "*"}:
|
||||
issues.append({
|
||||
"effect": stmt.get("Effect"),
|
||||
"action": stmt.get("Action"),
|
||||
"condition": stmt.get("Condition", "NONE"),
|
||||
})
|
||||
return {"has_policy": True, "wildcard_issues": issues}
|
||||
except ClientError:
|
||||
return {"has_policy": False, "wildcard_issues": []}
|
||||
|
||||
|
||||
def check_encryption(session, bucket_name):
|
||||
"""Check if default encryption is enabled."""
|
||||
s3 = session.client("s3")
|
||||
try:
|
||||
enc = s3.get_bucket_encryption(Bucket=bucket_name)
|
||||
rules = enc.get("ServerSideEncryptionConfiguration", {}).get("Rules", [])
|
||||
if rules:
|
||||
algo = rules[0].get("ApplyServerSideEncryptionByDefault", {}).get("SSEAlgorithm")
|
||||
return {"enabled": True, "algorithm": algo}
|
||||
except ClientError:
|
||||
pass
|
||||
return {"enabled": False, "algorithm": None}
|
||||
|
||||
|
||||
def check_versioning(session, bucket_name):
|
||||
"""Check if versioning is enabled."""
|
||||
s3 = session.client("s3")
|
||||
resp = s3.get_bucket_versioning(Bucket=bucket_name)
|
||||
return {"status": resp.get("Status", "Disabled")}
|
||||
|
||||
|
||||
def check_logging(session, bucket_name):
|
||||
"""Check if server access logging is enabled."""
|
||||
s3 = session.client("s3")
|
||||
resp = s3.get_bucket_logging(Bucket=bucket_name)
|
||||
enabled = "LoggingEnabled" in resp
|
||||
return {"enabled": enabled}
|
||||
|
||||
|
||||
def audit_bucket(session, bucket_name):
|
||||
"""Run full security audit on a single bucket."""
|
||||
return {
|
||||
"bucket": bucket_name,
|
||||
"public_access_block": check_public_access_block(session, bucket_name),
|
||||
"public_acl_grants": check_bucket_acl(session, bucket_name),
|
||||
"bucket_policy": check_bucket_policy(session, bucket_name),
|
||||
"encryption": check_encryption(session, bucket_name),
|
||||
"versioning": check_versioning(session, bucket_name),
|
||||
"logging": check_logging(session, bucket_name),
|
||||
}
|
||||
|
||||
|
||||
def classify_risk(audit_result):
|
||||
"""Classify risk level for a bucket based on audit findings."""
|
||||
risk = "LOW"
|
||||
if audit_result["public_acl_grants"]:
|
||||
risk = "CRITICAL"
|
||||
elif audit_result["bucket_policy"]["wildcard_issues"]:
|
||||
risk = "HIGH"
|
||||
elif not audit_result["encryption"]["enabled"]:
|
||||
risk = "MEDIUM"
|
||||
elif not audit_result["public_access_block"]["configured"]:
|
||||
risk = "MEDIUM"
|
||||
audit_result["risk_level"] = risk
|
||||
return audit_result
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="AWS S3 Bucket Permissions Audit Agent")
|
||||
parser.add_argument("--profile", default=os.getenv("AWS_PROFILE"))
|
||||
parser.add_argument("--region", default=os.getenv("AWS_DEFAULT_REGION"))
|
||||
parser.add_argument("--bucket", help="Audit a specific bucket")
|
||||
parser.add_argument("--output", default="s3_audit_report.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
session = get_session(args.profile, args.region)
|
||||
account_id = session.client("sts").get_caller_identity()["Account"]
|
||||
print(f"[+] Auditing S3 buckets in account {account_id}")
|
||||
|
||||
if args.bucket:
|
||||
buckets = [{"name": args.bucket}]
|
||||
else:
|
||||
buckets = list_all_buckets(session)
|
||||
print(f"[+] Found {len(buckets)} buckets")
|
||||
|
||||
results = []
|
||||
for b in buckets:
|
||||
name = b["name"]
|
||||
print(f" Auditing {name}...")
|
||||
audit = audit_bucket(session, name)
|
||||
audit = classify_risk(audit)
|
||||
results.append(audit)
|
||||
if audit["risk_level"] in ("CRITICAL", "HIGH"):
|
||||
print(f" [{audit['risk_level']}] {name}")
|
||||
|
||||
report = {
|
||||
"account": account_id,
|
||||
"audit_date": datetime.utcnow().isoformat(),
|
||||
"total_buckets": len(results),
|
||||
"critical": sum(1 for r in results if r["risk_level"] == "CRITICAL"),
|
||||
"high": sum(1 for r in results if r["risk_level"] == "HIGH"),
|
||||
"buckets": results,
|
||||
}
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2, default=str)
|
||||
print(f"[+] Report saved to {args.output}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user