AnalysisType: rule
Filename: aws_cloudtrail_loginprofilecreatedormodified.py
RuleID: "AWS.CloudTrail.LoginProfileCreatedOrModified"
DisplayName: "AWS User Login Profile Created or Modified"
Enabled: true
LogTypes:
- AWS.CloudTrail
Severity: Low
Reports:
MITRE ATT&CK:
- TA0003:T1098
- TA0005:T1108
- TA0005:T1550
- TA0008:T1550
Stratus Red Team:
- aws.persistence.iam-create-user-login-profile
- aws.privilege-escalation.iam-update-user-login-profile
Description: An attacker with iam:UpdateLoginProfile permission on other users can change the password used to login to the AWS console. May be legitimate account administration.
DedupPeriodMinutes: 60
Threshold: 1
Reference: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage-pass-accesskeys-ssh.html
Tests:
- Name: ChangeOwnPassword
ExpectedResult: false
Log:
{ "awsRegion": "us-east-1",
"eventCategory": "Management",
"eventID": "1234",
"eventName": "UpdateLoginProfile",
"eventSource": "iam.amazonaws.com",
"eventTime": "2022-09-15 13:45:24",
"eventType": "AwsApiCall",
"eventVersion": "1.08",
"managementEvent": true,
"readOnly": false,
"recipientAccountId": "987654321",
"requestParameters":
{ "passwordResetRequired": false,
"userName": "alice" },
"sessionCredentialFromConsole": true,
"sourceIPAddress": "AWS Internal",
"userAgent": "AWS Internal",
"userIdentity":
{ "accessKeyId": "ABC1234",
"accountId": "987654321",
"arn": "arn:aws:sts::98765432:assumed-role/IAM/alice",
"principalId": "ABCDE:alice",
"sessionContext":
{ "attributes":
{ "creationDate": "2022-09-15T13:36:47Z",
"mfaAuthenticated": "true" },
"sessionIssuer":
{ "accountId": "987654321",
"arn": "arn:aws:iam::9876432:role/IAM",
"principalId": "1234ABC",
"type": "Role",
"userName": "IAM" },
"webIdFederationData": { } },
"type": "AssumedRole" } }
- Name: User changed password for other
ExpectedResult: true
Log:
{ "awsRegion": "us-east-1",
"eventCategory": "Management",
"eventID": "1234",
"eventName": "UpdateLoginProfile",
"eventSource": "iam.amazonaws.com",
"eventTime": "2022-09-15 13:45:24",
"eventType": "AwsApiCall",
"eventVersion": "1.08",
"managementEvent": true,
"readOnly": false,
"recipientAccountId": "987654321",
"requestParameters":
{ "passwordResetRequired": false,
"userName": "bob" },
"sessionCredentialFromConsole": true,
"sourceIPAddress": "AWS Internal",
"userAgent": "AWS Internal",
"userIdentity":
{ "accessKeyId": "ABC1234",
"accountId": "987654321",
"arn": "arn:aws:sts::98765432:assumed-role/IAM/alice",
"principalId": "ABCDE:alice",
"sessionContext":
{ "attributes":
{ "creationDate": "2022-09-15T13:36:47Z",
"mfaAuthenticated": "true" },
"sessionIssuer":
{ "accountId": "987654321",
"arn": "arn:aws:iam::9876432:role/IAM",
"principalId": "1234ABC",
"type": "Role",
"userName": "IAM" },
"webIdFederationData": { } },
"type": "AssumedRole" } }
# ------ paired body: aws_cloudtrail_loginprofilecreatedormodified.py ------
from panther_aws_helpers import aws_cloudtrail_success, aws_rule_context
PROFILE_EVENTS = {
"UpdateLoginProfile",
"CreateLoginProfile",
"DeleteLoginProfile",
}
def rule(event):
# Only look for successes
if not aws_cloudtrail_success(event):
return False
# Check when someone other than the user themselves creates or modifies a login profile
# with no password reset needed
return (
event.get("eventSource", "") == "iam.amazonaws.com"
and event.get("eventName", "") in PROFILE_EVENTS
and not event.deep_get("requestParameters", "passwordResetRequired", default=False)
and not event.deep_get("userIdentity", "arn", default="").endswith(
f"/{event.deep_get('requestParameters', 'userName', default='')}"
)
)
def title(event):
return (
f"[{event.deep_get('userIdentity', 'arn')}] "
f"changed the password for "
f"[{event.deep_get('requestParameters','userName')}]"
)
def alert_context(event):
context = aws_rule_context(event)
context["ip_and_username"] = event.get(
"sourceIPAddress", "<MISSING_SOURCE_IP>"
) + event.deep_get("requestParameters", "userName", default="<MISSING_USER_NAME>")
return context