AWS
AWS account information enumeration
AWS CLI access
The AWS Command Line Interface (AWS CLI)
can be used to access AWS resources through a command line utility. To setup the AWS CLI
environment, notably the configuration of credentials, the aws configure
command may be used.
The aws configure
will ask for the following information, that will be stored (in clear-text) in the config
and credentials
files (by default in a .aws
folder in the current's user home directory):
Access key ID
Secret access key
AWS default region
Output format
To create a Access key ID
and secret access key
, refer to the AWS official documentation.
Manual enumeration with AWS CLI
The following commands can be used to retrieve basic information about the AWS account:
Automated enumeration with ScoutSuite
Scout Suite
leverage the API provided by AWS (as well as other possible Cloud providers) to automatically enumerate the configuration of the account. It can be used to quickly gather information on the attack surface of the AWS account across all regions.
AWS logs overview
A number of log sources are available in AWS
that can be useful for incident response purposes:
CloudTrail
Logs of every operation conducted in the AWS account. Essentially logs all API calls made in the account.
For each action / operation, the following information are logged:
- Unique Event ID.
- Event name (such as ListPolicies
, AssumeRole
, etc.).
- The timestamp of the operation.
- The region the operation was conducted in.
- Information on who realized the action (IAM identity, source IP address, user agent).
- The eventual impacted resource.
- The eventual request parameters.
- ...
CloudWatch
System performance metrics, such as CPU usage, filesystem or network inputs/outputs, etc.
An additional CloudWatch
agent can be installed on EC2 hosts to forward OS-level logs to CloudWatch
.
Additionally, CloudTrail
logs can be forwarded to CloudWatch
, for instance to configure automated alerting.
Config
Logs periodically the configuration state of a number of resources (EC2
, VPC
, security groups, etc.). Can be used to detect change in configuration and retrieve historical data on configuration changes (who and when was a given resource created / modified).
S3 Access Logs
Logs bucket-level activities, i.e access, upload, modification, and deletion of data stored in a S3 bucket
(versus operation on the bucket object itself as logged by CloudTrail
).
S3 Access Logs
i disabled by default and must be enabled on a per bucket basis.
VPC Flow Logs
Logs VPC
-level IP
network traffic to CloudWatch
.
Different version of VPC Flow Logs
, 2 to 5 to date, can be enabled. Higher versions record an increased number of fields per record. The version 2
, enabled by default, records the following fields (in order):
- version number.
- account id (AWS account ID of the owner of the source network interface for which traffic is recorded).
- interface id (ID of the network interface for which the traffic is recorded).
- source address.
- destination address.
- source port.
- destination port.
- network protocol.
- number of packets transferred during the "flow" log.
- number of bytes transferred during the "flow" log.
- start of the "flow" log.
- end of the flow log.
- whether the traffic was accepted (ACCEPT
) or rejected (REJECT
).
- status of the flow log.
For more information on VPC Flow Logs
, refer to the official AWS documentation.
WAF Logs
Logs requests processed by the AWS WAF
service. WAF Logs
can notably be forwarded to CloudWatch
or stored in a S3
bucket.
Information about the request (source IP, eventual requests headers, eventual parameters, etc.) as well as the rule matched are logged.
AWS logs collection
Multi-regions CloudTrail logs export
The awsCloudTrailDownload.py
Python script can be used to download the CloudTrail
logs across all regions.
Automated logs export with Invictus-AWS
The Invictus-AWS
Python script can be used to retrieve information about the environment (service usage and configuration) and export logs from a number of sources (CloudTrail
, CloudWatch
, S3 Access Logs
, ...) to an S3
bucket. Invictus-AWS
is region bound.
CloudWatch logs export with awslogs
The awslogs
utility can be used to access and filter the AWS CloudWatch
logs. awslogs
requires the permissions associated with the CloudWatchLogsReadOnlylAccess
policy.
CloudTrail logs analysis
CloudTrail key fields
eventTime
Event timestamp in UTC
.
awsRegion
The region the request was made to, such as us-east-1
.
eventSource
The service the request was made to.
Such as s3.amazonaws.com
for S3
buckets, sts.amazonaws.com
for the Security Token Service (STS)
for temporary credentials request, etc.
eventName
The request action, matching one of the API for that service.
For example, AssumeRole
, ListBuckets
, SendCommand
, etc.
errorCode
The error code and human-readable error message associated with an event if (and only if) the operation failed.
readOnly
Whether the operation is a read-only operation (true
or false
).
userIdentity
Information about the user that made the request.
* userIdentity.type
: the type of the identity.
Possible types:
- Root
: account root user.
- IAMUser
: IAM user.
- AssumedRole
: temporary security credentials obtained with a role by making a call to the AWS STS
's AssumeRole
API.
- Role
:
- FederatedUser
: temporary security credentials for a federated user (Active Directory
, AWS Directory Service
, etc.), obtained via a call to the AWS STS
's GetFederationToken
API. - AWSAccount
: An account from another tenant / AWS account.
- AWSService
: AWS account that belongs to an AWS service.
* [Optional] userIdentity.userName
: Human readable name of the identity that made the call.
Generally only available for IAMUser
or Root
identity.
* [Optional] userIdentity.arn
: ARN
of the entity (user or role) that made the call.
* [Optional] userIdentity.principalId
: Unique identifier for the entity that made the call.
For temporary security credentials, this value includes the session name. For instance, for AssumedRole
events, the principalId
is the unique identifier that contains the role ID and the role session name returned in the AssumeRole
event's responseElements.assumedRoleUser.assumedRoleId
.
* [Optional] userIdentity.accountId
: The account that owns the entity that granted permissions for the request
* [Optional] userIdentity.accessKeyId
: The eventual access key ID
that was used to make the request.
Access key IDs
beginning with AKIA
are long-term credentials (for an IAM user
or the AWS account root user) while access key IDs
beginning with ASIA
are temporary credentials (created using AWS STS
operations).
* [Optional] userIdentity.sessionContext
: Populated for requests made with temporary security credentials to contain information about the session that was created.
userIdentity.sessionContext.creationDate
: when the session was created.
userIdentity.sessionContext.mfaAuthenticated
: whether the initial credentials were authenticated MFA.
userIdentity.sessionContext.
:
userIdentity.sessionContext.sourceIdentity
: the original identity (user or role) making the request (with type
, arn
, userName
sub-fields).
sourceIPAddress
The IP address that the request was made from.
For requests from services within AWS, only the DNS
name of the service (for example ec2.amazonaws.com
) is displayed.
userAgent
The User-Agent
through which the request was made.
sessionCredentialFromConsole
Whether the operation was conducted through the web console (true
or false
).
resources
A list of resource(s) accessed in the event.
For each resource, the following fields may be available:
- type
: resource type identifier (in the format: AWS::<AWS_SERVICE_NAME>::<AWS_DATA_TYPE_NAME>
).
- ARN
: ARN
of the resource.
- accountId
: account that owns the resource.
requestParameters
The parameters, if any, that were sent with the request.
For example, requestParameters.bucketName
, requestParameters.userName
, etc.
responseElements
The response element(s) for actions that make changes (create, update, or delete actions).
For example, responseElements.user.createDate
, responseElements.accessKey.accessKeyId
, etc.
CloudTrail notable API / events
eventSource
eventName
Type
Description
sts.amazonaws.com
GetCallerIdentity
Reconnaissance
Return details about the IAM user or role whose credentials are used to call the operation.
iam.amazonaws.com
ListUsers
Reconnaissance
Enumerate the IAM users in the AWS account, that match the optional specified path prefix requestParameters.pathPrefix
.
iam.amazonaws.com
ListRoles
Reconnaissance
Enumerate the IAM roles in the AWS account, that match the optional specified path prefix requestParameters.pathPrefix
.
iam.amazonaws.com
ListGroups
Reconnaissance
Enumerate the IAM groups in the AWS account, that match the optional specified path prefix requestParameters.pathPrefix
.
iam.amazonaws.com
ListGroupsForUser
Reconnaissance
List the IAM
groups that the specified IAM
user (by requestParameters.userName
) belongs to.
iam.amazonaws.com
ListPolicies
Reconnaissance
Enumerate the IAM policies in the AWS account, that match the optional specified path prefix requestParameters.pathPrefix
.
iam.amazonaws.com
ListAttachedUserPolicies
ListAttachedGroupPolicies
ListAttachedRolePolicies
Reconnaissance
List the managed policies that are attached to the specified IAM
user / group / role.
Notable fields:
ListAttachedUserPolicies
: requestParameters.userName
ListAttachedGroupPolicies
: requestParameters.groupName
ListAttachedRolePolicies
: requestParameters.roleName
iam.amazonaws.com
ListUserPolicies
ListGroupPolicies
ListRolePolicies
Reconnaissance
List the names of the inline policies embedded in the specified IAM
user / group / role.
Notable fields:
ListUserPolicies
: requestParameters.userName
ListGroupPolicies
: requestParameters.groupName
ListRolePolicies
: requestParameters.roleName
iam.amazonaws.com
GetPolicy
Reconnaissance
Get information about the specified managed policy (by requestParameters.policyArn
), including the policy's default version and the total number of IAM
users, groups, and roles to the policy is attached to.
iam.amazonaws.com
GetPolicyVersion
Reconnaissance
Get information about the specified version of the specified managed policy, including the policy document.
Notable fields:
requestParameters.policyArn
requestParameters.versionId
s3.amazonaws.com
ListBuckets
Reconnaissance
List the buckets owned by the authenticated sender of the request.
ec2.amazonaws.com
GetConsoleScreenshot
Reconnaissance
Take a screenshot of a running instance.
Notable fields:
requestParameters.instanceId
requestParameters.wakeUp
: whether a keystroke input should be simulated to wake up an instance in standby.
ec2.amazonaws.com
DescribeInstances
Reconnaissance
Enumerate and retrieve information on all or the specified instances.
Notable fields:
requestParameters.instanceId
: optional list of instance id(s) to enumerate.
requestParameters.filter
: optional filter(s).
sts.amazonaws.com
AssumeRole
Privilege escalation
Return a set of temporary security credentials that can be used to access AWS resources under the privileges granted by the role. A role is a set of policies.
Can be called by IAM
principal (user or role).
Notable fields:
requestParameters.roleArn
: The ARN
of the role to assume.
requestParameters.roleSessionName
: a unique identifier (in the form of i-089eb6ce74072ae1f
) to identify the session.
requestParameters.durationSeconds
: the validity period of the temporary credentials. Minimum value of 900 seconds up to the maximum session duration set for the role (maximum 43200 seconds).
responseElements.assumedRoleUser.arn
: the ARN
of the temporary security credentials, that will be logged under userIdentity.arn
(for API calls made during the session).
responseElements.assumedRoleUser.assumedRoleId
: a unique identifier containing the role ID and the role session name, that will be logged under userIdentity.principalId
(for API calls made during the session).
responseElements.credentials.accessKeyId
: the access key ID that identifies the temporary security credentials, that will be logged under userIdentity.accessKeyId
(for API calls made during the session).
responseElements.credentials.expiration
: the date on which the current credentials expire.
sso.amazonaws.com
GetRoleCredentials
Privilege escalation
Return a set of temporary security credentials.
Similar to AssumeRole
, but can (and must) be called by AWS SSO users
, which are not directly IAM
principals. AWS SSO users
can have permission to assume IAM
roles and must do so through GetRoleCredentials
.
Notable fields: requestParameters.roleName
responseElements.credentials.roleCredentials.accessKeyId
responseElements.credentials.roleCredentials.expiration
iam.amazonaws.com
AttachUserPolicy
AttachGroupPolicy
AttachRolePolicy
Privilege escalation
Attach the specified managed policy to the specified IAM
user / group / role. A policy is the most atomic level of privileges that can be granted.
As a privilege escalation path, the compromised user may be a member of the impacted group or may be able to assume the impacted role.
Notable fields:
requestParameters.policyArn
AttachUserPolicy
: requestParameters.userName
AttachGroupPolicy
requestParameters.groupName
:
AttachRolePolicy
: requestParameters.roleName
iam.amazonaws.com
PutUserPolicy
PutGroupPolicy
PutRolePolicy
Privilege escalation
Add (or update) an inline policy embedded in the specified IAM
user / group / role. A policy is the most atomic level of privileges that can be granted.
Notable fields:
requestParameters.policyName
requestParameters.policyDocument
: policy in JSON format.
PutUserPolicy
: requestParameters.userName
PutGroupPolicy
: requestParameters.groupName
PutRolePolicy
: requestParameters.roleName
iam.amazonaws.com
CreatePolicyVersion
Privilege escalation
Create a new version of the specified managed IAM
policy, allowing the definition of new permissions (ultimately granted to IAM
users, groups, or Roles the policy is linked to).
Notable fields:
requestParameters.policyArn
requestParameters.policyDocument
: policy in JSON format.
requestParameters.setAsDefault
: whether the new policy version should be set as default, i.e should become the operative version (true
of false
).
iam.amazonaws.com
SetDefaultPolicyVersion
Privilege escalation
Set the specified preexisting version of the specified policy as the policy's default (operative) version.
The policy version set will impact the IAM
users, groups, or Roles the policy is linked to, potentially opening privilege escalation vectors.
Notable fields:
requestParameters.policyArn
requestParameters.versionId
iam.amazonaws.com
AddUserToGroup
Privilege escalation Persistence
Add the specified user to the specified group.
Notable fields:
requestParameters.userName
requestParameters.groupName
iam.amazonaws.com
CreateAccessKey
Privilege escalation Persistence
Create a new AWS secret access key for the user specified by requestParameters.userName
.
Notable fields:
responseElements.accessKey.accessKeyId
responseElements.accessKey.createDate
responseElements.accessKey.status
responseElements.accessKey.userName
iam.amazonaws.com
CreateLoginProfile
Privilege escalation Persistence
Create a password for the user specified by requestParameters.userName
(to allow the user to access the AWS Management Console).
As a privilege escalation vector, a user (userIdentity.userName
) can create a password for a (more privileged) user (requestParameters.userName
) to connect as the user through the management console and elevate privileges.
iam.amazonaws.com
UpdateLoginProfile
Privilege escalation Persistence
Create a password for the user specified by requestParameters.userName
(to allow the user to access the AWS Management Console).
As a privilege escalation vector, a user (userIdentity.userName
) can reset the password of a (more privileged) user (requestParameters.userName
) to compromise that user and elevate privileges.
ec2.amazonaws.com
RunInstances
Execution Persistence
Create and run new EC2 instance(s).
Notable fields:
requestParameters.instanceType
The requestParameters.instancesSet.items{}
list contains (for each request instance):
imageId
tags{}
list with a Key
=Name
with Value
=<INSTANCE_NAME>
keyName
for the key credentials associated with the instance.
The responseElements.instancesSet.items{}
list contains (for each created instance):
instanceId
keyName
subnetId
privateIpAddress
ssm.amazonaws.com
SendCommand
Execution
Run command(s) on one or more instances.
Notable fields:
requestParameters.instanceIds
/ responseElements.command.instanceIds
: list of instance ids for the command execution.
requestParameters.documentName
/ responseElements.documentName
: name of the SSM document to run (such as AWS-RunShellScript
or AWS-RunPowerShellScript
).
requestParameters.parameters
: required and optional parameters specified in the document being run (can be HIDDEN_DUE_TO_SECURITY_REASONS
for shell / powershell execution).
ssm.amazonaws.com
StartSession
Execution
Initiate a connection to the target instance.
Notable fields:
requestParameters.target
: target instance id.
responseElements.sessionId
: identifier of the session.
responseElements.streamUrl
: an URL on the target instance SSM Agent
used by the Session Manager client
to send commands and receive output.
responseElements.tokenValue
: a token used to authenticate the connection (hidden in CloudTrail
).
ssm.amazonaws.com
ResumeSession
Execution
Reconnect a connection after it has been disconnected (but not terminated).
Notable fields:
requestParameters.sessionId
: identifier of the disconnected session.
responseElements.sessionId
: identifier of the session.
responseElements.streamUrl
: an URL on the target instance SSM Agent
used by the Session Manager client
to send commands and receive output.
responseElements.tokenValue
: a token used to authenticate the connection (hidden in CloudTrail
).
ec2.amazonaws.com
GetPasswordData
Execution Persistence
Retrieves the encrypted administrator password for a running Windows instance. The password is encrypted with the key pair specified when the instance was launched.
Notable fields:
requestParameters.instanceId
ec2.amazonaws.com
ModifyInstanceAttribute
Execution Persistence
Modify the specified attribute of the specified instance.
A modification of the userData
attribute can be used to execute code at boot time, requiring a restart of a running instance (StopInstances
then StartInstances
).
Does not allow the modification of the long-terme key pair(s) associated with an instance. There is no AWS API to conduct such operation.
Notable fields:
requestParameters.instanceId
requestParameters.attribute
(userData
for the user data).
requestParameters.userData
(specified user data).
ec2.amazonaws.com
SendSSHPublicKey
Execution
Push a temporary SSH public key to the specified EC2 instance for use by the specified user. The key remains for 60 seconds. Used by the EC2 Instance Connect
service for SSH
access (directly or through the service web-based interface).
Notable fields:
requestParameters.instanceId
lambda.amazonaws.com
CreateFunction
Execution Persistence
Create a new Lambda function.
Notable fields:
requestParameters.functionName
requestParameters.code
but doesn't include the ZipFile
parameter (that contains the base64-encoded contents of the deployment package).
lambda.amazonaws.com
UpdateFunctionCode
Execution Persistence
Update an existing Lambda function's code.
Notable fields:
requestParameters.functionName
requestParameters.code
but doesn't include the ZipFile
parameter (that contains the base64-encoded contents of the deployment package).
s3.amazonaws.com
PutBucketAcl
Exfiltration
Set the ACL
of the specified bucket. Note that the use of ACL
for S3
is generally deprecated (in favor of using policy).
Notable fields:
requestParameters.bucket
requestParameters.AccessControlPolicy.AccessControlList.Grant.Grantee.URI
array : URIs for the container for the entity being granted permissions.
If the array contains the string http://acs.amazonaws.com/groups/global/AuthenticatedUsers
or http://acs.amazonaws.com/groups/global/AllUsers
, the specified bucket is made public.
s3.amazonaws.com
GetObject
Data access
AWS CloudTrail supports Amazon S3 Data Events
, but is not enabled by default.
Retrieve objects from Amazon S3
, via the associated API.
Access through the web interface (or a static website leveraging a S3 bucket
) will not be logged under CloudTrail
(but can be logged in S3 server access logs
).
ses.amazonaws.com
GetAccount
ListIdentities
VerifyEmailIdentity
UpdateAccountSendingEnabled
Impact (phishing)
Obtain information about the email-sending status and capabilities of the Amazon SES
account (in the current region).
Return a list containing all of the identities (email addresses and domains) of the Amazon SES
account (in the current region).
Add an email address to the list of identities Amazon SES
account (in the current region) and attempt to verify it.
Enable (or disables email) sending across the entire Amazon SES account
in the current AWS Region.
Usage of these APIs by threat actors have been identified in the wild to conduct phishing campaigns following an identity compromise.
iam.amazonaws.com
CreateUser
Persistence
Create a new AWS user in the account.
Notable fields:
responseElements.user.arn
responseElements.user.createDate
responseElements.user.userId
responseElements.user.userName
ec2.amazonaws.com
CreateKeyPair
Persistence
Create a key pair with the specified name in the AWS Region.
Notable fields:
requestParameters.keyName
/ responseElements.keyName
responseElements.keyFingerprint
responseElements.keyPairId
ec2.amazonaws.com
ImportKeyPair
Persistence
Import the public key (previously created), only providing the public key to AWS.
Notable fields:
requestParameters.keyName
/ responseElements.keyName
responseElements.keyFingerprint
responseElements.keyPairId
sts.amazonaws.com
GetSessionToken
Credentials access Persistence
Return a set of temporary credentials for an AWS account
or IAM user
.
The temporary security credentials created by GetSessionToken
can be used to make API calls to any AWS service with the following exceptions:
- Calls to IAM
API operations are prohibited unless MFA authentication information is included in the request.
- Calls to STS
API are prohibited (except AssumeRole
and GetCallerIdentity
).
Notable fields:
responseElements.accessKeyId
responseElements.expiration
CloudTrail logs manual analysis with jq
The jq
utility supports querying JSON formatted data and can be used to select and filter events from CloudTrail
exported logs.
The following queries illustrate how jq
can be used to select, order, and filter events from CloudTrail
JSON logs:
References
https://www.youtube.com/watch?v=VLIFasM8VbY
https://docs.aws.amazon.com/whitepapers/latest/aws-security-incident-response-guide/logging-and-events.html
https://www.chrisfarris.com/post/aws-ir/
https://www.datadoghq.com/blog/monitoring-cloudtrail-logs/
https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-record-contents.html
https://www.wiz.io/blog/hunting-for-signs-of-persistence-in-the-cloud-an-ir-guide
https://docs.datadoghq.com/fr/security/default_rules/#cat-cloud-siem-log-detection
https://docs.sekoia.io/xdr/features/collect/integrations/cloud_and_saas/aws/aws_cloudtrail/
https://docs.aws.amazon.com/fr_fr/lambda/latest/dg/logging-using-cloudtrail.html
https://easttimor.github.io/aws-incident-response/
https://stackoverflow.com/questions/61257189/ec2-instance-connect-and-iam-public-keys
https://docs.datadoghq.com/fr/security/default_rules/aws-bucket-acl-made-public/
https://cloud.hacktricks.xyz/pentesting-cloud/aws-pentesting/aws-privilege-escalation/aws-iam-privesc
https://unit42.paloaltonetworks.com/compromised-cloud-compute-credentials/
https://gist.github.com/kmcquade/33860a617e651104d243c324ddf7992a
Last updated