ConsoleLogin in CloudTrail: Reading AWS Console Sign-In Events
Published
One attempt to sign in to the AWS Management Console, by the root user, an IAM user or a federated user; responseElements.ConsoleLogin says whether it worked and additionalEventData.MFAUsed whether MFA was used.
In AWS's example records: eventCategory: ManagementmanagementEvent: truereadOnly: false
AWS's description
CloudTrail logs attempts to sign in to the AWS Management Console, the AWS Discussion Forums, and the AWS Support Center. All IAM user and root user sign-in events, as well as all federated user sign-in events, generate records in CloudTrail log files. For information about finding and viewing logs, see Finding your CloudTrail log files and Downloading your CloudTrail log files.
Source: CloudTrail User Guide: AWS Management Console sign-in events · copied from AWS's documentation and refreshed weekly
Fields that matter in an investigation
| Field | What it tells you |
|---|---|
| 1responseElements.ConsoleLogin | Success or Failure, the outcome of the attempt. A failed console password shows up here, not in errorCode, which AWS's failed sign-in examples do not carry. |
| 2errorMessage | Why it failed. Failed authentication is a wrong password for a real user; No username found in supplied account means the name typed is not a user in the account. |
| 3additionalEventData.MFAUsed | Yes or No, whether this sign-in used an MFA device. A successful sign-in with No for a privileged user or for root is the first thing to check. |
| 4userIdentity.type | IAMUser for an IAM user's password, Root for the account's root user, AssumedRole for a federated user in AWS's examples. Treat every Root sign-in as worth a look. |
| 5userIdentity.userName | The IAM user name entered on the sign-in page. When that name does not exist, CloudTrail writes HIDDEN_DUE_TO_SECURITY_REASONS instead, because people sometimes type a password into the name box. |
| 6userIdentity.arn | The identity that signed in. Some failed records carry a user name but no ARN, so group failures by userName and sourceIPAddress. |
| 7sourceIPAddress | The address the browser connected from. Compare with your office and VPN ranges, and check unknown addresses against blocklists. |
| 8userAgent | The browser and operating system. A user who suddenly signs in from a different browser and address deserves a closer look. |
| 9awsRegion | Not the user's location. Root sign-ins are recorded in us-east-1, us-east-2 or us-west-2, IAM user sign-ins in a Region that depends on the sign-in endpoint. |
| 10tlsDetails.clientProvidedHostHeader | The sign-in endpoint the browser used, such as us-east-1.signin.aws.amazon.com in AWS's IAM user examples and signin.aws.amazon.com in its root examples. |
Every field is checked on each build against AWS's CloudTrail record contents and userIdentity documentation and the example and recorded ConsoleLogin records shown below.
What the record looks like
AWS's example: IAM user, successful sign-in without MFA (source)
Numbered lines are the fields in the table.
AWS's example: IAM user, successful sign-in with MFA
Numbered lines are the fields in the table.
AWS's example: IAM user, unsuccessful sign-in
Numbered lines are the fields in the table.
AWS's example: Root user, successful sign-in without MFA
Source · public IP addresses replaced with documentation addresses
Numbered lines are the fields in the table.
AWS's example: Root user, successful sign-in with MFA
Source · public IP addresses replaced with documentation addresses
Numbered lines are the fields in the table.
AWS's example: Root user, unsuccessful sign-in
Source · public IP addresses replaced with documentation addresses
Numbered lines are the fields in the table.
AWS's example: Example event records for federated users
Source · public IP addresses replaced with documentation addresses
Numbered lines are the fields in the table.
AWS's example: Example sign-in failure event in CloudTrail log file
Numbered lines are the fields in the table.
AWS's example: Example sign-in failure event caused by incorrect user name
Numbered lines are the fields in the table.
Recorded during an attack simulation: Stratus Red Team technique aws.initial-access.console-login-without-mfa
Show the recorded ConsoleLogin record
Numbered lines are the fields in the table.
A real CloudTrail record from a test detonation, published by Stratus Red Team (Datadog, Apache License 2.0) and anonymized there; account IDs, addresses, access key IDs and session tokens are replaced here with AWS's documentation values, and the operator's user name with "operator". The anonymizer also changes values such as the Region.
What it records
CloudTrail writes a ConsoleLogin record each time someone tries to sign in to the AWS Management Console: the root user, an IAM user with a password, or a federated user arriving through an identity provider. The event comes from signin.amazonaws.com, and in AWS’s example records it carries eventType AwsConsoleSignIn, is a management event and has readOnly set to false.
The outcome is in responseElements.ConsoleLogin, either Success or Failure. Failed attempts add errorMessage but no errorCode, which is the detail most queries get wrong. AWS’s examples show two reasons: Failed authentication (a real user, wrong password) and No username found in supplied account (no such user, and the name typed is replaced by HIDDEN_DUE_TO_SECURITY_REASONS). additionalEventData.MFAUsed records whether an MFA device was used, additionalEventData.LoginTo the console address the sign-in led to, and requestParameters is always null because the password is never logged.
The Region in the record is the sign-in endpoint’s, not the user’s. Root sign-ins are recorded in us-east-1, us-east-2 or us-west-2. An IAM user signing in through the global endpoint is recorded in us-east-1, or in us-east-2, eu-north-1 or ap-southeast-2 when the browser holds an account alias cookie, and a Regional endpoint records its own Region. A search limited to the Region you work in misses sign-ins, so query a multi-Region or organization trail.
When it matters
Console sign-ins are where stolen passwords turn into hands-on access, and the record holds enough to separate routine use from takeover:
- Root user sign-ins. In most accounts the root user is used for a handful of tasks a year. Any
userIdentity.typeofRoot, successful or not, should be explained by someone. - Success without MFA.
MFAUsedset toNoon a successful sign-in by an administrator or by root means a password alone opened the console. - Many failures, then a success. Several
Failed authenticationrecords from onesourceIPAddressagainst one user name is password guessing; failures against many names from one address is spraying, and a run of hidden user names means the names themselves are being guessed. ASuccessfrom the same address afterwards means a password worked (MITRE ATT&CK T1110, then T1078.004). - A new console user. A
ConsoleLoginby an IAM user who normally works only with access keys, shortly after aCreateLoginProfileorUpdateLoginProfilefor that user, is a classic way to turn a stolen key into console access.
How to investigate
- Pull every
ConsoleLoginfor the account and period from all Regions, then split byuserIdentity.typeand outcome. - For failures, group by
sourceIPAddress,errorMessageanduserIdentity.userName, and look for a later success from the same address. Some failed records carry the user name without an ARN, so join on the name. - For successes, check
MFAUsed, comparesourceIPAddressanduserAgentwith the user’s history, and look forDeactivateMFADevice,CreateLoginProfileorUpdateLoginProfilecalls involving the same user beforehand. - Follow the session: search the next hours for calls by the same
userIdentity.arnfrom the same address.
Failed sign-ins by source address in Microsoft Sentinel, with any success from that address in the same week:
AWSCloudTrail
| where TimeGenerated > ago(7d)
| where EventName == "ConsoleLogin"
| extend Outcome = tostring(parse_json(ResponseElements).ConsoleLogin)
| summarize Failures = countif(Outcome == "Failure"), Successes = countif(Outcome == "Success"),
Users = make_set(UserIdentityUserName, 50), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
by SourceIpAddress
| where Failures >= 5
| order by Failures desc
Successful sign-ins by root, or by anyone without MFA:
AWSCloudTrail
| where EventName == "ConsoleLogin"
| extend Outcome = tostring(parse_json(ResponseElements).ConsoleLogin),
MfaUsed = tostring(parse_json(AdditionalEventData).MFAUsed)
| where Outcome == "Success" and (UserIdentityType == "Root" or MfaUsed == "No")
| project TimeGenerated, UserIdentityType, UserIdentityArn, SourceIpAddress, UserAgent, MfaUsed, AWSRegion
The same question in Athena, over a table on the trail’s S3 bucket (named cloudtrail_logs here):
SELECT eventtime, useridentity.type, useridentity.arn, sourceipaddress,
json_extract_scalar(responseelements, '$.ConsoleLogin') AS outcome,
json_extract_scalar(additionaleventdata, '$.MFAUsed') AS mfa_used
FROM cloudtrail_logs
WHERE eventname = 'ConsoleLogin'
ORDER BY eventtime DESC
LIMIT 200;
If a whole export is in front of you, the free log analyzer reads CloudTrail files in the browser and flags bursts of failed console sign-ins and root activity.
Related events
- CreateLoginProfile IAM
- UpdateLoginProfile IAM
- DeactivateMFADevice IAM
- AssumeRoleWithSAML AWS STS
- GetCallerIdentity AWS STS
Detect it
Frequently Asked Questions
- Why does a failed ConsoleLogin event have no errorCode?
- In AWS's example records a failed console sign-in is marked by responseElements.ConsoleLogin set to Failure and an errorMessage of Failed authentication, with no errorCode field. A query or alert that only looks for a non-empty errorCode will miss every failed console password, so test the ConsoleLogin outcome instead.
- Why is ConsoleLogin recorded in a Region the user never uses?
- AWS records sign-ins by endpoint, not by where the person is. Root user sign-ins land in us-east-1, us-east-2 or us-west-2; IAM users signing in through the global endpoint appear in us-east-1, or in us-east-2, eu-north-1 or ap-southeast-2 when an account alias cookie is present; a Regional endpoint records its own Region. Search every Region or an organization trail.
- What does HIDDEN_DUE_TO_SECURITY_REASONS mean in a ConsoleLogin event?
- The sign-in named a user that does not exist in the account, so the attempt failed with No username found in supplied account and CloudTrail did not record what was typed, since a mistyped password often lands in the name field. Many of these from one address is someone guessing user names.
- Does MFAUsed No on a successful sign-in mean the user has no MFA device?
- It means this sign-in completed without MFA. For an IAM user that usually means no MFA device is assigned, which is worth fixing for anyone with console access. Check whether a DeactivateMFADevice call for the same user came shortly before, because removing MFA and then signing in is a common takeover sequence.
- How do I see what someone did after a ConsoleLogin?
- Take the userIdentity.arn and sourceIPAddress from the successful record and search the following hours for API calls with the same identity and address. CloudTrail marks calls that come from a console session with the sessionCredentialFromConsole field, which separates what was clicked in the console from scripted use of access keys.
Find every ConsoleLogin in your own CloudTrail logs
Load CloudTrail logs (the Records files CloudTrail writes to S3, or aws cloudtrail lookup-events output) into the free browser analyzer: logging changes, new access keys, administrator grants, root activity and failed console sign-ins are flagged, with event names linked to their pages here. Nothing is uploaded.