mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-17 05:05:16 +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,140 @@
|
||||
#!/usr/bin/env python3
|
||||
"""AWS IAM permission boundary management agent using boto3."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
try:
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
except ImportError:
|
||||
sys.exit("boto3 required: pip install boto3")
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_iam_client(profile: str = "", region: str = "us-east-1"):
|
||||
"""Create IAM client with optional profile."""
|
||||
session = boto3.Session(profile_name=profile) if profile else boto3.Session()
|
||||
return session.client("iam", region_name=region)
|
||||
|
||||
|
||||
def create_permission_boundary(client, policy_name: str, allowed_services: List[str],
|
||||
allowed_regions: List[str] = None) -> dict:
|
||||
"""Create a permission boundary policy restricting services and regions."""
|
||||
statements = [{
|
||||
"Sid": "AllowedServices",
|
||||
"Effect": "Allow",
|
||||
"Action": [f"{svc}:*" for svc in allowed_services],
|
||||
"Resource": "*",
|
||||
}]
|
||||
if allowed_regions:
|
||||
statements[0]["Condition"] = {
|
||||
"StringEquals": {"aws:RequestedRegion": allowed_regions}
|
||||
}
|
||||
statements.append({
|
||||
"Sid": "DenyBoundaryChanges",
|
||||
"Effect": "Deny",
|
||||
"Action": ["iam:DeleteRolePermissionsBoundary", "iam:PutRolePermissionsBoundary"],
|
||||
"Resource": "*",
|
||||
})
|
||||
policy_doc = {"Version": "2012-10-17", "Statement": statements}
|
||||
try:
|
||||
resp = client.create_policy(
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=json.dumps(policy_doc),
|
||||
Description=f"Permission boundary: {', '.join(allowed_services)}",
|
||||
)
|
||||
arn = resp["Policy"]["Arn"]
|
||||
logger.info("Created boundary policy: %s", arn)
|
||||
return {"policy_arn": arn, "policy_document": policy_doc}
|
||||
except ClientError as exc:
|
||||
return {"error": str(exc)}
|
||||
|
||||
|
||||
def attach_boundary_to_role(client, role_name: str, boundary_arn: str) -> dict:
|
||||
"""Attach permission boundary to an IAM role."""
|
||||
try:
|
||||
client.put_role_permissions_boundary(
|
||||
RoleName=role_name, PermissionsBoundary=boundary_arn)
|
||||
logger.info("Attached boundary %s to role %s", boundary_arn, role_name)
|
||||
return {"role": role_name, "boundary_arn": boundary_arn, "attached": True}
|
||||
except ClientError as exc:
|
||||
return {"role": role_name, "error": str(exc)}
|
||||
|
||||
|
||||
def audit_roles_without_boundary(client) -> List[dict]:
|
||||
"""Find IAM roles that lack a permission boundary."""
|
||||
paginator = client.get_paginator("list_roles")
|
||||
unbounded = []
|
||||
for page in paginator.paginate():
|
||||
for role in page["Roles"]:
|
||||
if "PermissionsBoundary" not in role:
|
||||
unbounded.append({
|
||||
"role_name": role["RoleName"],
|
||||
"arn": role["Arn"],
|
||||
"created": role["CreateDate"].isoformat(),
|
||||
})
|
||||
logger.info("Found %d roles without permission boundary", len(unbounded))
|
||||
return unbounded
|
||||
|
||||
|
||||
def audit_boundary_effectiveness(client, role_name: str) -> dict:
|
||||
"""Audit effective permissions for a role with boundary."""
|
||||
try:
|
||||
role = client.get_role(RoleName=role_name)["Role"]
|
||||
boundary = role.get("PermissionsBoundary", {})
|
||||
policies_resp = client.list_attached_role_policies(RoleName=role_name)
|
||||
inline_resp = client.list_role_policies(RoleName=role_name)
|
||||
return {
|
||||
"role": role_name,
|
||||
"boundary_arn": boundary.get("PermissionsBoundaryArn", "NONE"),
|
||||
"attached_policies": [p["PolicyName"] for p in policies_resp["AttachedPolicies"]],
|
||||
"inline_policies": inline_resp["PolicyNames"],
|
||||
}
|
||||
except ClientError as exc:
|
||||
return {"role": role_name, "error": str(exc)}
|
||||
|
||||
|
||||
def generate_report(client) -> dict:
|
||||
"""Generate permission boundary compliance report."""
|
||||
unbounded = audit_roles_without_boundary(client)
|
||||
report = {
|
||||
"analysis_date": datetime.utcnow().isoformat(),
|
||||
"roles_without_boundary": unbounded,
|
||||
"roles_without_boundary_count": len(unbounded),
|
||||
"recommendations": [],
|
||||
}
|
||||
if unbounded:
|
||||
report["recommendations"].append(
|
||||
f"Attach permission boundaries to {len(unbounded)} roles lacking boundaries")
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="AWS IAM Permission Boundary Agent")
|
||||
parser.add_argument("--profile", default="", help="AWS CLI profile name")
|
||||
parser.add_argument("--region", default="us-east-1")
|
||||
parser.add_argument("--audit", action="store_true", help="Audit roles without boundaries")
|
||||
parser.add_argument("--output-dir", default=".")
|
||||
parser.add_argument("--output", default="iam_boundary_report.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
os.makedirs(args.output_dir, exist_ok=True)
|
||||
client = get_iam_client(args.profile, args.region)
|
||||
report = generate_report(client)
|
||||
out_path = os.path.join(args.output_dir, args.output)
|
||||
with open(out_path, "w") as f:
|
||||
json.dump(report, f, indent=2, default=str)
|
||||
logger.info("Report saved to %s", out_path)
|
||||
print(json.dumps(report, indent=2, default=str))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user