Tree's Notes
  • Overview
  • Tools & Cheatsheets
  • Hacking Methodology
  • Hands-on Practice
  • Linux
    • Linux Basics
  • Windows
    • Windows Basics
  • MacOS
    • MacOS Basics
  • Web
    • Web Basics
  • Mobile
    • iOS
    • Android
  • OS Agnostic
    • Template
  • Courses
    • Hack The Box
      • Bug Bounty Hunter
        • Module 1: Web Requests
        • Module 2: Introduction to Web Applications
        • Module 3: Using Web Proxies
        • Module 4: Information Gathering - Web Edition
        • Module 5: Attacking Web Applications with Ffuf
        • Module 6: JavaScript Deobfuscation
        • Module 7: Cross-Site Scripting (XSS)
        • Module 8: SQL Injection Fundamentals
        • Module 9: SQLMap Essentials
        • Module 10: Command Injections
        • Module 11: File Upload Attacks
        • Module 12: Server-Side Attacks
        • Module 13: Login Brute Forcing
        • Module 14: Broken Authentication
        • Module 15: Web Attacks
        • Module 16: File Inclusion
        • Module 17: Session Security
        • Module 18: Web Service & API Attacks
        • Module 19: Hacking Wordpress
        • Module 20: Bug Bounty Hunting Process
    • OffSec
      • 🦊EXP-301
        • Module 1: Windows User Mode Exploit Development: General Course Information
        • Module 2: WinDbg and x86 Architecture
        • Module 3: Exploiting Stack Overflows
        • Module 4: Exploiting SEH Overflows
        • Module 5: Introduction to IDA Pro
        • Module 6: Overcoming Space Restrictions: Egghunters
        • Module 7: Creating Custom Shellcode
        • Module 8: Reverse Engineering for Bugs
        • Module 9: Stack Overflows and DEP Bypass
        • Module 10: Stack Overflows and ASLR Bypass
        • Module 11: Format String Specifier Attack Part I
        • Module 12: Format String Specifier Attack Part II
        • Module 13: Trying Harder: The Labs
      • 🐙EXP-312
        • Module 1: macOS Control Bypasses: General Course Information
        • Module 2: Virtual Machine Setup Guide
        • Module 3: Introduction to macOS
        • Module 4: macOS Binary Analysis Tools
        • Module 5: The Art of Crafting Shellcodes
        • Module 6: The Art of Crafting Shellcodes (Apple Silicon Edition)
        • Module 7: Dylib Injection
        • Module 8: The Mach Microkernel
        • Module 9: XPC Attacks
        • Module 10: Function Hooking on macOS
        • Module 11: The macOS Sandbox
        • Module 12: Bypassing Transparency, Consent, and Control (Privacy)
        • Module 13: GateKeeper Internals
        • Module 14: Bypassing GateKeeper
        • Module 15: Symlink and Hardlink Attacks
        • Module 16: Injecting Code into Electron Applications
        • Module 17: Getting Kernel Code Execution
        • Module 18: Mach IPC Exploitation
        • Module 19: macOS Penetration Testing
        • Module 20: Chaining Exploits on macOS Ventura
        • Module 21: Mount(ain) of Bugs (archived)
      • ⚓IR-200
        • Module 1: Incident Response Overview
        • Module 2: Fundamentals of Incident Response
        • Module 3: Phases of Incident Response
        • Module 4: Incident Response Communication Plans
        • Module 5: Common Attack Techniques
        • Module 6: Incident Detection and Identification
        • Module 7: Initial Impact Assessment
        • Module 8: Digital Forensics for Incident Responders
        • Module 9: Incident Response Case Management
        • Module 10: Active Incident Containment
        • Module 11: Incident Eradication and Recovery
        • Module 12: Post-Mortem Reporting
        • Module 13: Incident Response Challenge Labs
      • 🐉PEN-103
      • 🐲PEN-200
        • Module 1: Copyright
        • Module 2: Penetration Testing with Kali Linux: General Course Information
        • Module 3: Introduction to Cybersecurity
        • Module 4: Effective Learning Strategies
        • Module 5: Report Writing for Penetration Testers
        • Module 6: Information Gathering
        • Module 7: Vulnerability Scanning
        • Module 8: Introduction to Web Application Attacks
        • Module 9: Common Web Application Attacks
        • Module 10: SQL Injection Attacks
        • Module 11: Client-side Attacks
        • Module 12: Locating Public Exploits
        • Module 13: Fixing Exploits
        • Module 14: Antivirus Evasion
        • Module 15: Password Attacks
        • Module 16: Windows Privilege Escalation
        • Module 17: Linux Privilege Escalation
        • Module 18: Port Redirection and SSH Tunneling
        • Module 19: Tunneling Through Deep Packet Inspection
        • Module 20: The Metasploit Framework
        • Module 21: Active Directory Introduction and Enumeration
        • Module 22: Attacking Active Directory Authentication
        • Module 23: Lateral Movement in Active Directory
        • Module 24: Enumerating AWS Cloud Infrastructure
        • Module 25: Attacking AWS Cloud Infrastructure
        • Module 26: Assembling the Pieces
        • Module 27: Trying Harder: The Challenge Labs
      • 🛜PEN-210
        • Module 1: IEEE 802.11
        • Module 2: Wireless Networks
        • Module 3: Wi-Fi Encryption
        • Module 4: Linux Wireless Tools, Drivers, and Stacks
        • Module 5: Wireshark Essentials
        • Module 6: Frames and Network Interaction
        • Module 7: Aircrack-ng Essentials
        • Module 8: Cracking Authentication Hashes
        • Module 9: Attacking WPS Networks
        • Module 10: Rogue Access Points
        • Module 11: Attacking Captive Portals
        • Module 12: Attacking WPA Enterprise
        • Module 13: bettercap Essentials
        • Module 14: Determining Chipsets and Drivers
        • Module 15: Kismet Essentials
        • Module 16: Manual Network Connections
      • 🔗PEN-300
        • Module 1: Evasion Techniques and Breaching Defenses: General Course Information
        • Module 2: Operating System and Programming Theory
        • Module 3: Client Side Code Execution With Office
        • Module 4: Phishing with Microsoft Office
        • Module 5: Client Side Code Execution With Windows Script Host
        • Module 6: Reflective PowerShell
        • Module 7: Process Injection and Migration
        • Module 8: Introduction to Antivirus Evasion
        • Module 9: Advanced Antivirus Evasion
        • Module 10: Application Whitelisting
        • Module 11: Bypassing Network Filters
        • Module 12: Linux Post-Exploitation
        • Module 13: Kiosk Breakouts
        • Module 14: Windows Credentials
        • Module 15: Windows Lateral Movement
        • Module 16: Linux Lateral Movement
        • Module 17: Microsoft SQL Attacks
        • Module 18: Active Directory Exploitation
        • Module 19: Attacking Active Directory
        • Module 20: Combining the Pieces
        • Module 21: Trying Harder: The Labs
      • ⚛️SEC-100
      • 🛡️SOC-200
        • Module 1: Introduction to SOC-200
        • Module 2: Attacker Methodology Introduction
        • Module 3: Windows Endpoint Introduction
        • Module 4: Windows Server Side Attacks
        • Module 5: Windows Client-Side Attacks
        • Module 6: Windows Privilege Escalation
        • Module 7: Windows Persistence
        • Module 8: Linux Endpoint Introduction
        • Module 9: Linux Server Side Attacks
        • Module 10: Linux Privilege Escalation
        • Module 11: Network Detections
        • Module 12: Antivirus Alerts and Evasion
        • Module 13: Active Directory Enumeration
        • Module 14: Network Evasion and Tunneling
        • Module 15: Windows Lateral Movement
        • Module 16: Active Directory Persistence
        • Module 17: SIEM Part One: Intro to ELK
        • Module 18: SIEM Part Two: Combining the Logs
        • Module 19: Trying Harder: The Labs
      • TH-200
        • Module 1: Threat Hunting Concepts and Practices
        • Module 2: Threat Actor Landscape Overview
        • Module 3: Communication and Reporting for Threat Hunters
        • Module 4: Hunting With Network Data
        • Module 5: Hunting on Endpoints
        • Module 6: Theat Hunting Without IoCs
        • Module 7: Threat Hunting Challenge Labs
      • 🦉WEB-200
        • Module 1: Introduction to WEB-200
        • Module 2: Tools (archived)
        • Module 3: Web Application Enumeration Methodology
        • Module 4: Introduction to Burp Suite
        • Module 5: Cross-Site Scripting Introduction and Discovery
        • Module 6: Cross-Site Scripting Exploitation and Case Study
        • Module 7: Cross-Origin Attacks
        • Module 8: Introduction to SQL
        • Module 9: SQL Injection
        • Module 10: Directory Traversal Attacks
        • Module 11: XML External Entities
        • Module 12: Server-side Template Injection - Discovery and Exploitation
        • Module 13: Command Injection
        • Module 14: Server-side Request Forgery
        • Module 15: Insecure Direct Object Referencing
        • Module 16: Assembling the Pieces: Web Application Assessment Breakdown
      • 🕷️WEB-300
        • Module 1: Introduction
        • Module 2: Tools & Methodologies
        • Module 3: ManageEngine Applications Manager AMUserResourcesSyncServlet SSQL Injection RCE
        • Module 4: DotNetNuke Cookie Deserialization RCE
        • Module 5: ERPNext Authentication Bypass and Remote Code Execution
        • Module 6: openCRX Authentication Bypass and Remote Code Execution
        • Module 7: openITCOCKPIT XSS and OS Command Injection - Blackbox
        • Module 8: Concord Authentication Bypass to RCE
        • Module 9: Server-Side Request Forgery
        • Module 10: Guacamole Lite Prototype Pollution
        • Module 11: Dolibarr Eval Filter Bypass RCE
        • Module 12: RudderStack SQLi and Coraza WAF Bypass
        • Module 13: Conclusion
        • Module 14: ATutor Authentication Bypass and RCE (archived)
        • Module 15: ATutor LMS Type Juggling Vulnerability (archived)
        • Module 16: Atmail Mail Server Appliance: from XSS to RCE (archived)
        • Module 17: Bassmaster NodeJS Arbitrary JavaScript Injection Vulnerability (archived)
    • SANS
      • FOR572
Powered by GitBook
On this page
  • About the Public Cloud Labs
  • Reconnaissance of Cloud Resources on the Internet
  • Accessing the Lab
  • Domain and Subdomain Reconnaissance
  • Service-specific Domains
  • Reconnaissance via Cloud Service Provider's API
  • Preparing the Lab - Configure AWS CLI
  • Publicly Shared Resources
  • Obtaining Account IDs from S3 Buckets
  • Enumerating IAM Users in Other Accounts
  • Initial IAM Reconnaissance
  • Accessing the Lab
  • Examining Compromised Credentials
  • Scoping IAM permissions
  • IAM Resources Enumeration
  • Choosing Between a Manual or Automated Enumeration Approach
  • Enumerating IAM Resources
  • Processing API Response data with JMESPath
  • Running Automated Enumeration with Pacu
  • Extracting Insights from Enumeration Data
Edit on GitHub
  1. Courses
  2. OffSec
  3. PEN-200

Module 24: Enumerating AWS Cloud Infrastructure

About the Public Cloud Labs

  1. The lab environment should not be used for activities not described or requested in the learning materials you encounter. It is not designed to serve as a playground to test additional items that are out of the scope of the Learning Module.

  2. The lab environment should not be used to take action against any asset external to the lab. This is specifically noteworthy because some Modules may describe or even demonstrate attacks against vulnerable cloud deployments for the purpose of describing how those deployments can be secured.

  3. Existing rules and requirements against sharing OffSec training materials still apply. Credentials and other details of the lab are not meant to be shared. OffSec monitors activity in the Public Cloud Labs (including resource usage) and monitors for abnormal events that are not related to activities described in the learning modules.

Activities that are flagged as suspicious will result in an investigation. If the investigation determines that a student acted outside of the guidelines described above, or otherwise intentionally abused the OffSec Public Cloud Labs, OffSec may choose to rescind that learner's access to the OffSec Public Cloud Labs and/or terminate the learner's account.

Reconnaissance of Cloud Resources on the Internet

Accessing the Lab

Deployment will take a few minutes to complete and, once complete, the additional services might take 5-10 minutes to start.

Once the lab finishes its deployment, we'll receive some pieces of information we'll need later while working in the lab.

  • Public DNS IP Address

  • Domain name of the target

  • Credentials for the IAM user attacker

    • ACCESS_KEY_ID

    • SECRET_ACCESS_KEY

We must configure the DNS in our local environment to use the public DNS set for this lab:

kali@kali:~$ cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 44.205.254.229
nameserver 1.1.1.1

We should also keep in mind that the public IP address of the DNS server will change every time we restart the lab, and we'll need to run this configuration again.

Domain and Subdomain Reconnaissance

Querying the authoritative DNS servers for the offseclab.io domain:

kali@kali:~$ host -t ns offseclab.io
offseclab.io name server ns-1536.awsdns-00.co.uk.
offseclab.io name server ns-512.awsdns-00.net.
offseclab.io name server ns-0.awsdns-00.com.
offseclab.io name server ns-1024.awsdns-00.org.

Validating who owns the domains found:

kali@kali:~$ whois awsdns-00.com | grep "Registrant Organization"
Registrant Organization: Amazon Technologies, Inc.

Querying the public IP address of our target:

kali@kali:~$ host www.offseclab.io
www.offseclab.io has address 52.70.117.69

Performing a reverse DNS lookup:

kali@kali:~$ host 52.70.117.69
69.117.70.52.in-addr.arpa domain name pointer ec2-52-70-117-69.compute-1.amazonaws.com

kali@kali:~$ whois 52.70.117.69 | grep "OrgName"
OrgName:        Amazon Technologies Inc.

Using dnsenum to auomate some of this dns reconnaissance:

kali@kali:~$ dnsenum offseclab.io --threads 100
dnsenum VERSION:1.2.6

-----   offseclab.io   -----


Host's addresses:
__________________

offseclab.io.                            60       IN    A        52.70.117.69

Name Servers:
______________

ns-1536.awsdns-00.co.uk.                 0        IN    A        205.251.198.0
ns-0.awsdns-00.com.                      0        IN    A        205.251.192.0
ns-512.awsdns-00.net.                    0        IN    A        205.251.194.0
ns-1024.awsdns-00.org.                   0        IN    A        205.251.196.0


Mail (MX) Servers:
___________________



Trying Zone Transfers and getting Bind Versions:
_________________________________________________

Trying Zone Transfer for offseclab.io on ns-512.awsdns-00.net ...
AXFR record query failed: corrupt packet

Trying Zone Transfer for offseclab.io on ns-1024.awsdns-00.org ...
AXFR record query failed: corrupt packet

Trying Zone Transfer for offseclab.io on ns-0.awsdns-00.com ...
AXFR record query failed: corrupt packet

Trying Zone Transfer for offseclab.io on ns-1536.awsdns-00.co.uk ...
AXFR record query failed: corrupt packet


Brute forcing with /usr/share/dnsenum/dns.txt:
_______________________________________________
mail.offseclab.io.                       60       IN    A        52.70.117.69
www.offseclab.io.                        60       IN    A        52.70.117.69
...

Service-specific Domains

Not much to add, of note Amazon ec2 instances tend to have a URL beginning with ec2. Same goes for s3 buckets.

cloud-enum is a useful tool to perform OSINT across multiple CSPs. The cloud-enum tool will search through several public CSPs for resources containing a keyword specified using the --keyword KEYWORD (-k KEYWORD) parameter. We can specify multiple keyword arguments, or we can specify a list with the --keyfile KEYFILE (-kf KEYFILE) parameter.

We can also use the --mutations (-m) option to specify a file to add extra words to the keyword. If we don't specify any file, the /usr/lib/cloud-enum/enum_tools/fuzz.txt file is used by default. We can disable this option using the --quickscan (-qs) parameter.

Using cloud-enum to search for more buckets belonging to offseclab.io:

kali@kali:~$ cloud_enum -k offseclab-assets-public-axevtewi --quickscan --disable-azure --disable-gcp

...

Keywords:    offseclab-assets-public-axevtewi
Mutations:   NONE! (Using quickscan)
Brute-list:  /usr/lib/cloud-enum/enum_tools/fuzz.txt

[+] Mutated results: 1 items

++++++++++++++++++++++++++
      amazon checks
++++++++++++++++++++++++++

[+] Checking for S3 buckets
  OPEN S3 BUCKET: http://offseclab-assets-public-axevtewi.s3.amazonaws.com/
      FILES:
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/offseclab-assets-public-axevtewi
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/amethyst-expanded.png
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/amethyst.png
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/logo.svg
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/pic02.jpg
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/pic05.jpg
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/pic13.jpg
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/ruby-expanded.png
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/ruby.jpg
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/saphire-expanded.png
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/saphire.jpg
                            
                            
 Elapsed time: 00:00:00

[+] Checking for AWS Apps
[*] Brute-forcing a list of 1 possible DNS names
                            
 Elapsed time: 00:00:00


[+] All done, happy hacking!

Using a custom keyfile for cloud-enum:

kali@kali:~$ for key in "public" "private" "dev" "prod" "development" "production"; do echo "offseclab-assets-$key-axevtewi"; done | tee /tmp/keyfile.txt
offseclab-assets-public-axevtewi
offseclab-assets-private-axevtewi
offseclab-assets-dev-axevtewi
offseclab-assets-prod-axevtewi
offseclab-assets-development-axevtewi
offseclab-assets-production-axevtewi

kali@kali:~$ cloud_enum -kf /tmp/keyfile.txt -qs --disable-azure --disable-gcp

...

Keywords:    offseclab-assets-public-axevtewi, offseclab-assets-private-axevtewi, offseclab-assets-dev-axevtewi, offseclab-assets-prod-axevtewi, offseclab-assets-development-axevtewi, offseclab-assets-production-axevtewi
Mutations:   NONE! (Using quickscan)
Brute-list:  /usr/lib/cloud-enum/enum_tools/fuzz.txt

[+] Mutated results: 6 items

++++++++++++++++++++++++++
      amazon checks
++++++++++++++++++++++++++

[+] Checking for S3 buckets
  OPEN S3 BUCKET: http://offseclab-assets-public-axevtewi.s3.amazonaws.com/
      FILES:
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/offseclab-assets-public-axevtewi
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/amethyst-expanded.png
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/amethyst.png
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/logo.svg
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/pic02.jpg
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/pic05.jpg
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/pic13.jpg
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/ruby-expanded.png
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/ruby.jpg
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/saphire-expanded.png
      ->http://offseclab-assets-public-axevtewi.s3.amazonaws.com/sites/www/images/saphire.jpg
  Protected S3 Bucket: http://offseclab-assets-private-axevtewi.s3.amazonaws.com/
                            
 Elapsed time: 00:00:06

[+] Checking for AWS Apps
[*] Brute-forcing a list of 6 possible DNS names
                            
 Elapsed time: 00:00:00


[+] All done, happy hacking!

Objects inside a bucket can be publicly accessible even if the bucket is not publicly accessible.

Reconnaissance via Cloud Service Provider's API

Preparing the Lab - Configure AWS CLI

Configuring awscli:

kali@kali:~$ sudo apt update
...

kali@kali:~$ sudo apt install -y awscli
...
The following NEW packages will be installed:
  awscli docutils-common python3-awscrt python3-docutils python3-jmespath python3-roman
(Reading database ... 461429 files and directories currently installed.)
...

kali@kali:~$ aws configure --profile attacker
AWS Access Key ID []: AKIAQO...
AWS Secret Access Key []: cOGzm...
Default region name []: us-east-1
Default output format []: json

kali@kali:~$ aws --profile attacker sts get-caller-identity
{
    "UserId": "AIDAQOMAIGYU5VFQCHOI4",
    "Account": "123456789012",
    "Arn": "arn:aws:iam::123456789012:user/attacker"
}

Publicly Shared Resources

Listing all AMIs that our account can read, that are provided by Amazon that are public, including self-owned public AMIs:

kali@kali:~$ aws --profile attacker ec2 describe-images --owners amazon --executable-users all
{
    "Images": [
        {
            "Architecture": "x86_64",
            "CreationDate": "2022-06-29T09:46:55.000Z",
            "ImageId": "ami-0d4f490f4e62171b4",
            "ImageLocation": "amazon/Deep Learning Base AMI (Amazon Linux 2) Version 53.4",
            "ImageType": "machine",
            "Public": true,
            "OwnerId": "898082745236",
            "PlatformDetails": "Linux/UNIX",
            "UsageOperation": "RunInstances",
            "State": "available",
            "BlockDeviceMappings": [
                {
                    "DeviceName": "/dev/xvda",
                    "Ebs": {
                        "DeleteOnTermination": true,
                        "Iops": 3000,
                        "SnapshotId": "snap-0ce7f231ea72dd0ea",
                        "VolumeSize": 100,
...

Filtering for AMIs with a name including "Offseclab":

kali@kali:~$ aws --profile attacker ec2 describe-images --executable-users all --filters "Name=name,Values=*Offseclab*"
{
    "Images": [
        {
            "Architecture": "x86_64",
            "CreationDate": "2023-08-05T19:43:29.000Z",
            "ImageId": "ami-0854d94958c0a17e6",
            "ImageLocation": "123456789012/Offseclab Base AMI",
            "ImageType": "machine",
            "Public": true,
            "OwnerId": "123456789012",
            "PlatformDetails": "Linux/UNIX",
            "UsageOperation": "RunInstances",
            "State": "available",
            "BlockDeviceMappings": [
                {
                    "DeviceName": "/dev/xvda",
                    "Ebs": {
                        "DeleteOnTermination": true,
                {
                    "DeviceName": "/dev/xvda",
                    "Ebs": {
                        "DeleteOnTermination": true,
                        "DeleteOnTermination": true,
                        "SnapshotId": "snap-098dc18c797e4f255",
                        "VolumeSize": 8,
                        "VolumeType": "gp2",
                        "Encrypted": false
                    }
                }
            ],
            "EnaSupport": true,
            "Hypervisor": "xen",
            "Name": "Offseclab Base AMI",
            "RootDeviceName": "/dev/xvda",
            "RootDeviceType": "ebs",
            "SriovNetSupport": "simple",
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "Offseclab Base AMI"
                }
            ],
            "VirtualizationType": "hvm",
            "DeprecationTime": "2023-08-05T21:43:00.000Z"
        }
    ]
}

Obtaining Account IDs from S3 Buckets

Steps to find the account ID from a publicly available S3 bucket:

  1. Create an IAM user with a policy that only allows them to ls the S3 bucket if the account ID begins with x where x is 0-9.

  2. As that user, attempt to ls the S3 bucket. If it's able to, then move to the next digit. Otherwise change the first digit for the account ID in teh policy and reapply.

  3. Rinse & repeat.

There are also tools like s3-account-search to do this, however that tool uses roles rather than users to link the policy to the condition.

Example policy:

policy-s3-read.json
{
     "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowResourceAccount",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": "*",
            "Condition": {
                "StringLike": {"s3:ResourceAccount": ["0*"]}
            }
        }
    ]
}

Enumerating IAM Users in Other Accounts

Similar to the last section, we can use policies to determine if IAM accounts exist when we know an account ID. In this case we would assign the policy to our own private bucket. If no error returns after running the command to apply the policy, that means that the cloudadmin user exists in the target account.

Creating a dummy private bucket:

kali@kali:~$ aws --profile attacker s3 mb s3://offseclab-dummy-bucket-$RANDOM-$RANDOM-$RANDOM
make_bucket: offseclab-dummy-bucket-28967-25641-13328

Example policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowUserToListBucket",
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::offseclab-dummy-bucket-28967-25641-13328",
            "Principal": {
                "AWS": ["arn:aws:iam::123456789012:user/cloudadmin"]
            },
            "Action": "s3:ListBucket"

        }
    ]
}

Applying the policy to our private bucket:

kali@kali:~$ aws --profile attacker s3api put-bucket-policy --bucket offseclab-dummy-bucket-28967-25641-13328 --policy file://grant-s3-bucket-read.json 

Applying a policy where the user does not exist:

kali@kali:~$ aws --profile attacker s3api put-bucket-policy --bucket offseclab-dummy-bucket-28967-25641-13328  --policy file://grant-s3-bucket-read-userDoNotExist.json 

An error occurred (MalformedPolicy) when calling the PutBucketPolicy operation: Invalid principal in policy

We can automate this process using pacu and a prebuilt list of users we'd like to test:

# Generating our list of users.
kali@kali:~$ echo -n "lab_admin
security_auditor
content_creator
student_access
lab_builder
instructor
network_config
monitoring_logging
backup_restore
content_editor" > /tmp/role-names.txt

# Installing pacu.
kali@kali:~$ sudo apt update
kali@kali:~$ sudo apt install pacu

# Starting pacu in interactive mode. 
kali@kali:~$ pacu
....
Database created at /root/.local/share/pacu/sqlite.db

What would you like to name this new session? offseclab
Session offseclab created.
...

# Setting keys from the AWS CLI, specifying the attacker role.
Pacu (offseclab:No Keys Set) > import_keys attacker
  Imported keys as "imported-attacker"
  
# Listing available modules.
Pacu (offseclab:imported-attacker) > ls
...
[Category: RECON_UNAUTH]

  iam__enum_roles
  iam__enum_users
...

# Getting information about the iam__enum_roles module
Pacu (offseclab:imported-attacker) > help iam__enum_roles
iam__enum_roles written by Spencer Gietzen of Rhino Security Labs.

usage: pacu [--word-list WORD_LIST] [--role-name ROLE_NAME] --account-id
            ACCOUNT_ID

This module takes in a valid AWS account ID and tries to enumerate existing
IAM roles within that account. It does so by trying to update the
AssumeRole policy document of the role that you pass into --role-name if
passed or newlycreated role. For your safety, it updates the policy with an
explicit deny against the AWS account/IAM role, so that no security holes
are opened in your account during enumeration. NOTE: It is recommended to
use personal AWS access keys for this script, as it will spam CloudTrail
with "iam:UpdateAssumeRolePolicy" logs and a few "sts:AssumeRole" logs. The
target account will not see anything in their logs though, unless you find
a misconfigured role that allows you to assume it. The keys used must have
the iam:UpdateAssumeRolePolicy permission on the role that you pass into
--role-name to be able to identify a valid IAM role and the sts:AssumeRole
permission to try and request credentials for any enumerated roles.
...

# Running the module with our custom name list.
Pacu (offseclab:imported-attacker) > run iam__enum_roles --word-list /tmp/role-names.txt --account-id 123456789012
  Running module iam__enum_roles...
...

[iam__enum_roles] Targeting account ID: 123456789012

[iam__enum_roles] Starting role enumeration...


[iam__enum_roles]   Found role: arn:aws:iam::123456789012:role/lab_admin

[iam__enum_roles] Found 1 role(s):

[iam__enum_roles]     arn:aws:iam::123456789012:role/lab_admin

[iam__enum_roles] Checking to see if any of these roles can be assumed for temporary credentials...

[iam__enum_roles]   Role can be assumed, but hit max session time limit, reverting to minimum of 1 hour...

[iam__enum_roles]   Successfully assumed role for 1 hour: arn:aws:iam::123456789012:role/lab_admin

[iam__enum_roles] {
  "Credentials": {
    "AccessKeyId": "ASIAQOMAIGYUWZXRMMO2",
    "SecretAccessKey": "2UU80dtizqx3DUa9mn6033AjXKb13GXOMCy+tOUt",
    "SessionToken": "FwoGZXIvYXdzEO///////////wEaDCv5...",
    "Expiration": "2023-08-18 22:07:49+00:00"
  },
  "AssumedRoleUser": {
    "AssumedRoleId": "AROAQOMAIGYUR5KMGWT7V:dCkQ0O1y6n9KSQmGBaKJ",
    "Arn": "arn:aws:sts::123456789012:assumed-role/lab_admin/dCkQ0O1y6n9KSQmGBaKJ"
  }
}
Cleaning up the PacuIamEnumRoles-XbsIV role.

Now that we were able to assume the role, let's set environment variable and query the environment:

kali@kali:~$ export AWS_ACCESS_KEY=ASIAQOMAIGYUWZXRMMO2
kali@kali:~$ export AWS_SECRET_ACCESS_KEY=2UU80dtizqx3DUa9mn6033AjXKb13GXOMCy+tOUt
kali@kali:~$ export AWS_SESSION_TOKEN=FwoGZXIvYXdzEO///////////wEaDCv5...

# We don't need to include profile anymore as it will use our environment variables.
kali@kali:~$ aws ec2 describe-vpcs --region us-east-1

Initial IAM Reconnaissance

Accessing the Lab

  • Credentials for access as the target user.

    • Target ACCESS KEY ID

    • Target SECRET ACCESS KEY

  • Credentials for access as the challenge user.

    • Challenge ACCESS KEY ID

    • Challenge SECRET ACCESS KEY

  • Credentials for access as the monitor user.

    • Management Console login URL

    • Username

    • Password

Examining Compromised Credentials

The get-caller-identity subcommand is a good way to identify the account and identity of the credentials, and this action will never return an AccessDenied error. However, we should be aware that this action is logged in Cloudtrail's event history. As defenders, we should establish alerts for these types of calls as they are typically executed by attackers once they've compromised credentials.

Getting details about our compromised account:

kali@kali:~$ aws --profile target sts get-caller-identity

The more stealthy command to gather information, this results in logs of our attacker's account rather than the target's:

kali@kali:~$ aws --profile challenge sts get-access-key-info --access-key-id AKIAQOMAIGYUVEHJ7WXM

Getting information in a stealthy way from error messages via a lambda function:

kali@kali:~$ aws --profile target lambda invoke --function-name arn:aws:lambda:us-east-1:123456789012:function:nonexistent-function outfile

An error occurred (AccessDeniedException) when calling the Invoke operation: User: arn:aws:iam::123456789012:user/support/clouddesk-plove is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-1:123456789012:function:nonexistent-function because no resource-based policy allows the lambda:InvokeFunction action

Scoping IAM permissions

Listing inline policies:

kali@kali:~$ aws --profile target iam list-user-policies --user-name clouddesk-plove

{
    "PolicyNames": []
}

Listing policies associated with the user specified:

kali@kali:~$ aws --profile target iam list-attached-user-policies --user-name clouddesk-plove
{
    {
    "AttachedPolicies": [
        {
            "PolicyName": "deny_challenges_access",
            "PolicyArn": "arn:aws:iam::123456789012:policy/deny_challenges_access"
        }
    ]
}
}

Listing groups that the specified user is attached to:

kali@kali:~$ aws --profile target iam list-groups-for-user --user-name clouddesk-plove

{
    "Groups": [
        {
            "Path": "/support/",
            "GroupName": "support",
            "GroupId": "AGPAQOMAIGYUSHSVDSYIP",
            "Arn": "arn:aws:iam::123456789012:group/support/support",
        }
    ]
}

Checking inline and managed policies for the group discovered:

kali@kali:~$ aws --profile target iam list-group-policies --group-name support

{
    "PolicyNames": []
}

kali@kali:~$ aws --profile target iam list-attached-group-policies --group-name support
{
    "AttachedPolicies": [
        {
            "PolicyName": "SupportUser",
            "PolicyArn": "arn:aws:iam::aws:policy/job-function/SupportUser"
        }
    ]
}

While AWS Managed Policies offer flexibility for IAM management, they tend to be overly-permissive and there is an inherent security risk when they are used alone.

Determining the version of the AWS managed policy applied to the support group:

kali@kali:~$ aws --profile target iam list-policy-versions --policy-arn "arn:aws:iam::aws:policy/job-function/SupportUser"

{
    "Versions": [
        {
            "VersionId": "v8",
            "IsDefaultVersion": true
        },
        {
            "VersionId": "v7",
            "IsDefaultVersion": false,
        },
...

Retrieving the most recent version document:

kali@kali:~$ aws --profile target iam get-policy-version --policy-arn arn:aws:iam::aws:policy/job-function/SupportUser --version-id v8

{
    "PolicyVersion": {
        "Document": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": [
                        "support:*",
                        "acm:DescribeCertificate",
                        "acm:GetCertificate",
                        "acm:List*",
                        "acm-pca:DescribeCertificateAuthority",
                        "autoscaling:Describe*",
...
                        "workdocs:Describe*",
                        "workmail:Describe*",
                        "workmail:Get*",
                        "workspaces:Describe*"
                    ],
                    "Effect": "Allow",
                    "Resource": "*"
                }
            ]
        },
        "VersionId": "v8",
        "IsDefaultVersion": true,
...
    }
}

IAM Resources Enumeration

Choosing Between a Manual or Automated Enumeration Approach

Enumerating IAM Resources

Resource Type
Name
ARN

IAM::User

clouddesk-plove

arn:aws:iam::123456789012:user/support/clouddesk-plove

IAM:Group

support

arn:aws:iam::123456789012:group/support/support

IAM::Policy

SupportUser

arn:aws:iam::aws:policy/job-function/SupportUser

Checking the actions our policy grants us the ability to us:

kali@kali:~$ aws --profile target iam get-policy-version --policy-arn arn:aws:iam::aws:policy/job-function/SupportUser --version-id v8 | grep "iam"

                        "iam:GenerateCredentialReport",
                        "iam:GenerateServiceLastAccessedDetails",
                        "iam:Get*",
                        "iam:List*",

Filter command via the aws help to show what all we can do:

kali@kali:~$ aws --profile target iam help | grep -E "list-|get-|generate-"

       o generate-credential-report
       o generate-organizations-access-report
       o generate-service-last-accessed-details
       o get-access-key-last-used
       o get-account-authorization-details
       o get-account-password-policy
       o get-account-summary
       o get-context-keys-for-custom-policy
       o get-context-keys-for-principal-policy
       o get-credential-report
       o get-group
       o get-group-policy
       o get-instance-profile
       o get-login-profile
       o get-open-id-connect-provider
       o get-organizations-access-report
       o get-policy
       o get-policy-version
       o get-role
       o get-role-policy
       o get-saml-provider
       o get-server-certificate
       o get-service-last-accessed-details
       o get-service-last-accessed-details-with-entities
       o get-service-linked-role-deletion-status
       o get-ssh-public-key
       o get-user
       o get-user-policy
       o list-access-keys
       o list-account-aliases
       o list-attached-group-policies
       o list-attached-role-policies
       o list-attached-user-policies
       o list-entities-for-policy
       o list-group-policies
       o list-groups
       o list-groups-for-user
       o list-instance-profile-tags
       o list-instance-profiles
       o list-instance-profiles-for-role
       o list-mfa-device-tags
       o list-mfa-devices
       o list-open-id-connect-provider-tags
       o list-open-id-connect-providers
       o list-policies
       o list-policies-granting-service-access
       o list-policy-tags
       o list-policy-versions
       o list-role-policies
       o list-role-tags
       o list-roles
       o list-saml-provider-tags
       o list-saml-providers
       o list-server-certificate-tags
       o list-server-certificates
       o list-service-specific-credentials
       o list-signing-certificates
       o list-ssh-public-keys
       o list-user-policies
       o list-user-tags
       o list-users
       o list-virtual-mfa-devices

Getting a summary of the IAM-related information in the account, tee'ing it to avoid interacting with the AWS API again:

kali@kali:~$ aws --profile target iam get-account-summary | tee account-summary.json

aws --profile target iam get-account-summary
{
    "SummaryMap": {
        "GroupPolicySizeQuota": 5120,
        "InstanceProfilesQuota": 1000,
        "Policies": 8,
        "GroupsPerUserQuota": 10,
        "InstanceProfiles": 0,
        "AttachedPoliciesPerUserQuota": 10,
        "Users": 18,
        "PoliciesQuota": 1500,
        "Providers": 1,
        "AccountMFAEnabled": 0,
        "AccessKeysPerUserQuota": 2,
        "AssumeRolePolicySizeQuota": 2048,
        "PolicyVersionsInUseQuota": 10000,
        "GlobalEndpointTokenVersion": 1,
        "VersionsPerPolicyQuota": 5,
        "AttachedPoliciesPerGroupQuota": 10,
        "PolicySizeQuota": 6144,
        "Groups": 8,
        "AccountSigningCertificatesPresent": 0,
        "UsersQuota": 5000,
        "ServerCertificatesQuota": 20,
        "MFADevices": 0,
        "UserPolicySizeQuota": 2048,
        "PolicyVersionsInUse": 27,
        "ServerCertificates": 0,
        "Roles": 20,
        "RolesQuota": 1000,
        "SigningCertificatesPerUserQuota": 2,
        "MFADevicesInUse": 0,
        "RolePolicySizeQuota": 10240,
        "AttachedPoliciesPerRoleQuota": 10,
        "AccountAccessKeysPresent": 0,
        "GroupsQuota": 300
    }
}

Enumerating all the IAM identities:

kali@kali:~$ aws --profile target iam list-users | tee users.json

{
    "Users": [
        {
            "Path": "/admin/",
            "UserName": "admin-alice",
            "UserId": "AIDAQOMAIGYU3FWX3JOFP",
            "Arn": "arn:aws:iam::123456789012:user/admin/admin-alice",
        },
...


kali@kali:~$ aws --profile target iam list-groups | tee groups.json

{
    "Groups": [
        {
            "Path": "/admin/",
            "GroupName": "admin",
            "GroupId": "AGPAQOMAIGYUXBR7QGLLN",
            "Arn": "arn:aws:iam::123456789012:group/admin/admin",
        },
...


kali@kali:~$ aws --profile target iam list-roles | tee roles.json

{
    "Roles": [
        {
            "Path": "/",
            "RoleName": "aws-controltower-AdministratorExecutionRole",
            "RoleId": "AROAQOMAIGYU6PUFJYD7W",
            "Arn": "arn:aws:iam::123456789012:role/aws-controltower-AdministratorExecutionRole",
...

Listing policies attached to IAM identities, only displaying the Customer Managed Policies and omitting the AWS Managed Policies:

kali@kali:~$ aws --profile target iam list-policies --scope Local --only-attached | tee policies.json

{
    "Policies": [
        {
            "PolicyName": "manage-credentials",
            "PolicyId": "ANPAQOMAIGYU3LK3BHLGL",
            "Arn": "arn:aws:iam::123456789012:policy/manage-credentials",
            "Path": "/",
            "DefaultVersionId": "v1",
            "AttachmentCount": 1,
            "PermissionsBoundaryUsageCount": 0,
            "IsAttachable": true,
            "UpdateDate": "2023-10-19T15:45:59+00:00"
        },
...

Getting the inline policies for every identity:

  • list-user-policies

  • get-user-policy

  • list-group-policies

  • get-group-policy

  • list-role-policies

  • get-role-policy

Checking for all managed policies:

  • list-attached-user-policies

  • list-attached-group-policies

  • list-attached-role-policies

Then we can run the get-policy-version subcommand to read the policy document for each managed policy found.

Alternatively, if we have Get* permissions, we can just run get-account-authorization-details to gather the same information of all the previous commands.

kali@kali:~$ aws --profile target iam get-account-authorization-details --filter User Group LocalManagedPolicy Role | tee account-authorization-details.json

{
    "UserDetailList": [
        {
            "Path": "/admin/",
            "UserName": "admin-alice",
            "UserId": "AIDAQOMAIGYU3FWX3JOFP",
            "Arn": "arn:aws:iam::123456789012:user/admin/admin-alice",
            "GroupList": [
                "amethyst_admin",
                "admin"
            ],
    ...
    "GroupDetailList": [
        {
            "Path": "/admin/",
            "GroupName": "admin",
            "GroupId": "AGPAQOMAIGYUXBR7QGLLN",
            "Arn": "arn:aws:iam::123456789012:group/admin/admin",
            "GroupPolicyList": [],
    ...
    "RoleDetailList": [
        {
            "Path": "/",
            "RoleName": "aws-controltower-AdministratorExecutionRole",
            "RoleId": "AROAQOMAIGYU6PUFJYD7W",
            "Arn": "arn:aws:iam::123456789012:role/aws-controltower-AdministratorExecutionRole",
    ...
    "Policies": [
        {
            "PolicyName": "ruby_admin",
            "PolicyId": "ANPAQOMAIGYU3I3WDCID3",
            "Arn": "arn:aws:iam::123456789012:policy/ruby/ruby_admin",
            "Path": "/ruby/",
...

Processing API Response data with JMESPath

Example querying all user information via get-account-authorization-details:

kali@kali:~$ aws --profile target iam get-account-authorization-details --filter User

{
    "UserDetailList": [
        {
            "Path": "/admin/",
            "UserName": "admin-alice",
            "UserId": "AIDAQOMAIGYUSSOCFCREC",
            "Arn": "arn:aws:iam::123456789012:user/admin/admin-alice",
            "GroupList": [
                "admin"
            ],
            "AttachedManagedPolicies": [],
            "Tags": []
        },
        {
            "Path": "/amethyst/",
            "UserName": "admin-cbarton",
            "UserId": "AIDAQOMAIGYUTHT4D5YLG",
            "Arn": "arn:aws:iam::123456789012:user/amethyst/admin-cbarton",
            "GroupList": [
                "amethyst_admin"
            ],
            "AttachedManagedPolicies": [],
            "Tags": []
        },
...

Now using JMESPath expression to query just the UserName field:

kali@kali:~$ aws --profile target iam get-account-authorization-details --filter User --query "UserDetailList[].UserName"

[
    "admin-alice",
    "admin-cbarton",
    "admin-srogers",
    "admin-tstark",
    "clouddesk-bob",
...

Additional examples:

kali@kali:~$ aws --profile target iam get-account-authorization-details --filter User --query "UserDetailList[0].[UserName,Path,GroupList]"

[
    "admin-alice",
    "/admin/",
    [
        "admin"
    ]
]


kali@kali:~$ aws --profile target iam get-account-authorization-details --filter User --query "UserDetailList[0].{Name: UserName,Path: Path,Groups: GroupList}"

{
    "Name": "admin-alice",
    "Path": "/admin/",
    "Groups": [
        "admin"
    ]
}

Listing all IAM Users with a username containing the word 'admin' via Filter Projections:

kali@kali:~$ aws --profile target iam get-account-authorization-details --filter User --query "UserDetailList[?contains(UserName, 'admin')].{Name: UserName}"

[
    {
        "Name": "admin-alice"
    },
    {
        "Name": "admin-cbarton"
    },
    {
        "Name": "admin-srogers"
    },

...

More examples with Filter Projections:

kali@kali:~$ aws --profile target iam get-account-authorization-details --filter User Group --query "{Users: UserDetailList[?Path=='/admin/'].UserName, Groups: GroupDetailList[?Path=='/admin/'].{Name: GroupName}}"

{
   "Users": [
       "admin-alice"
   ],
   "Groups": [
       {
           "Name": "admin"
       }
   ]
}

Running Automated Enumeration with Pacu

Similar to get-account-authorization-details w/ pacu:

Pacu (enumlab:imported-target) > run iam__enum_users_roles_policies_groups
  Running module iam__enum_users_roles_policies_groups...
[iam__enum_users_roles_policies_groups] Found 18 users
[iam__enum_users_roles_policies_groups] Found 20 roles
[iam__enum_users_roles_policies_groups] Found 8 policies
[iam__enum_users_roles_policies_groups] Found 8 groups
[iam__enum_users_roles_policies_groups] iam__enum_users_roles_policies_groups completed.

[iam__enum_users_roles_policies_groups] MODULE SUMMARY:

  18 Users Enumerated
  20 Roles Enumerated
  8 Policies Enumerated
  8 Groups Enumerated
  IAM resources saved in Pacu database.

Listing data in the Pacu database:

Pacu (enumlab:imported-target) > services
  IAM

Pacu (enumlab:imported-target) > data IAM
{
  "Groups": [
    {
      "Arn": "arn:aws:iam::123456789012:group/admin/admin",
      "GroupId": "AGPAQOMAIGYUZQMC6G5NM",
      "GroupName": "admin",
      "Path": "/admin/"
    },
    {
      "Arn": "arn:aws:iam::123456789012:group/amethyst/amethyst_admin",
      "GroupId": "AGPAQOMAIGYUYF3JD3FXV",
      "GroupName": "amethyst_admin",
      "Path": "/amethyst/"
    },
...

Extracting Insights from Enumeration Data

Analyzing admin-alice's IAM user data:

kali@kali:~$ aws --profile target iam get-account-authorization-details --filter User Group --query "UserDetailList[?UserName=='admin-alice']"

[
    {
        "Path": "/admin/",
        "UserName": "admin-alice",
        "UserId": "AIDAQOMAIGYU3FWX3JOFP",
        "Arn": "arn:aws:iam::123456789012:user/admin/admin-alice",
        "GroupList": [
            "amethyst_admin",
            "admin"
        ],
        "AttachedManagedPolicies": [],
        "Tags": [
            {
                "Key": "Project",
                "Value": "amethyst"
            }
        ]
    }
]

Querying the information about the two groups the user belongs to:

kali@kali:~$ aws --profile target iam get-account-authorization-details --filter User Group --query "GroupDetailList[?GroupName=='admin']"

[
    {
        "Path": "/admin/",
        "GroupName": "admin",
        "GroupId": "AGPAQOMAIGYUXBR7QGLLN",
        "Arn": "arn:aws:iam::123456789012:group/admin/admin",
        "GroupPolicyList": [],
        "AttachedManagedPolicies": [
            {
                "PolicyName": "AdministratorAccess",
                "PolicyArn": "arn:aws:iam::aws:policy/AdministratorAccess"
            }
        ]
    }
]


kali@kali:~$ aws --profile target iam get-account-authorization-details --filter User Group --query "GroupDetailList[?GroupName=='amethyst_admin']"

[
    {
        "Path": "/amethyst/",
        "GroupName": "amethyst_admin",
        "GroupId": "AGPAQOMAIGYUX23CDL3AN",
        "Arn": "arn:aws:iam::123456789012:group/amethyst/amethyst_admin",
        "GroupPolicyList": [],
        "AttachedManagedPolicies": [
            {
                "PolicyName": "amethyst_admin",
                "PolicyArn": "arn:aws:iam::123456789012:policy/amethyst/amethyst_admin"
            }
        ]
    }
]

Paths to go from here:

  1. Social engineer Alice's credentials -- we know there is no MFA.

  2. Searching for credentials with permission to modify admin-alice's credentials.

    1. In this case, we could look for policies with iam:"*", or iam:CreateAccessKey allowed actions.

  3. Obtaining credentials of another admin user or find a user with permissions to add users to the admin group.

    1. In this case we'd be looking for policies with iam:"*", or iam:AddUserToGroup allowed actions.

Displaying policies associated with the amethyst_admin group:

kali@kali:~$ aws --profile target iam get-account-authorization-details --filter LocalManagedPolicy --query "Policies[?PolicyName=='amethyst_admin']"

[
    {
        "PolicyName": "amethyst_admin",
        "PolicyId": "ANPAQOMAIGYUUA3PZUK57",
        "Arn": "arn:aws:iam::123456789012:policy/amethyst/amethyst_admin",
        "Path": "/amethyst/",
        "DefaultVersionId": "v7",
        "AttachmentCount": 1,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "PolicyVersionList": [
            {
                "Document": {
                    "Statement": [
                        {
                            "Action": "iam:*",
                            "Effect": "Allow",
                            "Resource": [
                                "arn:aws:iam::123456789012:user/amethyst/*",
                                "arn:aws:iam::123456789012:group/amethyst/*",
                                "arn:aws:iam::123456789012:role/amethyst/*",
                                "arn:aws:iam::123456789012:policy/amethyst/*"
                            ],
                            "Sid": "AllowAllIAMActionsInUserPath"
                        },
                        {
                            "Action": "iam:*",
                            "Condition": {
                                "StringEquals": {
                                    "aws:ResourceTag/Project": "amethyst"
                                }
                            },
                            "Effect": "Allow",
                            "Resource": "arn:aws:iam::*:user/*",
                            "Sid": "AllowAllIAMActionsInGroupMembers"
                        },
                        {
                            "Action": [
                                "ec2:*",
                                "lambda:*"
                            ],
                            "Condition": {
                                "StringEquals": {
                                    "aws:ResourceTag/Project": "amethyst"
                                }
                            },
                            "Effect": "Allow",
                            "Resource": "*",
                            "Sid": "AllowAllActionsInTaggedResources"
                        },
                        {
                            "Action": [
                                "ec2:*",
                                "lambda:*"
                            ],
                            "Condition": {
                                "StringEquals": {
                                    "aws:RequestTag/Project": "amethyst"
                                }
                            },
                            "Effect": "Allow",
                            "Resource": "*",
                            "Sid": "AllowAllActionsInTaggedResources2"
                        },
                        {
                            "Action": "s3:*",
                            "Effect": "Allow",
                            "Resource": [
                                "arn:aws:s3:::amethyst*",
                                "arn:aws:s3:::amethyst*/*"
                            ],
                            "Sid": "AllowAllS3ActionsInPath"
                        }
                    ],
                    "Version": "2012-10-17"
                },
                "IsDefaultVersion": true,
            },
    }
]

Userful search listing Users, groups, and attached managed policies:

aws --profile target iam get-account-authorization-details --filter User Group --query "UserDetailList[].{Name: UserName,Path: Path,Groups: GroupList, AttachedManagedPolicies:AttachedManagedPolicies}"
PreviousModule 23: Lateral Movement in Active DirectoryNextModule 25: Attacking AWS Cloud Infrastructure

Last updated 7 months ago

🐲