Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entity mapping fixes for BEC solution #9432

Merged
merged 5 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,62 @@ relevantTechniques:
tags:
- AADSecOpsGuide
query: |
AuditLogs
| where TimeGenerated between(ago(14d)..ago(1d))
let auditList =
AuditLogs
| where TimeGenerated >= ago(14d)
| where OperationName =~ "Add member to role completed (PIM activation)"
| where Result =~ "success"
| extend ElevatedUser = tostring(TargetResources[2].userPrincipalName)
| extend TargetUserPrincipalName = tostring(TargetResources[2].userPrincipalName)
| extend displayName = tostring(TargetResources[0].displayName)
| extend displayName2 = tostring(TargetResources[3].displayName)
| extend ElevatedRole = iif(displayName =~ "Member", displayName2, displayName)
| join kind = rightanti (AuditLogs
;
let lookbackList = auditList
| where TimeGenerated between(ago(14d)..ago(1d))
;
let recentList = auditList
| where TimeGenerated > ago(1d)
| where OperationName =~ "Add member to role completed (PIM activation)"
| where Result =~ "success"
| extend ElevatedUser = tostring(TargetResources[2].userPrincipalName)
| extend displayName = tostring(TargetResources[0].displayName)
| extend displayName2 = tostring(TargetResources[3].displayName)
| extend ElevatedRole = iif(displayName =~ "Member", displayName2, displayName)
| extend ElevatedBy = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)) on ElevatedRole, ElevatedUser
| project-reorder ElevatedUser, ElevatedRole, ResultReason,ElevatedBy
;
let newlyElevated = recentList
| join kind = leftanti lookbackList on ElevatedRole, TargetUserPrincipalName
;
newlyElevated | project Id, AdditionalDetails
| mv-expand bagexpansion=array AdditionalDetails
| evaluate bag_unpack(AdditionalDetails)
| evaluate pivot(key, make_set(value))
| extend ipaddr = todynamic(column_ifexists("ipaddr", ""))
| mv-expand ipaddr
| project Id, InitiatingIPAddress = tostring(ipaddr)
| join kind=rightouter newlyElevated on 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 = iff(isnotempty(tostring(InitiatedBy.user.ipAddress)), tostring(InitiatedBy.user.ipAddress), InitiatingIPAddress)
| extend ElevatedBy = iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName)
| extend ElevatedUser = TargetUserPrincipalName
| extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])
| extend TargetAccountName = tostring(split(TargetUserPrincipalName, "@")[0]), TargetAccountUPNSuffix = tostring(split(TargetUserPrincipalName, "@")[1])
| project-reorder ElevatedUser, ElevatedRole, ResultReason, ElevatedBy, InitiatingUserPrincipalName, InitiatingAadUserId, InitiatingIPAddress, TargetUserPrincipalName

entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: ElevatedUser
- identifier: Name
columnName: InitiatingAccountName
- identifier: UPNSuffix
columnName: InitiatingAccountUPNSuffix
- identifier: AadUserId
columnName: InitiatingAadUserId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: ElevatedBy
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
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
id: feb0a2fb-ae75-4343-8cbc-ed545f1da289
name: Authentication Method Changed for Privileged Account
description: |
'Identifies authentication methods being changed for a privileged account. This could be an indicated of an attacker adding an auth method to the account so they can have continued access.
'Identifies authentication methods being changed for a privileged account. This could be an indication of an attacker adding an auth method to the account so they can have continued access.
Ref : https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-privileged-accounts#things-to-monitor-1'
severity: High
requiredDataConnectors:
Expand All @@ -22,23 +22,41 @@ relevantTechniques:
tags:
- AADSecOpsGuide
query: |
let VIPUsers = (IdentityInfo
| where AssignedRoles contains "Admin"
| summarize by tolower(AccountUPN));
AuditLogs
| where Category =~ "UserManagement"
| where ActivityDisplayName =~ "User registered security info"
| where LoggedByService =~ "Authentication Methods"
| extend AccountCustomEntity = tostring(TargetResources[0].userPrincipalName), IPCustomEntity = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress)
| where AccountCustomEntity in (VIPUsers)
let VIPUsers = (IdentityInfo
| where AssignedRoles contains "Admin"
| summarize by tolower(AccountUPN));
AuditLogs
| where Category =~ "UserManagement"
| where ActivityDisplayName =~ "User registered security info"
| where LoggedByService =~ "Authentication Methods"
| extend TargetUserPrincipalName = tostring(TargetResources[0].userPrincipalName)
| where tolower(TargetUserPrincipalName) in (VIPUsers)
| extend TargetAadUserId = tostring(TargetResources[0].id)
| extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatingAadUserId = tostring(InitiatedBy.user.id)
| extend InitiatingIPAddress = tostring(InitiatedBy.user.ipAddress)
| extend TargetAccountName = tostring(split(TargetUserPrincipalName, "@")[0]), TargetAccountUPNSuffix = tostring(split(TargetUserPrincipalName, "@")[1])
| extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AccountCustomEntity
- identifier: Name
columnName: TargetAccountName
- identifier: UPNSuffix
columnName: TargetAccountUPNSuffix
- identifier: AadUserId
columnName: TargetAadUserId
- entityType: Account
fieldMappings:
- identifier: Name
columnName: InitiatingAccountName
- identifier: UPNSuffix
columnName: InitiatingAccountUPNSuffix
- identifier: AadUserId
columnName: InitiatingAadUserId
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPCustomEntity
version: 1.0.2
columnName: InitiatingIPAddress
version: 1.0.3
kind: Scheduled
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,41 @@ query: |
AuditLogs
| where Category =~ "RoleManagement"
| where OperationName has "Add eligible member"
| extend userPrincipalName = tostring(TargetResources[0].userPrincipalName)
| where tolower(userPrincipalName) in (admin_users)
| extend TargetUserPrincipalName = tostring(TargetResources[0].userPrincipalName)
| where tolower(TargetUserPrincipalName) in (admin_users)
| extend TargetAadUserId = tostring(TargetResources[0].id)
| extend Group = tostring(TargetResources[0].displayName)
| extend AddedTo = iif(isnotempty(userPrincipalName), userPrincipalName, Group)
| extend RoleAddedTo = iif(isnotempty(TargetUserPrincipalName), TargetUserPrincipalName, Group)
| extend mod_props = TargetResources[0].modifiedProperties
| extend appName = tostring(parse_json(tostring(InitiatedBy.app)).displayName)
| extend UPN = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend AddedBy = iif(isnotempty(appName), appName, UPN)
| 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 RoleAddedBy = iif(isnotempty(InitiatingAppName), InitiatingAppName, InitiatingUserPrincipalName)
| mv-expand mod_props
| where mod_props.displayName == "Role.DisplayName"
| extend UserAgent = tostring(AdditionalDetails[0].value)
| extend RoleAdded = tostring(parse_json(tostring(mod_props.newValue)))
| project-reorder TimeGenerated, OperationName, AddedTo, RoleAdded, AddedBy
| extend TargetAccountName = tostring(split(TargetUserPrincipalName, "@")[0]), TargetAccountUPNSuffix = tostring(split(TargetUserPrincipalName, "@")[1])
| extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])
| project-reorder TimeGenerated, OperationName, TargetUserPrincipalName, RoleAddedTo, RoleAdded, RoleAddedBy, InitiatingUserPrincipalName, InitiatingAppName
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: userPrincipalName
- identifier: Name
columnName: TargetAccountName
- identifier: UPNSuffix
columnName: TargetAccountUPNSuffix
- identifier: AadUserId
columnName: TargetAadUserId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AddedBy
version: 1.0.3
- identifier: Name
columnName: InitiatingAccountName
- identifier: UPNSuffix
columnName: InitiatingAccountUPNSuffix
- identifier: AadUserId
columnName: InitiatingAadUserId
version: 1.0.4
kind: Scheduled
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ query: |
| join kind=inner(Events | extend TimeStamp = startofday(TimeGenerated)) on TimeStamp, User
| extend IpAddr = column_ifexists("IpAddr", SrcIpAddr)
| extend Name = iif(User contains "@", split(User, "@")[0], User)
| extend UPNSuffix = iif(User contains "@", split(User, "@")[1], User)
| extend UPNSuffix = iif(User contains "@", split(User, "@")[1], "")
| project-reorder TimeGenerated, User, EventType, EventResult, EventProduct, FilePath, HttpUserAgent, IpAddr, CountOfDocs, Baseline, Score
entityMappings:
- entityType: Account
Expand Down Expand Up @@ -70,5 +70,5 @@ alertDetailsOverride:
alertDescriptionFormat: |
This query looks for users (in this case {{User}}) with suspicious spikes in the number of files accessed (in this case {{number_of_files_accessed}} events) that relate to topics commonly accessed as part of Business Email Compromise (BEC) attacks. The query looks for access to files in storage that relate to topics such as invoices or payments, and then looks for users accessing these files in significantly higher numbers than in the previous 14 days. Incidents raised by this analytic should be investigated to see if the user accessing these files should be accessing them, and if the volume they accessed them at was related to a legitimate business need.
This query contains thresholds to reduce the chance of false positives, these can be adjusted to suit individual environments. In addition false positives could be generated by legitimate, scheduled actions that occur less often than every 14 days, additional exclusions can be added for these actions on username or IP address entities. This query uses the imFileEvent schema from ASIM, you will first need to ensure you have ASIM deployed in your environment. Ref https://learn.microsoft.com/azure/sentinel/normalization-about-parsers
version: 1.0.1
version: 1.0.2
kind: Scheduled
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,34 @@ query: |
| extend RoleName = trim('"',tostring(Property.newValue))
)
| where RoleName contains "admin"
| extend InitiatingApp = tostring(InitiatedBy.app.displayName)
| extend Initiator = iif(isnotempty(InitiatingApp), InitiatingApp, tostring(InitiatedBy.user.userPrincipalName))
| extend AddedUser = iff(OperationName=="Add member to role",tostring(TargetResources[0].userPrincipalName),tostring(TargetResources[2].userPrincipalName))
| project-reorder TimeGenerated, AddedUser, RoleName, Initiator
| 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 = iif(isnotempty(InitiatingAppName), InitiatingAppName, InitiatingUserPrincipalName)
| extend TargetUserPrincipalName = iff(OperationName=="Add member to role",tostring(TargetResources[0].userPrincipalName),tostring(TargetResources[2].userPrincipalName))
| extend TargetAadUserId = iff(OperationName=="Add member to role", tostring(TargetResources[0].id), tostring(TargetResources[2].id))
| extend AddedUser = TargetUserPrincipalName
| extend TargetAccountName = tostring(split(TargetUserPrincipalName, "@")[0]), TargetAccountUPNSuffix = tostring(split(TargetUserPrincipalName, "@")[1])
| extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])
| project-reorder TimeGenerated, AddedUser, RoleName, InitiatedBy
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: Initiator
- identifier: Name
columnName: TargetAccountName
- identifier: UPNSuffix
columnName: TargetAccountUPNSuffix
- identifier: AadUserId
columnName: TargetAadUserId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AddedUser
version: 1.0.2
- identifier: Name
columnName: InitiatingAccountName
- identifier: UPNSuffix
columnName: InitiatingAccountUPNSuffix
- identifier: AadUserId
columnName: InitiatingAadUserId
version: 1.0.3
kind: Scheduled
Loading