├── Media └── MEID-ElevateAccessEvents.png ├── README.md ├── Entra ID ├── MEID-SignIns-TorExitNodes.md ├── MEID-AttackDisruption-Actions.md └── MEID-ElevateAccessEvents.md ├── Defender For Endpoint ├── MDE-KDFv1-Retirement.md ├── MDE-PrintSpoolerUsage.md └── MDE-DefaultLocalAdmin-Logon.md └── Defender for Cloud Apps └── MDA-User-Removed-From-PrivateTeamsChannel.md /Media/MEID-ElevateAccessEvents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorisAmbrozzo/KQL-Queries/HEAD/Media/MEID-ElevateAccessEvents.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KQL-Queries for Microsoft Defender XDR and Microsoft Sentinel 2 | Hunting and detection queries repository. This repository contains (or will contain) queries for the following products: 3 | 4 | - Microsoft Defender for Endpoint 5 | - Microsoft Defender for Office 365 6 | - Microsoft Defender for Identity 7 | - Microsoft Defender for Cloud Apps 8 | - Microsoft Sentinel 9 | - Microsoft Entra 10 | 11 | > [!NOTE] 12 | > All queries are based on my own experience and research without any guarantee. 13 | 14 | 15 | -------------------------------------------------------------------------------- /Entra ID/MEID-SignIns-TorExitNodes.md: -------------------------------------------------------------------------------- 1 | # MEID-SignIns-TorExitNodes 2 | This KQL query retrieves all Tor exit nodes from the official tor project website. Tor exit nodes are the gateways of the communication flow between the Tor client and the destination server (after leaving the Tor network). Any request coming from one of these IP addresses indicates that the request came from the Tor network. 3 | 4 | This query can be used to check how many login attempts are coming from Tor exit nodes to the Entra ID tenant and whether further login attempts from Tor exit nodes should be blocked (e.g. conditional access) or not. 5 | 6 | ## Microsoft Sentinel 7 | ```kql 8 | let TorExitNodes = externaldata (IPAddress: string) ['https://check.torproject.org/torbulkexitlist'] with (format=txt); 9 | union SigninLogs, AADNonInteractiveUserSignInLogs 10 | | where TimeGenerated > ago(90d) 11 | //| where ResultType == 0 //See all successfull Logons 12 | | lookup kind = inner TorExitNodes on $left.IPAddress == $right.IPAddress 13 | | project 14 | TimeGenerated, 15 | Category, 16 | ResultType, 17 | ResultDescription, 18 | Identity, 19 | AppDisplayName, 20 | IPAddress, 21 | AuthenticationRequirement, 22 | RiskDetail, 23 | RiskState, 24 | RiskLevelAggregated, 25 | RiskLevelDuringSignIn, 26 | RiskEventTypes_V2 27 | ``` 28 | 29 | ## References 30 | - [Offical Tor Exit List Service from the Tor Project](https://check.torproject.org/torbulkexitlist) -------------------------------------------------------------------------------- /Defender For Endpoint/MDE-KDFv1-Retirement.md: -------------------------------------------------------------------------------- 1 | # MDE-KDFv1-Retirement 2 | 3 | KQL Query to list devices which are still using the KDFv1 (Key Derivation Function) algorithm to store the Primary Refresh Token which was addressed in CVE-2021-33781. Unpatched devices using the KDFv1 algorithm will no longer be able to sign in to Entra ID. 4 | 5 | Based on Microsoft Entra news from June 2024, users of Windows devices that haven't been patched since July 2021 may experience login failures with their Entra ID user accounts on an Entra joined or hybrid joined Windows device because the KDFv1 algorithm will be retired. With the patch after July 2021, Windows clients will use the stronger KDFv2 algorithm. 6 | 7 | ## Microsoft Defender XDR 8 | 9 | ```kql 10 | DeviceTvmSoftwareVulnerabilities 11 | | where CveId == "CVE-2021-33781" 12 | | join kind = inner (DeviceInfo 13 | | summarize arg_max(Timestamp, *) by DeviceId 14 | ) 15 | on $left.DeviceId == $right.DeviceId 16 | | where SoftwareName in~("windows_10","windows_11") and JoinType in~("Hybrid Azure AD Join","AAD Joined") 17 | | project DeviceId, 18 | DeviceName, 19 | OSPlatform, 20 | OSVersion, 21 | OSVersionInfo, 22 | SoftwareVendor, 23 | SoftwareVersion, 24 | CveId, 25 | VulnerabilitySeverityLevel, 26 | RecommendedSecurityUpdate, 27 | RecommendedSecurityUpdateId, 28 | JoinType, 29 | MachineGroup, 30 | LoggedOnUsers, 31 | OnboardingStatus 32 | ``` 33 | ## References 34 | - [Security update to Entra ID affecting clients which are running old, unpatched builds of Windows](https://techcommunity.microsoft.com/t5/microsoft-entra-blog/what-s-new-in-microsoft-entra-june-2024/ba-p/3796387) 35 | -------------------------------------------------------------------------------- /Entra ID/MEID-AttackDisruption-Actions.md: -------------------------------------------------------------------------------- 1 | # MEID-AttackDisruption-Actions 2 | The Enterprise Application **Microsoft Defender for Identity (formerly known as Radius Aad Syncer)** with the App ID _60ca1954-583c-4d1f-86de-39d835f3e452_ is responsible for executing Microsoft Defender XDR Attack Disruption actions in Entra ID. The KQL query lists each triggered Defender XDR Attack Disruption action in Entra ID performed by this service principal. 3 | 4 | To use the query, insert the **Service Principal Object ID** from the Enterprise Application with the App ID _60ca1954-583c-4d1f-86de-39d835f3e452_. 5 | 6 | ## Microsoft Sentinel 7 | ```kql 8 | AuditLogs 9 | | where TimeGenerated > ago(180d) 10 | | mv-expand InitiatedBy, TargetResources 11 | | mv-expand modifiedUserProperty = TargetResources.modifiedProperties 12 | | extend InitiatedApp = InitiatedBy.app 13 | | where InitiatedApp.servicePrincipalId == "INSERT OBJECT ID" // Filter for Microsoft Defender for Identity (formerly Radius Aad Syncer) Service Principal 14 | | extend 15 | ModifiedProperty = modifiedUserProperty.displayName, 16 | OldValue = modifiedUserProperty.oldValue, 17 | NewValue = modifiedUserProperty.newValue 18 | | project 19 | TimeGenerated, 20 | InitiatedApp.displayName, 21 | OperationName, 22 | TargetResources.userPrincipalName, 23 | ModifiedProperty, 24 | OldValue, 25 | NewValue, 26 | Result 27 | ``` 28 | 29 | ## References 30 | - [First-Party Microsoft Enterprise Applications](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in) 31 | - [Microsoft Defender XDR Attack disruption automated response actions](https://learn.microsoft.com/en-us/defender-xdr/automatic-attack-disruption#automated-response-actions) -------------------------------------------------------------------------------- /Defender For Endpoint/MDE-PrintSpoolerUsage.md: -------------------------------------------------------------------------------- 1 | # MDE-PrintSpoolerUsage 2 | 3 | The spooler accepts print jobs from computers and ensures that printer resources are available. To mitigate Print Spooler attacks, it is recommended that the Print Spooler service is disabled if the service is not required (e.g. Print Server). This KQL query lists each Windows server that is using the print spooler because an external client has accessed the print spooler service. 4 | 5 | ## Microsoft Defender XDR 6 | ```kql 7 | let lookback = 30d; 8 | DeviceNetworkEvents 9 | | where Timestamp > ago(lookback) 10 | | where InitiatingProcessFileName == @"spoolsv.exe" 11 | | where ActionType != @"ListeningConnectionCreated" and ActionType != @"ConnectionFailed" 12 | | join kind = inner 13 | ( 14 | DeviceInfo 15 | | summarize arg_max(Timestamp, *) by DeviceId 16 | ) 17 | on $left.DeviceId == $right.DeviceId 18 | | where OSPlatform startswith "WindowsServer" 19 | | summarize PrintSpoolerUsageCount = count() by DeviceName 20 | ``` 21 | 22 | ## Microsoft Sentinel 23 | ```kql 24 | let lookback = 30d; 25 | DeviceNetworkEvents 26 | | where TimeGenerated > ago(lookback) 27 | | where InitiatingProcessFileName == @"spoolsv.exe" 28 | | where ActionType != @"ListeningConnectionCreated" and ActionType != @"ConnectionFailed" 29 | | join kind = inner 30 | ( 31 | DeviceInfo 32 | | summarize arg_max(TimeGenerated, *) by DeviceId 33 | ) 34 | on $left.DeviceId == $right.DeviceId 35 | | where OSPlatform startswith "WindowsServer" 36 | | summarize PrintSpoolerUsageCount = count() by DeviceName 37 | ``` 38 | 39 | ## References 40 | - [Print Spooler Service](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-prsod/7262f540-dd18-46a3-b645-8ea9b59753dc) 41 | - [Defender for Identity Print Spooler Assessment](https://learn.microsoft.com/en-us/defender-for-identity/security-assessment-print-spooler) -------------------------------------------------------------------------------- /Entra ID/MEID-ElevateAccessEvents.md: -------------------------------------------------------------------------------- 1 | # MEID-ElevateAccessEvents 2 | As a Global Administrator, it is possible to access all subscriptions and management groups within a tenant by elevating access. This feature is particularly useful when an Azure subscription becomes orphaned (lacks an owner). Elevated access is highly privileged access. It might be important to audit when access was elevated and who performed the action. Since Januar 2025 this Operation is logged within the Entra Audit Logs. 3 | 4 | Elevated Access can be enabled within the Entra Portal : 5 | 6 | ![](https://raw.githubusercontent.com/lorisAmbrozzo/KQL-Queries/refs/heads/main/Media/MEID-ElevateAccessEvents.png?raw=true) 7 | 8 | 9 | ## Microsoft Sentinel 10 | ```kql 11 | AuditLogs 12 | | where Category == "AzureRBACRoleManagementElevateAccess" 13 | //| where OperationName == "User has elevated their access to User Access Administrator for their Azure Resources" //Uncomment if you only want to detect Elevate Access activation 14 | //| where OperationName == "The role assignment of User Access Administrator has been removed from the user" //Uncomment if you only want to detect Elevate Access deactivation 15 | | extend InvolvedUser = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName) 16 | | extend InvolvedIPAddress = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress) 17 | | project 18 | TimeGenerated, 19 | Category, 20 | OperationName, 21 | InvolvedUser, 22 | InvolvedIPAddress 23 | ``` 24 | 25 | ## References 26 | - [Elevate Access events are now exportable via Entra Audit Logs | Now in Public Preview](https://www.linkedin.com/pulse/elevate-access-events-now-exportable-via-entra-audit-logs-woaoe/) 27 | - [Elevate access to manage all Azure subscriptions and management groups](https://learn.microsoft.com/en-us/azure/role-based-access-control/elevate-access-global-admin?tabs=azure-portal%2Centra-audit-logs) -------------------------------------------------------------------------------- /Defender for Cloud Apps/MDA-User-Removed-From-PrivateTeamsChannel.md: -------------------------------------------------------------------------------- 1 | # MDA-User-Removed-From-PrivateTeamsChannel 2 | In the event of an incident response case, one possibility is to disable a user account in Entra ID/Active Directory to stop an ongoing attack. Microsoft Defender XDR Attack Disruption also automatically disables user accounts in the event of an active attack. By design, disabling the user account automatically removes the account from all Microsoft Teams. However, even after the account is re-enabled, it is possible that the user will not see the teams they were previously a member of. 3 | 4 | - **Standard Channels**: It can take up to 24–48 hours for the account memberships to be automatically restored for standard channels. 5 | - **Private Channels**: For private channels, the user will not be automatically added to the private channel again. They must make new membership requests for each private channel that they want to rejoin. 6 | 7 | This KQL query will list all the private channels from which the user was removed by querying the Cloud App Events table. 8 | 9 | 10 | ## Microsoft Defender XDR 11 | ```kql 12 | let affectedUser = "INSERT UPN"; //Update UPN 13 | let actionFilter = "MemberRemoved"; 14 | let lookBackTime = 8h; //Update look back time 15 | CloudAppEvents 16 | | where Timestamp > ago(lookBackTime) 17 | | where Application == "Microsoft Teams" 18 | | where ActionType == actionFilter 19 | | extend Workload = RawEventData.Workload 20 | | extend TeamsChannelName = RawEventData.ItemName 21 | | extend TeamsName = RawEventData.TeamName 22 | | mv-expand Members = RawEventData.Members 23 | | extend TeamsMember = Members.UPN 24 | | extend ChannelType = RawEventData.ChannelType 25 | | where TeamsMember == affectedUser 26 | | where ChannelType == "Private" 27 | | project 28 | Timestamp, 29 | Workload, 30 | Actor = AccountDisplayName, 31 | ActionType, 32 | TeamsName, 33 | TeamsChannelName, 34 | TeamsMember, 35 | ChannelType 36 | | order by Timestamp desc 37 | ``` 38 | 39 | ## References 40 | - [You don't see team members after your account is re-enabled](https://learn.microsoft.com/en-us/troubleshoot/microsoftteams/channels/logon-reenabled-user-not-see-previous-joined-teams) 41 | - [Private channels in Microsoft Teams](https://learn.microsoft.com/en-us/MicrosoftTeams/private-channels) 42 | - [Automatic Attack Disruption - Response actions](https://learn.microsoft.com/en-us/defender-xdr/automatic-attack-disruption#automated-response-actions) -------------------------------------------------------------------------------- /Defender For Endpoint/MDE-DefaultLocalAdmin-Logon.md: -------------------------------------------------------------------------------- 1 | # MDE-DefaultLocalAdmin-Logon 2 | This KQL query identifies logon events for the default local administrator (.\Administrator) with SID starting with S-1-5 and ending with 500 (according well-know SIDs). As the default domain administrator also starts with S-1-5 and ends with -500, the query includes a table containing the default domain administrator's SID of the domain to exclude these logons. 3 | 4 | The following logon types exists: 5 | 6 | 7 | | Logon Type | Description | 8 | | ----------| ---------- | 9 | | Interactive | User physically interacts with the device using the local keyboard and screen. | 10 | | Remote interactive (RDP) logons | User interacts with the device remotely using Remote Desktop, Terminal Services, Remote Assistance, or other RDP clients. | 11 | | Network | Session initiated when the device is accessed using PsExec or when shared resources on the device, such as printers and shared folders, are accessed. 12 | | Batch | Session initiated by scheduled tasks. 13 | | Service | Session initiated by services as they start. 14 | 15 | ## Microsoft Defender XDR 16 | 17 | ```kql 18 | let DefauldDomainAdministrators = dynamic([ 19 | "S-1-5-XXXXXXXXXX-XXXXXXXXX-XXXXXXXXXX-500", //Default Domain Administrator SID Domain X 20 | "S-1-5-XXXXXXXXXX-XXXXXXXXX-XXXXXXXXXX-500" // Default Domain Administrator SID Domain Y 21 | ]); 22 | DeviceLogonEvents 23 | | where AccountSid startswith "S-1-5-" and AccountSid endswith "-500" 24 | | where IsLocalAdmin == true 25 | | join kind = inner ( 26 | DeviceInfo 27 | | summarize arg_max(Timestamp, *) by DeviceId 28 | ) 29 | on $left.DeviceId == $right.DeviceId 30 | | where AccountSid !in~(DefauldDomainAdministrators) //Comment this line if you also want to see default domain administrator logins 31 | | summarize count() 32 | by 33 | DeviceName, 34 | LogonType, 35 | AccountDomain, 36 | AccountName, 37 | OSPlatform, 38 | MachineGroup 39 | ``` 40 | 41 | ## Microsoft Sentinel 42 | 43 | ```kql 44 | let DefauldDomainAdministrators = dynamic([ 45 | "S-1-5-XXXXXXXXXX-XXXXXXXXX-XXXXXXXXXX-500", //Default Domain Administrator SID Domain X 46 | "S-1-5-XXXXXXXXXX-XXXXXXXXX-XXXXXXXXXX-500" // Default Domain Administrator SID Domain Y 47 | ]); 48 | DeviceLogonEvents 49 | | where AccountSid startswith "S-1-5-" and AccountSid endswith "-500" 50 | | where IsLocalAdmin == true 51 | | join kind = inner ( 52 | DeviceInfo 53 | | summarize arg_max(TimeGenerated, *) by DeviceId 54 | ) 55 | on $left.DeviceId == $right.DeviceId 56 | | where AccountSid !in~(DefauldDomainAdministrators) //Comment this line if you also want to see default domain administrator logins 57 | | summarize count() 58 | by 59 | DeviceName, 60 | LogonType, 61 | AccountDomain, 62 | AccountName, 63 | OSPlatform, 64 | MachineGroup 65 | ``` 66 | 67 | ## References 68 | - [Active Directory Security identifiers](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers) 69 | - [DeviceLogonEvents table](https://learn.microsoft.com/en-us/defender-xdr/advanced-hunting-devicelogonevents-table) --------------------------------------------------------------------------------