Use UEBA in Microsoft Sentinel to your advantage

When using Microsoft Sentinel you can connect multiple sources as data connectors. By default all connected sources will ingest their information to predefined tables in the Log Analytics workspace, backing the Microsoft Sentinel instance. You then can query this data using analytic rules or hunting queries to identify abnormal behavior.

But for a few of those data connectors Microsoft is offering an additional feature called “User and Entity Behavior Analytics” or UEBA for short.

Supported data connectors

Currently the following data connectors are supported

  • Sign-in logs from Azure Active Directory
  • Audit logs from Azure Active Directory
  • Azure Activity logs
  • Windows Security events related to sign-ins, privilege assignment and process creation

What is UEBA?

In short UEBA takes care of baselining your incoming data and detecting anomalies.

Microsoft is using the raw data ingested and applies different machine learning algorithms to identify the baseline behavioral profiles of your users, hosts, IP addresses and applications. Those baselines and additional security information from Microsoft is applied to newly ingested data and used to identify anomalies in the incoming signals.

Those anomalies are ingested into the BehaviorAnalytics table where you can query the results and alert based on the information.


But it does not end there. UEBA also synchronizes the user information from Azure Active Directory and on-premises Active Directory (currently in preview when using Microsoft Defender for Identity) into the IdentityInfo table, for you to use later on.

What additional information is provided?

You still might ask yourself “Why bother?”. Sure you can create custom queries in Kusto that are super powerful, but with UEBA some of the hard work is done for you.

When UEBA analyzes for example a sign-in event it will compare the sign-in against multiple baseline factors. It e.g., will detect if a user has never signed in from this country or ISP, give you information if the direct colleagues (peers) have done so and also compare it against the whole tenant.

User peer analytics result

Of course you could create an analytics rule that queries the baseline information for all the users in a tenant, you might even work out how to identify the direct peers of the users, but it will cost you immense time and effort.

And UEBA does not only check if the country from which the sign-in is originated might be off. It will also check the device, the browser, the ISP, if the users is accessing the app the first time, if the user is dormant or new and many other factors and offers them in a easy to consume way to you and even adds a InvestigationPriority value to each entry, so you know which entries are more important than others.

In short UEBA makes your live detection and alert engineering easier, because you can use the information from the BehaviorAnalytics and IdentityInfo to limit false positives to a minimum and answer complex queries in just a few lines of KQL.

For example if you would want to limit a query to sign-ins of a certain role, the table SigninLogs would not offer all the needed data. But using the IdentityInfo you can easily filter out only sign-ins from a member of the global administrator role.

| where TimeGenerated > ago(1d)
| join kind=inner (IdentityInfo
    | where TimeGenerated > ago(14d)
    on $left.UserId == $right.AccountObjectId
| where AssignedRoles contains "Global Administrator"
| sort by TimeGenerated
The IdentityInfo table is re-synchronized every 14 days, to make sure there are no stale records. This is the reason why I defined this value in the join operator.
The Default retention is set to 30 days.

Or you want to identify if a dormant account was used to sign-in. Would you only rely on the default configuration of Microsoft Sentinel you could identify an dormant user if it was not used in 90 days. You could extend data retention to a higher value to extend change this. When using UEBA a dormant account is tracked over the last 180 days and the query is super simple.

// only include users not in use for > 180 days
| where UsersInsights.IsDormantAccount == True

The field UsersInsights also can be useful to identify if the sign-in was from a user with local admin permissions (IsLocalAdmin) or if the account used was created in the last 30 days (IsNewAccount).

The fields UsersInsights , DevicesInsights and ActivityInsights offer UEBA enriched information, while InvestigationPriority is a integer value between 0 - 10.

For a complete overview of all enrichment values available through UEBA head over to the Microsoft Sentinel UEBA reference. Also keep in mind that a good identity management is necessary for some values to be populated. E.g., the value BlastRadius can only be used if the manager attribute is populated for the user in question.

How much does UEBA cost?

The additional information UEBA provides are billed like all other data sources, by ingested data. The more information is analyzed by UEBA the more data is ingested in the UEBA related tables and therefor added to you ingestions bill. Other than this, no additional charges apply.

If you are still in you 30 days trial period, use that time to get a better feel for the cost in your environment.

With the following KQL query you can check how much data was ingested by UEBA.

| where TimeGenerated > startofday(ago(90d))
| where Solution == "BehaviorAnalyticsInsights"
| summarize IngestedGB = sum(Quantity) / 1000 by Solution

You can also use the workbook template “Microsoft Sentinel Cost” which gives you a nice graphical interface.

UEBA ingestion charge

How to enable UEBA?

To enable UEBA in your environment you must have either the Global or Security Administrator role activated as well as Microsoft Sentinel Contributor or Log Analytics Contributor. When you have the correct roles activated head over to your Sentinel instance and go straight to the settings blade. Switch to the “Settings” tab on top and click on “Set UEBA”.

Setup UEBA

Now enable the data sources for the IdentityInfo table. Keep in mind that you need Microsoft Defender for Identity to include on-premises Active Directory.

Also enable the different tables that should be analyzed by UEBA. You can only control this on a table by table basis, you cannot certain entities (users or devices).

Configure UEBA sources

After you apply the changes the UEBA feature is enabled and it will take a few hours until the first data will be visible in the respective tables.

Microsoft also offers a Anomalies table, which can be disabled without affecting the other UEBA features.

Example queries


Using the information from the UserPeerAnalytics table can give you insights into which users are working together. UEBA calculates the top 20 peers based on mail distribution list, security groups, and other factors for each user including guest accounts.

The following query will give you a list of all users and the complete list of the calculated peers.

| summarize Peers=make_set(PeerUserPrincipalName) by UserPrincipalName

While this query might not be a good hunting query, but is allows you get a feel what information is used for the peer-based analytics in the BehaviorAnalytics table.

Activity from uncommon country

Using the ActivityInsights information you can easily check of there was any activity from a country that in uncommon for the tenant.

| where ActivityInsights.CountryUncommonlyConnectedFromInTenant == true

Alerting on this query would result in to much noise. You can use events with an InvestigationPriority above 0 to filter most of the noise.

| where ActivityInsights.CountryUncommonlyConnectedFromInTenant == true
| where InvestigationPriority > 0

If you don’t use UEBA for this simple query the KQL query would look something like this. That’s much more effort and only touches one of the factors UEBA can take into account. Of course it’s also more flexible, since you can decide which baseline timeframe you want to apply.

// Query all countries from tenant users have connected in the past and see if a new country was used in todays sign-in logs
let KnownLocation = 
| where TimeGenerated between (ago(30d)..ago(1d))
| where ResultType == 0
| distinct Location
| where isnotempty( Location );
| where TimeGenerated > ago(1d)
| where ResultType == 0
| extend City = tostring(
| extend State = tostring(
| where Location !in (KnownLocation)
| summarize by AppDisplayName, AppId, UserPrincipalName, UserId, IPAddress,NetworkLocationDetails, Location, City, State
UnifiedSignInLogs is a custom function which combines all user based sign-in logs. I published the code here.

Threat intelligence

Microsoft is also using their own threat intel to identify e.g. Tor exit nodes, bot net members and other threats. Some of this information is exposed in the ThreatIntelIndicatorDescription field.

| where TimeGenerated > ago(90d)
| extend ThreatIntelIndicatorDescription = DevicesInsights.ThreatIntelIndicatorDescription
| where isnotempty( ThreatIntelIndicatorDescription ) 
| where InvestigationPriority > 0

UEBA Threat Indicators

Detect new device usage from unknown country

When you want to get a list of all activities, where the user has used the device not in the last 30 days and the country is uncommonly used by the users peers.

| where TimeGenerated > ago(90d)
| where ActivityInsights.FirstTimeUserConnectedFromDevice == true
| where ActivityInsights.CountryUncommonlyConnectedFromAmongPeers == true
| where InvestigationPriority > 0


MFA Takeover of Dormant Accounts

Mandiant released information about a technique used by APT29 where the attacker tries to takeover dormant accounts. By guessing the password of a dormant account the threat actor tries to sign-in as the user and use the inital MFA setup process to register their own MFA method.

Using the additional information UEBA provides it is possible to use the following analytics query to identify such actions.

// only include users not in use for > 180 days
| where UsersInsights.IsDormantAccount == True
// only include sign-ins where the country was not used before by this user
| where ActivityInsights.FirstTimeUserConnectedFromCountry == True
// only include if the sign-in was from a country not seen in the tenant on a regular basis or the ISP used is new
| where ActivityInsights.CountryUncommonlyConnectedFromInTenant == True or ActivityInsights.FirstTimeConnectionViaISPInTenant == True
| extend AadUserId = tostring( UsersInsights.AccountObjectID )
// check if a new MFA method was registered by this user
| join kind=innerunique ( 
    | where OperationName == "User registered security info"
    | extend AadUserId = tostring( )
    | summarize arg_max(TimeGenerated, *) by AadUserId
    | project
        MFAChangeTime = TimeGenerated,
    ) on AadUserId
| project-away AadUserId1
| extend MinutesBetweenEvents = datetime_diff("minute",MFAChangeTime, TimeGenerated)
// only output entries where the latest security info registration happend after the suspicious sign-in
| where MinutesBetweenEvents >= 0

And if you also want to be informed when a new user (created in the last 30 days) does the same, you can just add IsNewAccount to the query.

| where UsersInsights.IsDormantAccount == True or UsersInsights.IsNewAccount == True

Analyze conditional access failures

But it does not stop at alerting, Thomas Naunheim demonstrates how you can easily detect unusual high sign-in errors based on Conditional Access policies. This might be helpful after you implemented some changes to your CAPs in production.

Check out the query in his GitHub.



User and Entity Behavior Analytics is a great way to get additional context information based on past activity. The provided information makes is easier to filter out potential false positive alerts based on those baselined information. For could offer your analysts the time to concentrate on alerts that are more serve.

Of course there might be scenarios where the baseline interval from Microsoft does not fit your needs, or the information provided is not exactly what you are looking for. In those cases you still can query and analyze larger datasets yourself, but for many use cases the data provided offers great value.

Undocumented values

When comparing the values available in the official documentation and in my public tenant I identified a few currently undocumented values that might be of help when building new detections.

Most of them seem to be related to the added support for some security event Ids which are currently in public preview (August 2022).


  • AppDisplayNameRecentlyChanged
  • AppIdUncommonlyAccessedInTenant
  • Process
  • ProcessId
  • NewProcessId
  • NewProcessName
  • ParentProcessName
  • CommandLine
  • FirstTimeProcessCreatedFromDirectoryByTenant
  • FirstTimeProcessCreatedFromDirectoryByUser
  • SimilarActionWasNotPerformedInThePast
  • UncommonHighVolumeOfActions
  • UncommonHighVolumeOfSameActionAcrossUsers
  • UnusualNumberOfDistinctUsersFailedSignInFromIPAddress
  • UnusualNumberOfFailedSignInOfThisUser
  • FirstTimeUserFailedToLoggedOnToDevice
  • UserAdded
  • UserCreated