Recon
CSP Enumeration
Domain-based
Domain reconnaissance is a passive technique used early in attacks to gather public data without alerting the target. Starting with a domain name (e.g., example.com
), the goal is to identify infrastructure, hosting details, and subdomains. A recursive approach is essential—each discovery can lead to more.
Every domain has authoritative name servers that store its DNS records. Identifying them reveals who manages the domain’s DNS, often pointing to the cloud provider or registrar. For example, name server queries might show the , which can be verified via .
To identify where a site is hosted, we can resolve the domain and then perform a reverse IP lookup. In this case, the result shows the service is hosted on an AWS EC2 instance.
To discover more subdomains, automated tools like dnsenum
can be used.
S3 Buckets
Public cloud infrastructure often uses predictable hostnames that reveal the service in use. For example, a reverse DNS lookup might return ec2-18-102-34-210.compute-1.amazonaws.com
, indicating an AWS EC2 instance. Browser developer tools can aid in recon. In the Network tab, each row lists the file name and the domain it originated, such as:
The above URL:
suggests the use of
the bucket name:
example-assets-public-mnzpytrl
the object key:
sites/www/images/randomphoto.jpg
.
Visiting the bucket URL without the object path may reveal misconfigured permissions, such as directory listing, indicating that the bucket is publicly readable.
S3 permissions allow public access at the object level even if the bucket is private.
Or generate bucket naming variations with:
API Enumeration
AccountID Discovery
Cloud platforms like AWS let users share resources internally or publicly. While this enables collaboration, misconfigurations can expose sensitive data. Some resources are meant to be shared, but others may become publicly accessible by mistake. Under the AWS Shared Responsibility Model, securing shared data is the customer’s job—a common source of risk. Unlike web apps with visible URLs, these resources typically lack public endpoints. They’re discoverable only by querying the AWS API, often using the AWS CLI.
Via Public AMIs
An AMI is a blueprint for launching EC2 instances. It includes an and may also contain apps, configs, or user data. AMIs can be shared publicly—intentionally (e.g., open-source) or unintentionally due to misconfigurations.
We can enumerate the target's AccountID
via filtering the AMI's metadata.
Using the same principles, we can search for publicly available and snapshots.
Via IAM Policies
An attacker using their own AWS account can try to access misconfigured S3 buckets owned by another organization. If access is granted based on loose or overly broad policies, it may reveal sensitive data or even the account ID of the target. The attacker’s approach involves:
Creating a new IAM user to simulate a low-privilege attacker
Crafting a permissive IAM policy which includes a condition that matches certain account IDs
Using that policy to test access against external S3 buckets
Iterating on the policy to discover the correct account ID range
The
enum
user simulates a clean slate attacker with no permissions.
The attacker writes a policy allowing access only if the resource's AWS account ID starts with a specific prefix, in this case 0
.
The attacker now changes the wildcard condition to match different account ID prefixes until access is granted.
Update the policy to try a different prefix:
This time the command succeeds (e.g., returns a directory listing like PRE sites/
), thus, the attacker has confirmed that the resource is owned by an account beginning with 7
. By incrementally modifying the account ID prefix, the attacker can continue the process:
Cross-Account Access
Previously, we extracted an AWS account ID. Now, we’ll explore how to enumerate internal IAM identities (users or roles) in a known account by analyzing policy-based API responses. In AWS, cross-account access allows resources to be shared with just some specific external accounts, rather than the public. IAM policies use a Principal
field to specify the target identity (e.g., user or role). If that identity doesn’t exist, AWS returns an error—this can be used to verify if an identity is valid.
Define a bucket policy targeting a specific user in the victim account.
If no errors occur, the policy is applied successfully, meaning the enum
user exists in the target account. If we apply the policy for a non-existent user, we receive an error message.
In a similar manner, IAM roles can also be discovered by setting up trust policies and observing the responses. We can use pacu
to achieve that.
This approach allows attackers to enumerate and even assume roles within a target AWS account—often serving as a pivot for deeper access.
Initial IAM Recon
Identity Details
After compromising AWS credentials, attackers begin by exploring what the account can access—all while staying within valid permissions to avoid detection. Though AWS logs actions via CloudTrail, alerts only trigger if properly configured. As a result, legitimate-but-curious activity often goes unnoticed.
Assuming we’ve obtained a set of AWS access keys (target
), our first goal is to determine whether they are still valid, what account they belong to, and ideally do so without triggering logs in the target's CloudTrail. The most common way to verify credentials is via the get-caller-identity
subcommand. However, this action is always allowed (even if explicitly denied) and always logged in the target’s CloudTrail.
For stealthier reconnaissance, we can use the get-access-key-info
subcommand. This only reveals the account ID tied to the access key, and it logs only to the caller's account, not the account associated with the key. Therefore, we run it from a separate AWS account (e.g., an attacker-controlled one). Below is an example using an “attacker” profile configured with separate credentials:
Another stealthy approach for revealing identity details is via failed API calls; these aren't logged by default in Cloudtrail.
CloudTrail logging behavior varies by region. For example, the below command may show up in us-east-2
logs—but remain invisible in the default region (us-east-1
) if not explicitly configured. Attackers exploit this gap to probe quieter regions.
IAM Permissions
IAM policies determine what a user can do. Permissions may be:
Inline (directly attached to the user)
Managed (reusable, attached to multiple identities)
Inherited via group membership
AWS Managed Policies are pre-defined and often too permissive, allowing broad access to many resources.
To see the policy conten, we must first find its exact version.
If the compromised account lack the privileges to query for IAM-related infomation, permissions can be inferred via brute-force API probing with tools such as pacu
→ iam__bruteforce_permissions
, awsenum
, and enumerate-iam
.
The above tools can generate a lot of noise; a manual, service-aware approach is stealthier in sensitive environments.
IAM Resources Recon
With access to the compromised clouddesk-plove
IAM user, we begin enumeration. The user belongs to the support
group and inherits the AWS-managed SupportUser
policy, designed for support roles. According to AWS, this policy grants broad read-only access—enough to reveal sensitive information about the environment’s security posture.
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
We can start by retrieving and inspecting the policy to confirm IAM read permissions.
This allows nearly all get
and list
operations on IAM. We identify these using:
We can learn about any of the commands by running
aws iam <command> help
.
We can then run get-account-summary
:
The output includes useful information:
18 users, 20 roles, 8 groups
No MFA enabled (
MFADevices: 0
,MFADevicesInUse: 0
)No MFA enable for the
root
account (AccountMFAEnabled: 0
)
This is a serious weakness—any compromised credentials are immediately usable without second-factor authentication. We continue by enumerating users, groups, and roles:
These commands reveal identity paths and naming conventions (e.g., admin-alice
, admin
) that may indicate elevated privileges and warrant deeper analysis.
To investigate permissions at a more granular level, we can list the IAM policies created within this account, limiting the scope to locally-managed, i.e., customer-managed and not AWS-managed policies, and currently-attached policies, i.e., policies attached to an IAM identity.
One notable policy: manage-credentials
—its name implies potential for key rotation or MFA manipulation, both possible paths to escalation. We can fetch all attached identity definitions using:
To run
get-account-authorization-details
, the account needsGetAccountAuthorizationDetails
, which is rarely granted directly but often included via broader wildcards likeiam:Get*
.
Explicing Deny Bypass
During this phase, we enumerated the deny_challenges_access
policy which is attached to our compromised user.
Explicit denies always override allows, signaling the admin intentionally blocked access to this policy. However, IAM restrictions must account for both what’s explicitly denied and what’s still implicitly allowed. Thus, when we run a broader command that retrieves all locally managed policies in the account, hoping that the forbidden policy might be included in the output.
This applies a global Deny
to all tagged resources (challenge=true
). Despite the explicit block, we accessed it through broader permissions—a classic example of indirect access.
Processing API Responses
The AWS CLI returns JSON by default, which can be filtered using JMESPath—a query language tailored for JSON. This helps extract and transform key data during enumeration, especially from verbose commands like iam get-account-authorization-details
.
The output includes a UserDetailList
array of user objects with fields like UserName
, UserId
, Arn
, and GroupList
. To isolate usernames:
JMESPath queries (--query
) run client-side, while filters (--filter
) run server-side. To retrieve multiple fields we can use the [key1, key2, key3]
or the labeled keys format {Identifier1: key1, Identifier2: key2, IdentifierN: keyN}
format:
To filter users with names containing admin
:
For nested filtering—e.g., users and groups under /admin/
paths:
Or combine conditions:
Automated Enumeration
This data is stored in Pacu’s internal SQLite database.
Extracting Insights
Once AWS IAM enumeration is complete, the next step is analysis—turning raw data into actionable findings. This is key for identifying privilege escalation paths or misconfigurations. We must first determine what we're looking for: elevated privileges, policy gaps, or tagging misuse.
Output shows admin-alice
is in admin
and amethyst_admin
groups, tagged with Project: amethyst
. While the user has no direct policies, group memberships imply privilege inheritance.
Attribute-Based Access Control (ABAC) uses attributes (like tags) to control access, making tag analysis crucial.
The admin
group is attached to the AWS-managed AdministratorAccess
policy, and the amethyst_admin
group uses the amethyst_admin
custom policy.
The policy grants broad IAM permissions (e.g., iam:*
) but scopes them to resources tagged with Project:amethyst
or located under specific paths. While this appears restrictive, it can be dangerously permissive—especially when those tags overlap with high-privilege resources. The wildcard use (iam:*
) itself raises concerns about over-permissiveness. Two privilege escalation paths emerge:
Direct Access Abuse
Compromise
admin-alice
via phishing or exposed credentialsExploit absence of MFA
Group-Based Escalation
Users in the
amethyst_admin
group can useiam:CreateAccessKey
onadmin-alice
Add themselves to the
admin
group usingiam:AddUserToGroup
The critical issue is that admin-alice
is both tagged with Project:amethyst
and a member of amethyst_admin
. This allows other group members to perform privileged IAM actions on her—including creating access keys—enabling escalation from lower-privileged users to full admin access. This unintended overlap of tagging and group membership results in a serious security misconfiguration.
Last updated
Was this helpful?