AWSCloudTrail
| where EventName == "UpdateSAMLProvider" and isempty(ErrorCode) and isempty(ErrorMessage)
| extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)
| extend UserName = tostring(split(UserIdentityArn, '/')[-1])
| extend AccountName = case( UserIdentityPrincipalid == "Anonymous", "Anonymous", isempty(UserIdentityUserName), UserName, UserIdentityUserName)
| extend AccountName = iif(AccountName contains "@", tostring(split(AccountName, '@', 0)[0]), AccountName),
AccountUPNSuffix = iif(AccountName contains "@", tostring(split(AccountName, '@', 1)[0]), "")
| extend timestamp = TimeGenerated
version: 1.0.1
tactics:
- Persistence
relevantTechniques:
- T1078
entityMappings:
- fieldMappings:
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
- identifier: CloudAppAccountId
columnName: RecipientAccountId
entityType: Account
- fieldMappings:
- identifier: Address
columnName: SourceIpAddress
entityType: IP
triggerThreshold: 0
name: SAML update identity provider
queryFrequency: 1d
triggerOperator: gt
kind: Scheduled
description: |
'Attackers could update the SAML provider in order to create unauthorized but valid tokens and represent them to services that trust SAML tokens from the environment. These tokens can then be used to access resources. More about this API at https://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateSAMLProvider.html '
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_SAMLUpdateIdentity.yaml
requiredDataConnectors:
- dataTypes:
- AWSCloudTrail
connectorId: AWS
severity: High
query: |
AWSCloudTrail
| where EventName == "UpdateSAMLProvider" and isempty(ErrorCode) and isempty(ErrorMessage)
| extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)
| extend UserName = tostring(split(UserIdentityArn, '/')[-1])
| extend AccountName = case( UserIdentityPrincipalid == "Anonymous", "Anonymous", isempty(UserIdentityUserName), UserName, UserIdentityUserName)
| extend AccountName = iif(AccountName contains "@", tostring(split(AccountName, '@', 0)[0]), AccountName),
AccountUPNSuffix = iif(AccountName contains "@", tostring(split(AccountName, '@', 1)[0]), "")
| extend timestamp = TimeGenerated
queryPeriod: 1d
id: bce1dcba-4948-414d-8838-6385afb9d496
status: Available