STATE OF IDENTITY SECURITY Permiso has released the 2024 Survey Report

[GET THE REPORT]
Illustration Cloud

AWS Enhancements to UpdateLoginProfile and CreateLoginProfile logging

Introduction

While working on detection content for our clients, we often come across situations where logging from cloud providers and identity providers does not contain the level of detail needed. In this case we were working on detections to identify when a login profile is created or updated without the reset password flag set to true. This flag identifies if the user is required to reset their password on the next authentication.

Permiso has long included this detection for CreateLoginProfile and intended to expand coverage to UpdateLoginProfile as well. Unfortunately we found that while CreateLoginProfile and UpdateLoginProfile share request parameters, they do not share the same parameters within logs.

UpdateLoginProfile did not include any reference to the password reset flag within logs, making it impossible to signal on the password reset flag.

Additionally, we found that logs for CreateLoginProfile always show as false for the PasswordResetRequired request parameter, even if you set it to True in the the API call.

Testing and verifying logging is an important part of threat detection. At Permiso, we come across logging discrepancies like this often. Luckily, AWS is known for having a great outreach team that is willing to work with researchers like us!

Disclosure Timeline

We cannot understate how responsive the AWS team was in acknowledging the finding and making changes to enhance logging. There are other similar vendors we have worked with, that do not even respond in the same amount of time it took AWS to push a fix.

Disclosure Timeline

Technical Details

The table below presents the request parameters of both CreateLoginProfile and UpdateLoginProfile. It can be seen that the only difference is the password field which varies when each is required or not. For both, the PasswordResetRequired parameter is not required and by default would be false if otherwise not provided.

AWS Actions:

Action

Request Parameters

CreateLoginProfile

Password (required)
PasswordResetRequired (optional)
UserName
(required)

UpdateLoginProfile

Password (optional)
PasswordResetRequired (optional)
UserName
(required)

UpdateLoginProfile

Before AWS began to rollout the disclosed updates, UpdateLoginProfile would have provided little outside of a sense that an update occurred to the login profile of the disclosed user. A password reset may be required on the next authentication, or maybe the password was reset, and last, both request parameters may have been used but the log would not have provided any variation on these details. With the changes to logging implemented by AWS beginning October 17th, the event log for this same action captures more detail in the request parameter.

{
  "requestParameters": {
    "userName": "NathanTest",
+   "passwordResetRequired": true
  },
  "responseElements": null,
  ...
}

CreateLoginProfile

CreateLoginProfile in contrast to UpdateLoginProfile, does provide greater detail. CreateLoginProfile by its required parameters and by its nature would mean that a password has been set for the given username. The CreateLoginProfile action also provides logging details around the PasswordResetRequired parameter. Permiso discovered however that the passwordResetRequired log line is included in both the requestParameters and responseElements JSON objects. There is no issue with redundancy, the issue discovered was that the requestParameters object always stated that the passwordResetRequired parameter was false while the responseElements may accurately represent that the parameter was true. Permiso has provided a log for both cases to show the static incorrect requestParameters object.

{
  "requestParameters": {
    "userName": "CreateLoginProfileTestUserB",
    "passwordResetRequired": false // NOTE the mismatch below in the response
  },
  "responseElements": {
    "loginProfile": {
      "userName": "CreateLoginProfileTestUserB",
      "createDate": "Sep 20, 2022 3:26:25 PM",
      "passwordResetRequired": true
    }
  },
}

With the changes to logging implemented by AWS beginning October 17th, the event log for this same action instead looks similar to the following where passwordResetRequired will match in both the request and response:

{

  "requestParameters": {
    "userName": "CreateLoginProfileTestUserD",
    "passwordResetRequired": true
  },
  "responseElements": {
    "loginProfile": {
      "userName": "CreateLoginProfileTestUserD",
      "createDate": "Oct 21, 2022 1:51:12 PM",
      "passwordResetRequired": true
    }
  },
}

Acknowledgements

Big thanks to the AWS Security Outreach Team, and IAM team! They were super responsive, and quick to address our findings. It is clear that AWS is serious about security and willing to work with researchers to address concerns as they come up!

Appendix

Before: UpdateLoginProfile

{
  "eventVersion": "1.08",
  "userIdentity": {
    "type": "AssumedRole",
    "principalId": "ARABC5IQVABC5JABC5GQI:nathan.eades@permiso.io",
    "arn": "arn:aws:sts::353353353353:assumed-role/AWSReservedSSO_AdministratorAccess_c3ABC55ABC53ccef/nathan.eades@permiso.io",
    "accountId": "353353353353",
    "accessKeyId": "ASABC4IQVCIYZZABC44H",
    "sessionContext": {
      "sessionIssuer": {
        "type": "Role",
        "principalId": "ARABC5IQVABC5JABC5GQI",
        "arn": "arn:aws:iam::353353353353:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AdministratorAccesABC5ABC55ABC53ccef",
        "accountId": "353353353353",
        "userName": "AWSReservedSSO_AdministratorAccesABC5ABC55ABC53ccef"
      },
      "webIdFederationData": {},
      "attributes": {
        "creationDate": "2022-09-20T14:55:59Z",
        "mfaAuthenticated": "false"
      }
    }
  },
  "eventTime": "2022-09-20T15:01:24Z",
  "eventSource": "iam.amazonaws.com",
  "eventName": "UpdateLoginProfile",
  "awsRegion": "us-east-1",
  "sourceIPAddress": "AWS Internal",
  "userAgent": "AWS Internal",
  "requestParameters": {
    "userName": "NathanTest"
  },
  "responseElements": null,
  "requestID": "353a8cef-f1dc-353f-b2ca-bbbfb1d2b5fd",
  "eventID": "92b6e4e7-e2b9-3535-bd34-f2c94a79f1d7",
  "readOnly": false,
  "eventType": "AwsApiCall",
  "managementEvent": true,
  "recipientAccountId": "353353353353",
  "eventCategory": "Management",
  "sessionCredentialFromConsole": "true"
}

After: UpdateLoginProfile

{
  "eventVersion": "1.08",
  "userIdentity": {
    "type": "AssumedRole",
    "principalId": "ARABC5IQVABC5JABC5GQI:nathan.eades@permiso.io",
    "arn": "arn:aws:sts::353353353353:assumed-role/AWSReservedSSO_AdministratorAccess_c3ABC55ABC53ccef/nathan.eades@permiso.io",
    "accountId": "353353353353",
    "accessKeyId": "ASABC4IQVCIYZZABC44H",
    "sessionContext": {
      "sessionIssuer": {
        "type": "Role",
        "principalId": "ARABC5IQVABC5JABC5GQI",
        "arn": "arn:aws:iam::353353353353:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AdministratorAccesABC5ABC55ABC53ccef",
        "accountId": "353353353353",
        "userName": "AWSReservedSSO_AdministratorAccesABC5ABC55ABC53ccef"
      },
      "webIdFederationData": {},
      "attributes": {
        "creationDate": "2022-10-21T13:43:44Z",
        "mfaAuthenticated": "false"
      }
    }
  },
  "eventTime": "2022-10-21T14:47:59Z",
  "eventSource": "iam.amazonaws.com",
  "eventName": "UpdateLoginProfile",
  "awsRegion": "us-east-1",
  "sourceIPAddress": "AWS Internal",
  "userAgent": "AWS Internal",
  "requestParameters": {
    "userName": "NathanTest",
    "passwordResetRequired": true
  },
  "responseElements": null,
  "requestID": "e807c0b8-8fe6-4cbe-8f5e-572f7e3b930f",
  "eventID": "96f714dc-8a71-4078-89ff-bd3aaf341104",
  "readOnly": false,
  "eventType": "AwsApiCall",
  "managementEvent": true,
  "recipientAccountId": "353353353353",
  "eventCategory": "Management",
  "sessionCredentialFromConsole": "true"
}

Before: CreateLoginProfile - password reset not required

{
  "eventVersion": "1.08",
  "userIdentity": {
    "type": "AssumedRole",
    "principalId": "ARABC5IQVABC5JABC5GQI:nathan.eades@permiso.io",
    "arn": "arn:aws:sts::353353353353:assumed-role/AWSReservedSSO_AdministratorAccess_c353e353cc93ccef/nathan.eades@permiso.io",
    "accountId": "353353353353",
    "accessKeyId": "ASABC4IQVCIYZZABC44H",
    "sessionContext": {
      "sessionIssuer": {
        "type": "Role",
        "principalId": "ARABC5IQVABC5JABC5GQI",
        "arn": "arn:aws:iam::353353353353:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AdministratorAccess_c353e353cc93ccef",
        "accountId": "353353353353",
        "userName": "AWSReservedSSO_AdministratorAccess_c353e353cc93ccef"
      },
      "webIdFederationData": {},
      "attributes": {
        "creationDate": "2022-09-20T14:55:59Z",
        "mfaAuthenticated": "false"
      }
    }
  },
  "eventTime": "2022-09-20T15:25:56Z",
  "eventSource": "iam.amazonaws.com",
  "eventName": "CreateLoginProfile",
  "awsRegion": "us-east-1",
  "sourceIPAddress": "AWS Internal",
  "userAgent": "AWS Internal",
  "requestParameters": {
    "userName": "CreateLoginProfileTestUserA",
    "passwordResetRequired": false
  },
  "responseElements": {
    "loginProfile": {
      "userName": "CreateLoginProfileTestUserA",
      "createDate": "Sep 20, 2022 3:25:56 PM",
      "passwordResetRequired": false
    }
  },
  "requestID": "fc3ec353-b60a-4d22-a25b-add7a3533533",
  "eventID": "e353353e-05d8-4ec0-3539-35335341fe4b",
  "readOnly": false,
  "eventType": "AwsApiCall",
  "managementEvent": true,
  "recipientAccountId": "353353353353",
  "eventCategory": "Management",
  "sessionCredentialFromConsole": "true"
}

Before: CreateLoginProfile - password reset required

{
  "eventVersion": "1.08",
  "userIdentity": {
    "type": "AssumedRole",
    "principalId": "ARABC5IQVABC5JABC5GQI:nathan.eades@permiso.io",
    "arn": "arn:aws:sts::353353353353:assumed-role/AWSReservedSSO_AdministratorAccess_c353e353cc93ccef/nathan.eades@permiso.io",
    "accountId": "353353353353",
    "accessKeyId": "ASABC4IQVCIYZZABC44H",
    "sessionContext": {
      "sessionIssuer": {
        "type": "Role",
        "principalId": "ARABC5IQVABC5JABC5GQI",
        "arn": "arn:aws:iam::353353353353:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AdministratorAccess_c353e353cc93ccef",
        "accountId": "353353353353",
        "userName": "AWSReservedSSO_AdministratorAccess_c353e353cc93ccef"
      },
      "webIdFederationData": {},
      "attributes": {
        "creationDate": "2022-09-20T14:55:59Z",
        "mfaAuthenticated": "false"
      }
    }
  },
  "eventTime": "2022-09-20T15:26:25Z",
  "eventSource": "iam.amazonaws.com",
  "eventName": "CreateLoginProfile",
  "awsRegion": "us-east-1",
  "sourceIPAddress": "AWS Internal",
  "userAgent": "AWS Internal",
  "requestParameters": {
    "userName": "CreateLoginProfileTestUserB",
    "passwordResetRequired": false
  },
  "responseElements": {
    "loginProfile": {
      "userName": "CreateLoginProfileTestUserB",
      "createDate": "Sep 20, 2022 3:26:25 PM",
      "passwordResetRequired": true
    }
  },
  "requestID": "45e51b66-0a57-4bbe-b651-233fadfc5468",
  "eventID": "8504c50f-d84b-4061-b4ca-1bf40d445384",
  "readOnly": false,
  "eventType": "AwsApiCall",
  "managementEvent": true,
  "recipientAccountId": "353353353353",
  "eventCategory": "Management",
  "sessionCredentialFromConsole": "true"
}

After: CreateLoginProfile - password reset required

{
  "eventVersion": "1.08",
  "userIdentity": {
    "type": "AssumedRole",
    "principalId": "ARABC5IQVABC5JABC5GQI:nathan.eades@permiso.io",
    "arn": "arn:aws:sts::353353353353:assumed-role/AWSReservedSSO_AdministratorAccess_c353e353cc93ccef/nathan.eades@permiso.io",
    "accountId": "353353353353",
    "accessKeyId": "ASABC4IQVCIYZZABC44H",
    "sessionContext": {
      "sessionIssuer": {
        "type": "Role",
        "principalId": "ARABC5IQVABC5JABC5GQI",
        "arn": "arn:aws:iam::353353353353:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AdministratorAccess_c353e353cc93ccef",
        "accountId": "353353353353",
        "userName": "AWSReservedSSO_AdministratorAccess_c353e353cc93ccef"
      },
      "webIdFederationData": {},
      "attributes": {
        "creationDate": "2022-10-21T13:43:08Z",
        "mfaAuthenticated": "false"
      }
    }
  },
  "eventTime": "2022-10-21T13:51:12Z",
  "eventSource": "iam.amazonaws.com",
  "eventName": "CreateLoginProfile",
  "awsRegion": "us-east-1",
  "sourceIPAddress": "AWS Internal",
  "userAgent": "AWS Internal",
  "requestParameters": {
    "userName": "CreateLoginProfileTestUserD",
    "passwordResetRequired": true
  },
  "responseElements": {
    "loginProfile": {
      "userName": "CreateLoginProfileTestUserD",
      "createDate": "Oct 21, 2022 1:51:12 PM",
      "passwordResetRequired": true
    }
  },
  "requestID": "f5b7de8f-4725-4d5c-9a7a-b20b97cccd87",
  "eventID": "0347a96b-999b-4f1e-85a7-2a38307cf686",
  "readOnly": false,
  "eventType": "AwsApiCall",
  "managementEvent": true,
  "recipientAccountId": "353353353353",
  "eventCategory": "Management",
  "sessionCredentialFromConsole": "true"
}
Illustration Cloud

Related Articles

INTRODUCING CAPICHE DETECTION FRAMEWORK: AN OPEN-SOURCE TOOL TO SIMPLIFY CLOUD API-BASED HUNTING

Intro Attacks on cloud infrastructure have been steadily increasing in quantity, sophistication and scope. Common cryptomining attacks still exists, but the proliferation of BEC (Business Email Compromise) and SMS spamming along with full-bore

BucketShield: Track Log Flow, Secure Buckets, Simulate Threats – All in One Open-Source Tool

Introduction In today’s cloud-powered world, keeping your logs secure and intact is more important than ever. AWS CloudTrail serves as the backbone for tracking all activities across your cloud environment, but simply enabling it isn't enough.

Breaking free from the chains of fate - Bypassing AWSCompromisedKeyQuarantineV2 Policy

Intro AWSCompromisedKeyQuarantineV2 (v3 was released during the creation of this article) is an AWS policy that attaches to identities whose credentials are leaked. It denies access to certain actions, applied by the AWS team in the event that an

View more posts