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

231 lines
8.3 KiB
Python

#!/usr/bin/env python3
"""
AWS Penetration Testing with Pacu Agent — AUTHORIZED TESTING ONLY
Automates Pacu module execution for AWS security assessment including
IAM enumeration, privilege escalation scanning, and credential testing.
WARNING: Only use with explicit written authorization on approved AWS accounts.
"""
import json
import subprocess
import sys
from datetime import datetime, timezone
import boto3
from botocore.exceptions import ClientError
def run_pacu_module(module_name: str, session_name: str = "pentest", args: str = "") -> dict:
"""Execute a Pacu module via subprocess."""
cmd = ["pacu", "--session", session_name, "--module-name", module_name]
if args:
cmd.extend(["--module-args", args])
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
return {
"module": module_name,
"success": result.returncode == 0,
"output": result.stdout[-2000:] if result.stdout else "",
"error": result.stderr[-500:] if result.stderr else "",
}
except subprocess.TimeoutExpired:
return {"module": module_name, "success": False, "error": "Module timed out (300s)"}
except FileNotFoundError:
return {"module": module_name, "success": False, "error": "Pacu not installed. Install with: pip install pacu"}
def enumerate_iam_with_boto(profile: str = None) -> dict:
"""Fallback IAM enumeration using boto3 when Pacu is unavailable."""
session = boto3.Session(profile_name=profile) if profile else boto3.Session()
iam = session.client("iam")
sts = session.client("sts")
identity = sts.get_caller_identity()
result = {
"identity": {
"account": identity["Account"],
"arn": identity["Arn"],
},
"users": [],
"roles": [],
"policies": [],
}
try:
for page in iam.get_paginator("list_users").paginate():
for user in page["Users"]:
attached = iam.list_attached_user_policies(UserName=user["UserName"])
result["users"].append({
"username": user["UserName"],
"arn": user["Arn"],
"policies": [p["PolicyArn"] for p in attached["AttachedPolicies"]],
})
except ClientError as e:
result["users_error"] = str(e)
try:
for page in iam.get_paginator("list_roles").paginate():
for role in page["Roles"]:
result["roles"].append({
"name": role["RoleName"],
"arn": role["Arn"],
"trust_policy": role.get("AssumeRolePolicyDocument", {}),
})
except ClientError as e:
result["roles_error"] = str(e)
return result
def scan_privilege_escalation(iam_data: dict) -> list[dict]:
"""Identify privilege escalation paths from IAM enumeration data."""
escalation_vectors = []
dangerous_actions = {
"iam:CreatePolicyVersion", "iam:SetDefaultPolicyVersion",
"iam:AttachUserPolicy", "iam:AttachRolePolicy",
"iam:PutUserPolicy", "iam:PutRolePolicy",
"iam:AddUserToGroup", "iam:UpdateAssumeRolePolicy",
"iam:PassRole", "iam:CreateLoginProfile",
"lambda:CreateFunction", "lambda:UpdateFunctionCode",
}
iam_client = boto3.client("iam")
for user in iam_data.get("users", []):
user_dangerous = []
for policy_arn in user.get("policies", []):
try:
policy = iam_client.get_policy(PolicyArn=policy_arn)
version = iam_client.get_policy_version(
PolicyArn=policy_arn,
VersionId=policy["Policy"]["DefaultVersionId"],
)
doc = version["PolicyVersion"]["Document"]
for stmt in doc.get("Statement", []):
if stmt.get("Effect") != "Allow":
continue
actions = stmt.get("Action", [])
if isinstance(actions, str):
actions = [actions]
for action in actions:
if action == "*" or action in dangerous_actions:
user_dangerous.append({"action": action, "policy": policy_arn})
except ClientError:
continue
if user_dangerous:
escalation_vectors.append({
"principal": user["username"],
"type": "user",
"vectors": user_dangerous,
"risk": "CRITICAL" if any(v["action"] == "*" for v in user_dangerous) else "HIGH",
})
return escalation_vectors
def test_credential_access(region: str = "us-east-1") -> dict:
"""Test what services the current credentials can access."""
services_to_test = [
("sts", "get_caller_identity", {}),
("s3", "list_buckets", {}),
("ec2", "describe_instances", {}),
("iam", "list_users", {}),
("lambda", "list_functions", {}),
("secretsmanager", "list_secrets", {}),
("ssm", "describe_parameters", {}),
]
accessible = []
denied = []
for service, method, kwargs in services_to_test:
try:
client = boto3.client(service, region_name=region)
getattr(client, method)(**kwargs)
accessible.append(service)
except ClientError as e:
if e.response["Error"]["Code"] in ("AccessDenied", "AccessDeniedException", "UnauthorizedAccess"):
denied.append(service)
else:
accessible.append(service)
except Exception:
denied.append(service)
return {"accessible_services": accessible, "denied_services": denied}
def generate_report(iam_data: dict, escalation: list, access: dict, pacu_results: list) -> str:
"""Generate Pacu penetration testing report."""
lines = [
"AWS PENETRATION TESTING (PACU) REPORT — AUTHORIZED TESTING ONLY",
"=" * 65,
f"Account: {iam_data.get('identity', {}).get('account', 'N/A')}",
f"Identity: {iam_data.get('identity', {}).get('arn', 'N/A')}",
f"Date: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}",
"",
"SERVICE ACCESS:",
f" Accessible: {', '.join(access.get('accessible_services', []))}",
f" Denied: {', '.join(access.get('denied_services', []))}",
"",
f"IAM ENUMERATION:",
f" Users Found: {len(iam_data.get('users', []))}",
f" Roles Found: {len(iam_data.get('roles', []))}",
"",
f"PRIVILEGE ESCALATION VECTORS: {len(escalation)}",
"-" * 40,
]
for esc in escalation:
lines.append(f" [{esc['risk']}] {esc['principal']} ({esc['type']})")
for v in esc["vectors"][:5]:
lines.append(f" - {v['action']} via {v['policy']}")
if pacu_results:
lines.extend(["", "PACU MODULE RESULTS:"])
for pr in pacu_results:
status = "OK" if pr["success"] else "FAIL"
lines.append(f" [{status}] {pr['module']}")
return "\n".join(lines)
if __name__ == "__main__":
print("[!] AWS PENTEST WITH PACU — AUTHORIZED TESTING ONLY\n")
region = sys.argv[1] if len(sys.argv) > 1 else "us-east-1"
session_name = sys.argv[2] if len(sys.argv) > 2 else "pentest"
print("[*] Testing credential access scope...")
access = test_credential_access(region)
print("[*] Enumerating IAM...")
iam_data = enumerate_iam_with_boto()
print("[*] Scanning for privilege escalation vectors...")
escalation = scan_privilege_escalation(iam_data)
pacu_results = []
pacu_modules = [
"iam__enum_users_roles_policies_groups",
"iam__privesc_scan",
"ec2__enum",
"s3__enum",
"lambda__enum",
]
for module in pacu_modules:
print(f"[*] Running Pacu module: {module}")
result = run_pacu_module(module, session_name)
pacu_results.append(result)
report = generate_report(iam_data, escalation, access, pacu_results)
print(report)
output = f"pacu_pentest_{datetime.now(timezone.utc).strftime('%Y%m%d')}.json"
with open(output, "w") as f:
json.dump({"iam": iam_data, "escalation": escalation, "access": access,
"pacu_results": pacu_results}, f, indent=2, default=str)
print(f"\n[*] Results saved to {output}")