Skip to content

Commit

Permalink
Fixing up remaining AuditLog detections with entity mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
shainw committed Dec 30, 2023
1 parent 92bd641 commit 7bb1221
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,20 @@ query: |
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: InitiatingUserPrincipalName
- identifier: Name
columnName: InitiatingAccountName
- identifier: UPNSuffix
columnName: InitiatingAccountUPNSuffix
- entityType: Account
fieldMappings:
- identifier: AadUserId
columnName: InitiatingAadUserId
- entityType: Account
fieldMappings:
- identifier: AadUserId
columnName: InitiatingAppServicePrincipalId
- entityType: Account
fieldMappings:
- identifier: ObjectGuid
columnName: ServicePrincipalObjectID
- entityType: IP
Expand Down
55 changes: 36 additions & 19 deletions Detections/AuditLogs/ServicePrincipalAssignedPrivilegedRole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,57 @@ query: |
| extend type_ = tostring(TargetResources[0].type)
| where type_ =~ "ServicePrincipal"
| where isnotempty(TargetResources)
| extend ServicePrincipal = tostring(TargetResources[0].displayName)
| extend SPID = tostring(TargetResources[0].id)
| extend InitiatingAppName = tostring(InitiatedBy.app.displayName)
| extend InitiatingAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId)
| extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatingAadUserId = tostring(InitiatedBy.user.id)
| extend InitiatingIPAddress = tostring(InitiatedBy.user.ipAddress)
| extend InitiatedBy = tostring(iff(isnotempty(InitiatingUserPrincipalName),InitiatingUserPrincipalName, InitiatingAppName))
| extend ServicePrincipalName = tostring(TargetResources[0].displayName)
| extend ServicePrincipalId = tostring(TargetResources[0].id)
| mv-expand TargetResources[0].modifiedProperties
| extend TargetResources_0_modifiedProperties = columnifexists("TargetResources_0_modifiedProperties", '')
| where isnotempty(TargetResources_0_modifiedProperties)
| where TargetResources_0_modifiedProperties.displayName =~ "Role.DisplayName"
| extend TargetRole = parse_json(tostring(TargetResources_0_modifiedProperties.newValue))
| where TargetRole contains "admin"
| extend AddedByApp = iif(
isnotempty(tostring(parse_json(tostring(InitiatedBy.app)).servicePrincipalName)),
tostring(parse_json(tostring(InitiatedBy.app)).servicePrincipalName),
tostring(parse_json(tostring(InitiatedBy.app)).displayName)
)
| extend AddedByUser = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend AddedBy = iif(isnotempty(AddedByApp), AddedByApp, AddedByUser)
| extend IpAddress = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress)
| project-reorder TimeGenerated, ServicePrincipal, SPID, TargetRole, AddedBy, IpAddress
| project-away AddedByApp, AddedByUser
| extend displayName = tostring(TargetResources_0_modifiedProperties.displayName), newValue = tostring(parse_json(tostring(TargetResources_0_modifiedProperties.newValue)))
| where displayName == "Role.DisplayName" and newValue contains "admin"
| extend TargetRole = newValue
| project-reorder TimeGenerated, ServicePrincipalName, ServicePrincipalId, InitiatedBy, TargetRole, InitiatingIPAddress
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: InitiatingAppName
- identifier: AadUserId
columnName: SPID
columnName: InitiatingAppServicePrincipalId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AddedBy
version: 1.0.1
columnName: InitiatingUserPrincipalName
- identifier: Name
columnName: InitiatingAccountName
- identifier: UPNSuffix
columnName: InitiatingAccountUPNSuffix
- entityType: Account
fieldMappings:
- identifier: AadUserId
columnName: InitiatingAadUserId
- entityType: Account
fieldMappings:
- identifier: Name
columnName: ServicePrincipalName
- identifier: AadUserId
columnName: ServicePrincipalId
- entityType: IP
fieldMappings:
- identifier: Address
columnName: InitiatingIPAddress
version: 1.1.0
kind: Scheduled
metadata:
source:
kind: Community
author:
name: Pete Bryan
name: Microsoft Security Research
support:
tier: Community
categories:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,63 @@ relevantTechniques:
tags:
- GuestorExternalIdentities
query: |
let lookback = 1d;
AuditLogs
| where TimeGenerated > ago(lookback)
AuditLogs
| where OperationName=~ "Update user"
| where Result =~ "success"
| mv-expand TargetResources
| mv-expand TargetResources.modifiedProperties
| extend displayName_ = tostring(TargetResources_modifiedProperties.displayName) , oldValue_ = tostring(TargetResources_modifiedProperties.oldValue), newValue_ = tostring(TargetResources_modifiedProperties.newValue)
| where displayName_ == "UserPrincipalName" and oldValue_ !has "#EXT" and newValue_ has "#EXT"
| extend InitiatingApp = tostring(parse_json(tostring(InitiatedBy.app)).displayName)
| extend Initiator = iif(isnotempty(InitiatingApp), InitiatingApp, tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)) , IPAddress = tostring(InitiatedBy.["user"].["ipAddress"])
| project TimeGenerated, AADTenantId, IPAddress, Initiator, displayName_, oldValue_, newValue_
| extend displayName = tostring(TargetResources_modifiedProperties.displayName),
TargetUPN_oldValue = tostring(parse_json(tostring(TargetResources_modifiedProperties.oldValue))[0]),
TargetUPN_newValue = tostring(parse_json(tostring(TargetResources_modifiedProperties.newValue))[0])
| where displayName == "UserPrincipalName" and TargetUPN_oldValue !has "#EXT" and TargetUPN_newValue has "#EXT"
| extend InitiatingAppName = tostring(InitiatedBy.app.displayName)
| extend InitiatingAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId)
| extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatingAadUserId = tostring(InitiatedBy.user.id)
| extend InitiatingIPAddress = tostring(InitiatedBy.user.ipAddress)
| extend InitiatedBy = tostring(iff(isnotempty(InitiatingUserPrincipalName),InitiatingUserPrincipalName, InitiatingAppName))
| summarize arg_max(TimeGenerated, *) by CorrelationId
| project-reorder TimeGenerated, InitiatedBy, InitiatingAppName, InitiatingAppServicePrincipalId, InitiatingUserPrincipalName, InitiatingAadUserId, InitiatingIPAddress, TargetUPN_oldValue, TargetUPN_newValue
| extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])
| extend TargetAccountName = tostring(split(TargetUPN_oldValue, "@")[0]), TargetUPNSuffix = tostring(split(TargetUPN_oldValue, "@")[1])
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: InitiatingAppName
- identifier: AadUserId
columnName: InitiatingAppServicePrincipalId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: Initiator
columnName: InitiatingUserPrincipalName
- identifier: Name
columnName: InitiatingAccountName
- identifier: UPNSuffix
columnName: InitiatingAccountUPNSuffix
- entityType: Account
fieldMappings:
- identifier: AadUserId
columnName: InitiatingAadUserId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: displayName_
columnName: TargetUPN_oldValue
- identifier: Name
columnName: TargetAccountName
- identifier: UPNSuffix
columnName: TargetUPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPAddress
version: 1.0.2
columnName: InitiatingIPAddress
version: 1.1.0
kind: Scheduled
metadata:
source:
kind: Community
author:
name: Ashwin Patil
name: Microsoft Security Research
support:
tier: Community
categories:
Expand Down
36 changes: 26 additions & 10 deletions Detections/AuditLogs/URLAddedtoApplicationfromUnknownDomain.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,40 +45,56 @@ query: |
| extend AddedUrls = set_difference(NewUrls, OldUrls)
| where array_length(AddedUrls) > 0
| extend UserAgent = iif(tostring(AdditionalDetails[0].key) == "User-Agent", tostring(AdditionalDetails[0].value), "")
| extend AddingUser = iif(isnotempty(tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)) , tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName), "")
| extend AddingApp = iif(isnotempty(tostring(parse_json(tostring(InitiatedBy.app)).servicePrincipalName)) , tostring(parse_json(tostring(InitiatedBy.app)).servicePrincipalName), "")
| extend AddedBy = iif(isnotempty(AddingUser), AddingUser, AddingApp)
| project-away AddingApp, AddingUser
| extend InitiatingAppName = tostring(InitiatedBy.app.displayName)
| extend InitiatingAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId)
| extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatingAadUserId = tostring(InitiatedBy.user.id)
| extend InitiatingIPAddress = tostring(InitiatedBy.user.ipAddress)
| extend InitiatedBy = tostring(iff(isnotempty(InitiatingUserPrincipalName),InitiatingUserPrincipalName, InitiatingAppName))
| extend AppDisplayName = tostring(TargetResources.displayName)
| extend ipAddress = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress)
| where isnotempty(AddedUrls)
| mv-expand AddedUrls
| extend AddedUrls = trim(@'"', tostring(AddedUrls))
| extend Domain = extract("^(?:https?:\\/\\/)?(?:[^@\\/\\n]+@)?(?:www\\.)?([^:\\/?\\n]+)/", 1, replace_string(tolower(AddedUrls), '"', ""))
| where isnotempty(Domain)
| extend Domain = strcat(split(Domain, ".")[-2], ".", split(Domain, ".")[-1])
| where Domain !in (domains)
| project-reorder TimeGenerated, AppDisplayName, AddedUrls, AddedBy, UserAgent, ipAddress
| project-reorder TimeGenerated, AppDisplayName, AddedUrls, InitiatedBy, UserAgent, InitiatingIPAddress
| extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])
entityMappings:
- entityType: URL
fieldMappings:
- identifier: Url
columnName: AddedUrls
- entityType: Account
fieldMappings:
- identifier: Name
columnName: InitiatingAppName
- identifier: AadUserId
columnName: InitiatingAppServicePrincipalId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AddedBy
columnName: InitiatingUserPrincipalName
- identifier: Name
columnName: InitiatingAccountName
- identifier: UPNSuffix
columnName: InitiatingAccountUPNSuffix
- entityType: Account
fieldMappings:
- identifier: AadUserId
columnName: InitiatingAadUserId
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ipAddress
version: 1.0.3
columnName: InitiatingIPAddress
version: 1.1.0
kind: Scheduled
metadata:
source:
kind: Community
author:
name: Pete Bryan
name: Microsoft Security Research
support:
tier: Community
categories:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,59 @@ tags:
- AADSecOpsGuide
query: |
// Add the environments expected username format regex below before deploying
let user_regex = "";
AuditLogs
| where OperationName =~ "Add user"
| where Result =~ "success"
| extend userAgent = tostring(AdditionalDetails[0].value)
| extend addingUser = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend addingApp = tostring(parse_json(tostring(InitiatedBy.app)).displayName)
| extend AddedBy = iif(isnotempty(addingUser), addingUser, addingApp)
| extend ipAddress = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress)
| extend AddedUser = tostring(TargetResources[0].userPrincipalName)
| where AddedUser matches regex user_regex
let user_regex = "";
AuditLogs
| where OperationName =~ "Add user"
| where Result =~ "success"
| extend userAgent = tostring(AdditionalDetails[0].value)
| extend InitiatingAppName = tostring(InitiatedBy.app.displayName)
| extend InitiatingAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId)
| extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatingAadUserId = tostring(InitiatedBy.user.id)
| extend InitiatingIPAddress = tostring(InitiatedBy.user.ipAddress)
| extend InitiatedBy = tostring(iff(isnotempty(InitiatingUserPrincipalName),InitiatingUserPrincipalName, InitiatingAppName))
| extend AddedUser = tostring(TargetResources[0].userPrincipalName)
| where AddedUser matches regex user_regex
| extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])
| extend TargetAccountName = tostring(split(AddedUser, "@")[0]), TargetAccountUPNSuffix = tostring(split(AddedUser, "@")[1])
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: InitiatingAppName
- identifier: AadUserId
columnName: InitiatingAppServicePrincipalId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AddedBy
columnName: InitiatingUserPrincipalName
- identifier: Name
columnName: InitiatingAccountName
- identifier: UPNSuffix
columnName: InitiatingAccountUPNSuffix
- entityType: Account
fieldMappings:
- identifier: AadUserId
columnName: InitiatingAadUserId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AddedUser
version: 1.0.1
- identifier: Name
columnName: TargetAccountName
- identifier: UPNSuffix
columnName: TargetAccountUPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: InitiatingIPAddress
version: 1.1.0
kind: Scheduled
metadata:
source:
kind: Community
author:
name: Pete Bryan
name: Microsoft Security Research
support:
tier: Community
categories:
Expand Down
39 changes: 33 additions & 6 deletions Detections/AuditLogs/UserStatechangedfromGuesttoMember.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,55 @@ query: |
| mv-expand TargetResources
| mv-expand TargetResources.modifiedProperties
| where TargetResources_modifiedProperties.displayName =~ "TargetId.UserType"
| extend UpdatingServicePrincipal = tostring(parse_json(tostring(InitiatedBy.app)).servicePrincipalId)
| extend UpdatingUserPrincipal = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend UpdatingUser = iif(isnotempty(UpdatingServicePrincipal), UpdatingServicePrincipal, UpdatingUserPrincipal)
| extend UpdatingAppName = tostring(parse_json(tostring(InitiatedBy.app)).displayName)
| extend UpdatingServicePrincipalId = tostring(parse_json(tostring(InitiatedBy.app)).servicePrincipalId)
| extend UpdatingUserPrincipalName = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend UpdatingUserAadUserId = tostring(parse_json(tostring(InitiatedBy.user)).id)
| extend UpdatingUserIPAddress = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress)
| extend UpdatingUser = iif(isnotempty(UpdatingServicePrincipalId), UpdatingServicePrincipalId, UpdatingUserPrincipalName)
| extend UpdatedUserPrincipalName = tostring(TargetResources.userPrincipalName)
| project-reorder TimeGenerated, UpdatedUserPrincipalName, UpdatingUser
| where parse_json(tostring(TargetResources_modifiedProperties.newValue)) =~ "\"Member\"" and parse_json(tostring(TargetResources_modifiedProperties.oldValue)) =~ "\"Guest\""
| extend InitiatingAccountName = tostring(split(UpdatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(UpdatingUserPrincipalName, "@")[1])
| extend TargetAccountName = tostring(split(UpdatedUserPrincipalName, "@")[0]), TargetAccountUPNSuffix = tostring(split(UpdatedUserPrincipalName, "@")[1])
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: UpdatingAppName
- identifier: AadUserId
columnName: UpdatingServicePrincipalId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: UpdatingUser
columnName: UpdatingUserPrincipalName
- identifier: Name
columnName: InitiatingAccountName
- identifier: UPNSuffix
columnName: InitiatingAccountUPNSuffix
- entityType: Account
fieldMappings:
- identifier: AadUserId
columnName: UpdatingUserAadUserId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: UpdatedUserPrincipalName
version: 1.0.1
- identifier: Name
columnName: TargetAccountName
- identifier: UPNSuffix
columnName: TargetAccountUPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: UpdatingUserIPAddress
version: 1.1.0
kind: Scheduled
metadata:
source:
kind: Community
author:
name: Pete Bryan
name: Microsoft Security Research
support:
tier: Community
categories:
Expand Down
Loading

0 comments on commit 7bb1221

Please sign in to comment.