Query Details

Multiple Suspicious Modificationof Global Admin Properties

Query

let query_frequency = 1h;
let query_period = 14d;
IdentityInfo
| where TimeGenerated > ago(query_period)
| where set_has_element(AssignedRoles, "Global Administrator")
| distinct AccountUPN, AccountObjectId
| join kind=inner (
    AuditLogs
    | where TimeGenerated > ago(query_frequency)
    | where OperationName=~ "Update user" and Result =~ "success"
    // | where isnotempty(InitiatedBy["user"])
    | mv-expand TargetResource = TargetResources
    | where TargetResource["type"] == "User"
    | extend AccountObjectId = tostring(TargetResource["id"])
    | where not(tostring(TargetResource["modifiedProperties"]) == "[]")
    | mv-apply modifiedProperty = TargetResource["modifiedProperties"] on (
        summarize modifiedProperties = make_bag(
            bag_pack(tostring(modifiedProperty["displayName"]),
                bag_pack("oldValue", trim(@'[\"\s]+', tostring(modifiedProperty["oldValue"])),
                    "newValue", trim(@'[\"\s]+', tostring(modifiedProperty["newValue"])))))
    )
    | where not(tostring(modifiedProperties["Included Updated Properties"]["newValue"]) in ("LastDirSyncTime", ""))
    | where not(tostring(modifiedProperties["Included Updated Properties"]["newValue"]) == "StrongAuthenticationPhoneAppDetail" and isnotempty(modifiedProperties["StrongAuthenticationPhoneAppDetail"]) and tostring(array_sort_asc(extract_all(@'\"Id\"\:\"([^\"]+)\"', tostring(modifiedProperties["StrongAuthenticationPhoneAppDetail"]["newValue"])))) == tostring(array_sort_asc(extract_all(@'\"Id\"\:\"([^\"]+)\"', tostring(modifiedProperties["StrongAuthenticationPhoneAppDetail"]["oldValue"])))))
    | extend
        Initiator = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["displayName"]), tostring(InitiatedBy["user"]["userPrincipalName"])),
        InitiatorId = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["servicePrincipalId"]), tostring(InitiatedBy["user"]["id"])),
        IPAddress = tostring(InitiatedBy[tostring(bag_keys(InitiatedBy)[0])]["ipAddress"])
    ) on AccountObjectId
| project
    TimeGenerated,
    Category,
    Identity,
    Initiator,
    IPAddress,
    OperationName,
    Result,
    AccountUPN,
    InitiatedBy,
    AdditionalDetails,
    TargetResources,
    AccountObjectId,
    InitiatorId,
    CorrelationId

Explanation

This query is designed to track changes made to user accounts by global administrators in a system over a period of 14 days. It specifically looks for successful "Update user" operations.

The query first identifies accounts with the role of "Global Administrator". Then, it joins this data with audit logs that show successful user updates within the last hour.

The query also expands and filters the data to only include updates where the modified properties of the user account are not empty. It excludes updates related to "LastDirSyncTime", empty updates, and updates related to "StrongAuthenticationPhoneAppDetail" that have not changed the ID.

Finally, the query identifies the initiator of the update, whether it's a user or an app, and their corresponding ID and IP address. The result is a detailed report of all user updates, including the time of the operation, the category, the identity of the user, the initiator, the IP address, the operation name, the result, the account UPN, who initiated the operation, any additional details, the target resources, the account object ID, the initiator ID, and the correlation ID.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: May 23, 2023

Tables

IdentityInfoAuditLogs

Keywords

IdentityInfo,AuditLogs,TimeGenerated,AssignedRoles,GlobalAdministrator,AccountUPN,AccountObjectId,OperationName,UpdateUser,Result,Success,TargetResource,User,ModifiedProperties,IncludedUpdatedProperties,LastDirSyncTime,StrongAuthenticationPhoneAppDetail,Initiator,InitiatedBy,IPAddress,Category,Identity,AdditionalDetails,TargetResources,CorrelationId

Operators

letwheredistinctjoinmv-expandextendnottostringmv-applysummarizemake_bagbag_packtriminisnotemptyarray_sort_ascextract_alliifbag_keysproject

Actions