For the complete documentation index, see llms.txt. This page is also available as Markdown.

Access Keys

AWS IAM Access Keys

Theory

Access keys are long-term credentials used for programmatic access to AWS services. Each access key consists of two components: an Access Key ID that serves as a username, and a Secret Access Key that acts as a password. Unlike console passwords which are used for web-based access, access keys are used by the AWS CLI, SDKs, and direct API calls.

Access Key Format

Access keys follow specific format patterns that reveal information about their type and origin. The Access Key ID is a 20-character string, while the Secret Access Key is a 40-character string. The prefix of the Access Key ID indicates whether the credentials are permanent or temporary.

Permanent Access Keys (AKIA)

Permanent access keys start with AKIA and are associated with IAM users. These credentials never expire unless explicitly deleted or rotated by an administrator or the user themselves. Each IAM user can have up to two active access keys simultaneously, which facilitates rotation without downtime.

Access Key ID:     AKIAIOSFODNN7EXAMPLE
Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Temporary Credentials (ASIA)

Temporary credentials start with ASIA and include an additional Session Token. These credentials are issued by AWS Security Token Service (STS) when assuming roles, using federated access, or calling GetSessionToken. They automatically expire after a set duration, typically between 15 minutes and 12 hours.

Access Key ID:     ASIAIOSFODNN7EXAMPLE
Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Session Token:     FwoGZXIvYXdzEBYaDJw...
Expiration:        2024-12-31T23:59:59Z

Storage Locations

Access keys are stored in various locations across systems and applications, creating multiple opportunities for discovery and theft. The AWS CLI stores credentials in ~/.aws/credentials and configuration in ~/.aws/config by default. Applications often store keys in environment variables like AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. Configuration management tools, deployment scripts, and application config files frequently contain hardcoded credentials.

Container environments expose keys through environment variables or mounted volumes. Lambda functions receive credentials through environment variables or execution role metadata. EC2 instances can access credentials through the Instance Metadata Service (IMDS) when using IAM roles. Developer workstations may have keys in shell history, IDE configurations, or Docker configurations.

Security Risks

Access keys present significant security risks due to their widespread storage and long-lived nature. Developers frequently hardcode credentials directly in source code, which then gets committed to version control systems like GitHub. These committed secrets can remain in git history even after being removed from current files, providing a permanent record accessible to anyone with repository access.

Configuration files often store keys in plaintext, making them vulnerable to file disclosure vulnerabilities or unauthorized system access. Application logs may inadvertently capture credentials during debugging or error reporting. When keys are shared between team members through insecure channels like email or chat, they become exposed to interception and unauthorized access.

The lack of regular rotation compounds these risks. Unlike temporary credentials that expire automatically, permanent access keys remain valid indefinitely until manually revoked. This extended validity window gives attackers more time to discover and abuse compromised credentials. Organizations often have unused or forgotten access keys that maintain active permissions, creating unnecessary security exposures.

Service-Specific Credentials

Beyond standard access keys, AWS provides service-specific credentials for certain AWS services. These credentials are scoped to individual services and cannot be used for general AWS API access, providing a form of credential isolation. The primary use case is AWS CodeCommit, AWS's managed Git repository service.

Service-specific credentials for CodeCommit consist of a username and password that authenticate HTTPS Git operations against CodeCommit repositories. Unlike standard access keys that grant broad API access based on attached policies, these credentials only work with CodeCommit and cannot access other AWS services. However, they inherit the IAM user's CodeCommit permissions, so a user with codecommit:* can perform all Git operations across all repositories.

From a security perspective, service-specific credentials present an alternative privilege escalation and persistence vector. If you have iam:CreateServiceSpecificCredential permission for a target user, you can generate CodeCommit credentials for that user and access any repositories they have permission to read. This bypasses the two-access-key limit since service-specific credentials are tracked separately. Additionally, the iam:ResetServiceSpecificCredential permission allows resetting existing credentials to a new password you control, similar to password reset attacks.

Each IAM user can have up to two service-specific credentials per service. The credentials are identified by a ServiceSpecificCredentialId and can be in Active or Inactive status. AWS tracks the creation date and last authentication time, helping identify stale credentials. Organizations often overlook these creden

SSH Public Keys

SSH public keys provide an alternative authentication method for AWS CodeCommit using SSH instead of HTTPS. Each IAM user can upload up to five SSH public keys, which are then used to authenticate Git operations over SSH. The keys are identified by an SSHPublicKeyId and can be Active or Inactive.

When a user uploads an SSH public key via iam:UploadSSHPublicKey, AWS generates a unique SSH key ID in the format APKA[...]. This SSH key ID becomes part of the SSH username used for CodeCommit authentication, following the pattern SSH-KEY-ID@git-codecommit.region.amazonaws.com. The user then configures their local Git client to use their private key when connecting to CodeCommit.

From an attacker's perspective, SSH public keys provide another credential type for privilege escalation and persistence. If you have iam:UploadSSHPublicKey permission for a target user, you can generate an SSH keypair, upload the public key to their account, and use the private key to access CodeCommit repositories as that user. This technique is particularly stealthy because SSH keys generate different CloudTrail events than access key usage, potentially evading detection rules focused on access key patterns.

The iam:DeleteSSHPublicKey and iam:UpdateSSHPublicKey permissions also enable denial-of-service attacks. By deleting or deactivating a user's SSH keys, you can prevent them from accessing CodeCommit repositories until they upload new keys. This can disrupt development workflows and lock legitimate users out of critical code repositories.

Local Credential Caching

AWS credential management tools cache credentials locally to avoid repeatedly prompting for authentication or making unnecessary API calls. Understanding these caching mechanisms is essential for both credential theft from compromised systems and forensic analysis of credential usage.

The AWS CLI caches credentials in two primary locations. The ~/.aws/credentials file stores long-term credentials including IAM user access keys and credentials from various credential sources. The ~/.aws/cli/cache/ directory contains temporary credentials from assumed roles and other session-based authentication. Each cache file is named with a hash of the credential parameters and contains the temporary access key, secret key, session token, and expiration timestamp in JSON format.

For AWS SSO (IAM Identity Center) authentication, the AWS CLI caches SSO tokens in ~/.aws/sso/cache/. These cache files contain access tokens that can be used to retrieve fresh AWS credentials without re-authenticating through the SSO provider. The tokens typically have longer lifetimes than the credentials they generate, making them valuable targets for credential theft. An attacker who steals an SSO token cache file can generate valid temporary credentials for any accounts and roles the user has access to through SSO.

Additional credential caching locations include the ~/.aws/config file which may contain credential process commands or assume role configurations, environment variables like AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY that remain in memory and shell history, Docker configuration at ~/.docker/config.json which may contain credentials for ECR, and application-specific configuration files and environment variable files like .env used by development frameworks.

When compromising a system, these cache locations should be prioritized for credential harvesting. The cached credentials are often more valuable than individual access keys because they provide context about which roles the user assumes, which accounts they access through SSO, and what their normal access patterns look like. This information guides privilege escalation and lateral movement while maintaining operational security by mimicking legitimate usage patterns.

Practice

Reconnaissance

Access keys frequently leak through various channels including public code repositories, paste sites, public S3 buckets, and exposed configuration files. Attackers scan these sources looking for the characteristic AKIA pattern that identifies AWS access keys.

For comprehensive techniques on finding leaked credentials through OSINT, code repositories, and public exposures:

GitHub Recon

Once you have access to an AWS environment, enumerating existing access keys helps identify which users have programmatic access and how many keys each user possesses. This information reveals potential targets for credential theft or privilege escalation.

The AWS CLI provides commands to list and inspect access keys for users in the account. You can enumerate your own keys or, with sufficient permissions, list keys for other users.

Pacu automates the enumeration of access keys across all users in the account, providing a comprehensive view of programmatic access credentials.

ScoutSuite's IAM assessment includes access key analysis, identifying keys that haven't been rotated, unused keys, and users with multiple active keys.

CreateAccessKey Privilege Escalation

The iam:CreateAccessKey permission allows you to generate new access keys for IAM users. If you have this permission on your own user or another user, you can create additional credentials for programmatic access. Creating keys for other users is particularly powerful since you gain their permissions without needing their password.

Creating an access key for your own user provides an additional set of credentials you can use. This is useful for maintaining persistence or creating backup credentials before rotating existing keys.

If you have iam:CreateAccessKey permission on other users, you can create access keys for them and use those keys to perform actions as that user. This is a direct privilege escalation path if the target user has higher privileges.

Pacu can automatically identify and exploit CreateAccessKey permissions during privilege escalation scans.

Stealing Keys from EC2 Metadata

EC2 instances with attached IAM roles expose temporary credentials through the Instance Metadata Service (IMDS). If you gain access to an EC2 instance through SSRF, RCE, or direct SSH access, you can retrieve these credentials.

The original IMDS (version 1) uses simple HTTP GET requests without authentication, making it vulnerable to SSRF attacks.

IMDSv2 requires a session token obtained via PUT request, providing protection against SSRF attacks. However, if you have command execution on the instance, you can still retrieve credentials.

If you find an SSRF vulnerability in a web application running on EC2, you can exploit it to retrieve instance credentials even without direct access to the instance.

Stealing Keys from Lambda Functions

Lambda functions receive credentials through environment variables or execution roles. If you can invoke functions, read their code, or access their environment, you can steal these credentials.

Some developers hardcode access keys in Lambda environment variables instead of using execution roles. You can enumerate these if you have lambda:GetFunctionConfiguration permission.

Lambda functions using execution roles receive temporary credentials automatically. If you can execute code within the Lambda environment (through function invocation or code injection), you can access these credentials from environment variables.

Pacu can enumerate Lambda functions and extract environment variables that may contain hardcoded credentials.

UpdateAccessKey Status Manipulation

The iam:UpdateAccessKey permission allows you to activate or deactivate access keys. This can be used to disable other users' keys (denial of service) or reactivate old inactive keys that might have been disabled due to compromise.

If you have UpdateAccessKey permission on other users, you can disable their access keys, preventing them from using programmatic access.

Old inactive keys might have been disabled during security incidents but never deleted. Reactivating them provides credentials without the visibility of creating new keys.

DeleteAccessKey - Bypassing the Two-Key Limit

IAM users are limited to two access keys maximum. If a target user already has two active keys, attempting to create a third with iam:CreateAccessKey will fail. However, if you have iam:DeleteAccessKey permission, you can delete one of their existing keys to make room for a new key you control. This technique bypasses the two-key limit and provides a credential rotation attack vector.

This technique is particularly effective when the target user has two keys but only actively uses one. By deleting the inactive or rarely-used key, you avoid disrupting their normal operations while gaining your own access. The key deletion generates a CloudTrail event, but in environments with high IAM activity, this may not trigger immediate investigation, especially if the user isn't monitoring their own key count.

From a persistence perspective, you could also delete and recreate keys periodically to rotate your access credentials, making detection through static key monitoring more difficult. However, each deletion and creation generates CloudTrail events that could be correlated to identify the attack pattern.

CreateServiceSpecificCredential - CodeCommit Access

Service-specific credentials provide an alternative to access keys for services like CodeCommit. If you have iam:CreateServiceSpecificCredential permission for a target user, you can generate CodeCommit credentials that grant Git repository access without consuming one of their two access key slots.

The credentials inherit the user's CodeCommit permissions, so if the target user has codecommit:GitPull or codecommit:GitPush on sensitive repositories, you gain the same access. This technique is particularly valuable because:

  • Service-specific credentials are tracked separately from access keys, so security teams focusing on access key enumeration may miss them

  • Each user can have two service-specific credentials per service, providing additional credential slots

  • CodeCommit credentials only work with CodeCommit, reducing the scope of what logs might correlate the abuse

Organizations often store sensitive information in CodeCommit repositories including infrastructure-as-code configurations, application secrets, database passwords, API keys, and deployment scripts. Gaining CodeCommit access through service-specific credentials can reveal credentials for lateral movement or privilege escalation in other systems.

ResetServiceSpecificCredential - Credential Takeover

If you have iam:ResetServiceSpecificCredential permission, you can reset existing service-specific credentials to a new password you control, similar to password reset attacks on login profiles.

This attack will disrupt the legitimate user's Git access since their old password no longer works. However, in organizations where CodeCommit is used infrequently or for archived repositories, the disruption may go unnoticed long enough to exfiltrate repository contents.

UploadSSHPublicKey - SSH-Based CodeCommit Access

SSH public keys provide another authentication method for CodeCommit. If you have iam:UploadSSHPublicKey permission for a target user, you can upload your own SSH public key and use the corresponding private key to access their CodeCommit repositories.

SSH key authentication generates different CloudTrail events than HTTPS credential usage (codecommit.amazonaws.com vs git-codecommit.amazonaws.com), which may evade detection rules focused on service-specific credential patterns. Additionally, each user can upload up to five SSH keys, providing multiple credential slots for persistence.

The uploaded SSH key remains active until explicitly deleted or deactivated, providing long-term access even if the user's access keys or passwords are rotated. This makes SSH keys valuable for maintaining persistent access to code repositories during red team engagements.

Credential Cache Harvesting

When you compromise a system where AWS credentials are used, harvesting cached credentials can provide immediate access without needing to perform privilege escalation or credential creation attacks.

The AWS CLI stores credentials in standard locations that should be checked on any compromised system.

The credentials file may contain multiple profiles with different privilege levels. The config file reveals which roles the user typically assumes, providing insight into privilege escalation paths.

Temporary credentials from assumed roles are cached separately to avoid repeated STS calls.

Cached temporary credentials often have elevated permissions since users cache credentials from assumed roles rather than their base IAM user. Check all cache files to find the most privileged credentials.

AWS SSO tokens can be used to generate fresh credentials for multiple accounts and roles without re-authenticating.

SSO tokens typically have longer lifetimes than temporary credentials (hours vs minutes), making them more valuable for sustained access. A single SSO token may provide access to multiple AWS accounts and roles configured in the organization's IAM Identity Center.

Credentials in environment variables or command history can be extracted from memory or shell history files.

Environment variables are particularly valuable because they're often used for application credentials with broad permissions. Applications running with environment variable credentials typically need full access to AWS services for their functionality.

Resources

Last updated