mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-18 13:39:40 +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,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Anthropic Agent Skills Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,60 @@
|
||||
# API Reference: Cloud Penetration Testing Agent
|
||||
|
||||
## Overview
|
||||
|
||||
Enumerates AWS IAM users, roles, cross-account trusts, IMDSv1 instances, public S3 buckets, and Lambda secrets to identify privilege escalation paths and misconfigurations. For authorized penetration testing only.
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Package | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| requests | >=2.28 | HTTP API calls |
|
||||
| AWS CLI | >=2.0 | AWS service enumeration (subprocess) |
|
||||
|
||||
## CLI Usage
|
||||
|
||||
```bash
|
||||
python agent.py --profile target-account --output pentest_report.json
|
||||
```
|
||||
|
||||
## Key Functions
|
||||
|
||||
### `enumerate_iam_users()`
|
||||
Lists all IAM users with username, ARN, and creation date via `aws iam list-users`.
|
||||
|
||||
### `enumerate_iam_roles()`
|
||||
Lists IAM roles and identifies cross-account trust relationships by inspecting AssumeRolePolicyDocument principals.
|
||||
|
||||
### `check_imds_v1_instances()`
|
||||
Identifies running EC2 instances with IMDSv1 enabled (`HttpTokens: optional`), vulnerable to SSRF credential theft.
|
||||
|
||||
### `check_public_s3_buckets()`
|
||||
Enumerates S3 buckets and checks each for public policy status via `get-bucket-policy-status`.
|
||||
|
||||
### `check_lambda_env_secrets()`
|
||||
Inspects Lambda function environment variables for sensitive keys (password, secret, token, api_key).
|
||||
|
||||
### `test_privesc_create_policy_version(policy_arn)`
|
||||
Tests if a policy allows `iam:CreatePolicyVersion` permission which enables privilege escalation.
|
||||
|
||||
## AWS CLI Commands Used
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `aws iam list-users` | Enumerate IAM users |
|
||||
| `aws iam list-roles` | Enumerate roles and trust policies |
|
||||
| `aws ec2 describe-instances` | Check IMDS configuration |
|
||||
| `aws s3api list-buckets` | List S3 buckets |
|
||||
| `aws s3api get-bucket-policy-status` | Check public access |
|
||||
| `aws lambda list-functions` | Enumerate Lambda functions |
|
||||
| `aws lambda get-function-configuration` | Inspect env vars |
|
||||
| `aws iam simulate-principal-policy` | Test IAM permissions |
|
||||
|
||||
## MITRE ATT&CK Cloud Mapping
|
||||
|
||||
| Technique | ID | Function |
|
||||
|-----------|----|----------|
|
||||
| Cloud Account Discovery | T1087.004 | `enumerate_iam_users` |
|
||||
| Steal Application Access Token | T1528 | `check_lambda_env_secrets` |
|
||||
| Unsecured Credentials: Cloud Instance Metadata | T1552.005 | `check_imds_v1_instances` |
|
||||
| Valid Accounts: Cloud Accounts | T1078.004 | `enumerate_iam_roles` |
|
||||
@@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env python3
|
||||
# For authorized penetration testing and lab environments only
|
||||
"""Cloud Penetration Testing Agent - Enumerates and tests AWS IAM misconfigurations."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import argparse
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def enumerate_iam_users():
|
||||
"""Enumerate all IAM users in the AWS account."""
|
||||
cmd = ["aws", "iam", "list-users", "--output", "json"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
users = json.loads(result.stdout).get("Users", [])
|
||||
logger.info("Enumerated %d IAM users", len(users))
|
||||
return [{"username": u["UserName"], "arn": u["Arn"], "created": u["CreateDate"]} for u in users]
|
||||
return []
|
||||
|
||||
|
||||
def enumerate_iam_roles():
|
||||
"""Enumerate IAM roles and identify cross-account trust relationships."""
|
||||
cmd = ["aws", "iam", "list-roles", "--output", "json"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
roles = json.loads(result.stdout).get("Roles", [])
|
||||
cross_account = []
|
||||
for role in roles:
|
||||
policy_doc = role.get("AssumeRolePolicyDocument", {})
|
||||
for statement in policy_doc.get("Statement", []):
|
||||
principal = statement.get("Principal", {})
|
||||
aws_principal = principal.get("AWS", "")
|
||||
if isinstance(aws_principal, str) and ":root" in aws_principal:
|
||||
cross_account.append({
|
||||
"role": role["RoleName"],
|
||||
"arn": role["Arn"],
|
||||
"trusted_account": aws_principal,
|
||||
})
|
||||
logger.info("Found %d cross-account trust roles", len(cross_account))
|
||||
return cross_account
|
||||
return []
|
||||
|
||||
|
||||
def check_imds_v1_instances():
|
||||
"""Check for EC2 instances running with IMDSv1 (vulnerable to SSRF)."""
|
||||
cmd = [
|
||||
"aws", "ec2", "describe-instances",
|
||||
"--query", "Reservations[*].Instances[*].[InstanceId,MetadataOptions.HttpTokens,State.Name]",
|
||||
"--output", "json",
|
||||
]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
instances = json.loads(result.stdout)
|
||||
vulnerable = []
|
||||
for reservation in instances:
|
||||
for inst in reservation:
|
||||
if inst[1] == "optional" and inst[2] == "running":
|
||||
vulnerable.append({"instance_id": inst[0], "imds": "v1 (optional)", "state": inst[2]})
|
||||
logger.info("Found %d instances with IMDSv1 enabled", len(vulnerable))
|
||||
return vulnerable
|
||||
return []
|
||||
|
||||
|
||||
def check_public_s3_buckets():
|
||||
"""Enumerate S3 buckets and check for public access."""
|
||||
cmd = ["aws", "s3api", "list-buckets", "--query", "Buckets[*].Name", "--output", "text"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
return []
|
||||
buckets = result.stdout.strip().split()
|
||||
public_buckets = []
|
||||
for bucket in buckets:
|
||||
status_cmd = ["aws", "s3api", "get-bucket-policy-status", "--bucket", bucket, "--output", "json"]
|
||||
r = subprocess.run(status_cmd, capture_output=True, text=True)
|
||||
if r.returncode == 0:
|
||||
policy_status = json.loads(r.stdout)
|
||||
if policy_status.get("PolicyStatus", {}).get("IsPublic", False):
|
||||
public_buckets.append(bucket)
|
||||
logger.warning("PUBLIC bucket found: %s", bucket)
|
||||
return public_buckets
|
||||
|
||||
|
||||
def check_lambda_env_secrets():
|
||||
"""Check Lambda functions for secrets in environment variables."""
|
||||
cmd = ["aws", "lambda", "list-functions", "--query", "Functions[*].FunctionName", "--output", "text"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
return []
|
||||
functions = result.stdout.strip().split()
|
||||
findings = []
|
||||
sensitive_keys = ["password", "secret", "key", "token", "api_key", "database_url", "connection_string"]
|
||||
for fn in functions:
|
||||
env_cmd = [
|
||||
"aws", "lambda", "get-function-configuration",
|
||||
"--function-name", fn,
|
||||
"--query", "Environment.Variables",
|
||||
"--output", "json",
|
||||
]
|
||||
r = subprocess.run(env_cmd, capture_output=True, text=True)
|
||||
if r.returncode == 0 and r.stdout.strip() != "null":
|
||||
env_vars = json.loads(r.stdout)
|
||||
exposed = [k for k in env_vars if any(s in k.lower() for s in sensitive_keys)]
|
||||
if exposed:
|
||||
findings.append({"function": fn, "exposed_keys": exposed})
|
||||
logger.warning("Lambda %s has sensitive env vars: %s", fn, exposed)
|
||||
return findings
|
||||
|
||||
|
||||
def test_privesc_create_policy_version(policy_arn):
|
||||
"""Test if iam:CreatePolicyVersion can be used for privilege escalation."""
|
||||
cmd = [
|
||||
"aws", "iam", "simulate-principal-policy",
|
||||
"--policy-source-arn", policy_arn,
|
||||
"--action-names", "iam:CreatePolicyVersion",
|
||||
"--output", "json",
|
||||
]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
eval_results = json.loads(result.stdout).get("EvaluationResults", [])
|
||||
for er in eval_results:
|
||||
if er.get("EvalDecision") == "allowed":
|
||||
logger.warning("Privesc possible: %s has iam:CreatePolicyVersion", policy_arn)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def generate_report(users, cross_account_roles, imdsv1_instances, public_buckets, lambda_secrets):
|
||||
"""Generate cloud penetration test findings report."""
|
||||
report = {
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"iam_users": len(users),
|
||||
"cross_account_trusts": cross_account_roles,
|
||||
"imdsv1_vulnerable_instances": imdsv1_instances,
|
||||
"public_s3_buckets": public_buckets,
|
||||
"lambda_env_secrets": lambda_secrets,
|
||||
"finding_count": (
|
||||
len(cross_account_roles) + len(imdsv1_instances) +
|
||||
len(public_buckets) + len(lambda_secrets)
|
||||
),
|
||||
}
|
||||
print(json.dumps(report, indent=2))
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Cloud Penetration Testing Agent")
|
||||
parser.add_argument("--profile", default="default", help="AWS CLI profile")
|
||||
parser.add_argument("--output", default="cloud_pentest_report.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
users = enumerate_iam_users()
|
||||
cross_account = enumerate_iam_roles()
|
||||
imdsv1 = check_imds_v1_instances()
|
||||
public_buckets = check_public_s3_buckets()
|
||||
lambda_secrets = check_lambda_env_secrets()
|
||||
|
||||
report = generate_report(users, cross_account, imdsv1, public_buckets, lambda_secrets)
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
logger.info("Cloud pentest report saved to %s", args.output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user