Microsoft Defender ATP Advanced Hunting – Who’s logging on with local admin rights?

Note: I have updated the kql queries below, but the screenshots itself still refer to the previous (old) schema names

If you’re among those administrators that use Microsoft Defender Advanced Threat Protection, here’s a handy tip how to find out who’s logging on with local administrators’ rights. But first when would you want to run this? Well here are some scenarios I can think of:

  1. You want to find users that have local administrator rights on their devices.
  2. You introduced LAPS and instructed your IT support to no longer use their own credentials but use the LAPS Administrator and password. (here’s a great article why you should do so. Remote Use of Local Accounts: LAPS Changes Everything
  3. You’re proactively looking for suspicious behaviour

Or if you want to get more details about the computer and how they logged on (Remote Interactive, Interactive or via the network such as with PowerShell) simply comment out the summarize line in the kusto query code.

Yes I know screenshots with code aren’t cool, so here again to copy paste:

Update: August 2020, i have updated the below query to work with the latest MDATP hunting schema

// Uses that logon with local admin rights summary

DeviceLogonEvents
| where IsLocalAdmin == 1
| extend locallogon = extractjson(“$.IsLocalLogon”,AdditionalFields, typeof(string))
| project Timestamp , DeviceName, AccountDomain, AccountName , LogonType, ActionType, locallogon
| summarize count() by AccountName

 

// users that logon on with Local Admin rights – detailed

DeviceLogonEvents
| where IsLocalAdmin == 1
| extend locallogon = extractjson(“$.IsLocalLogon”,AdditionalFields, typeof(string))
| project Timestamp , DeviceName, AccountDomain, AccountName , LogonType, ActionType, locallogon

9 Replies to “Microsoft Defender ATP Advanced Hunting – Who’s logging on with local admin rights?”

  1. Thanks VERY much for this tip, however is it possible a couple of fields have changed since you wrote this?
    This worked for me:
    DeviceLogonEvents| where IsLocalAdmin == 1
    | extend locallogon = extractjson(“$.IsLocalLogon”,AdditionalFields, typeof(string))
    | project Timestamp , DeviceName, AccountDomain, AccountName , LogonType, ActionType, locallogon
    // summarize by user
    | summarize count() by AccountName

  2. Thanks very much for your knowledge!
    However is it possible a couple of the fields have changed since you wrote this?
    This worked for me:

    DeviceLogonEvents| where IsLocalAdmin == 1
    | extend locallogon = extractjson(“$.IsLocalLogon”,AdditionalFields, typeof(string))
    | project Timestamp , DeviceName, AccountDomain, AccountName , LogonType, ActionType, locallogon
    // summarize by user
    | summarize count() by AccountName

  3. Were you successfully able to create a detection rule from this query? I’m getting syntax errors and am still unsure what’s wrong as these aren’t very verbose

  4. Hello Michael, i have updated the queries, they used the old MDATP schema , should work now

    DeviceLogonEvents
    | where IsLocalAdmin == 1
    | extend locallogon = extractjson(“$.IsLocalLogon”,AdditionalFields, typeof(string))
    | project Timestamp , DeviceName, AccountDomain, AccountName , LogonType, ActionType, locallogon
    | summarize count() by AccountName

  5. If you’re looking for this in Azure Sentinel:

    Replace:
    | extend locallogon = extractjson(“$.IsLocalLogon”,AdditionalFields, typeof(string))

    with this:
    | where AdditionalFields.IsLocalLogon == true

  6. i get this error: Error message
    Path expression IsLocalLogon source must be scalar of type ‘dynamic’. Received a source of type string instead

Leave a Reply