Kusto Query LanguageMicrosoft Defender for EndpointMicrosoft SentinelSECURE

Detect Anomalous Amount of LDAP Traffic

Description

Adversaries can use LDAP to collect environment information. The query below can be used to detect anomalous amounts of LDAP queries from a originating device. This is done by baselining the normal amount of LDAP queries a device performs each hour. This query gives you input on which devices might need to be investigated.

Once you found a device you are interested in, simply use the Hunt For All Executed LDAP Queries From A Compromised Device query with the devicename as input to list all the LDAP details. The LDAP queries that list all devices and/or all users are interesting when executed from a workstation.

The query uses a variety of different variables which determine the result.

  • starttime – Determines the starting time of the search period
  • endtime – Determines the end time of the search period
  • timeframe – Determines the timeframe in which the amount of LDAP queries are counted. If you set this to 1 hour (1h) than a count for each hour is performed, if you set it to 1 day (1d) than a count for each day is performed and so on.
  • TotalEventsThreshold – Determines that each device must at least have performed 1 LDAP query to be included.

Only workstations are included by default in this alert. If you also want to investigate servers, then remove the line as specified in the comments of the query.

Risk

An adversary has gained access to your network and performs LDAP queries to perform reconnaissance.

Query

Microsoft Defender For Endpoint
Kusto
// Variables to define the anomalous behaviour
let starttime = 30d;
let endtime = 1d;
// Timeframe in which the amount of LDAP queries are counted
let timeframe = 1h;
let TotalEventsThreshold = 1;
// Collect workstation devicenames
let Workstations = DeviceInfo
    | where Timestamp > ago(30d)
    | where DeviceType == "Workstation"
    | distinct DeviceName;
// Collect LDAP statistics for each device
let TimeSeriesData = IdentityQueryEvents
    | where ActionType == "LDAP query"
    // If you want to have all devices included remove line below.
    | where DeviceName in~ (Workstations)
    | make-series PerHourCount=count() on Timestamp from startofday(ago(starttime)) to startofday(ago(endtime)) step timeframe by DeviceName;
// Generate LDAP baseline for each device
let TimeSeriesAlerts=TimeSeriesData
    | extend (anomalies, score, baseline) = series_decompose_anomalies(PerHourCount, 1.5, -1, 'linefit')
    | mv-expand
        PerHourCount to typeof(double),
        Timestamp to typeof(datetime),
        anomalies to typeof(double),
        score to typeof(double),
        baseline to typeof(long);
TimeSeriesAlerts
| where anomalies > 0
// Baseline is the most important result, that is the avarage amount of LDAP queries executed by a device, the PerHourCount shows the deviation from this amount.
| project DeviceName, Timestamp, PerHourCount, baseline, anomalies, score
| where PerHourCount > TotalEventsThreshold

Microsoft Sentinel
Kusto
// Variables to define the anomalous behaviour
let starttime = 90d;
let endtime = 1d;
// Timeframe in which the amount of LDAP queries are counted
let timeframe = 1h;
let TotalEventsThreshold = 1;
// Collect workstation devicenames
let Workstations = DeviceInfo
    | where TimeGenerated > ago(30d)
    | where DeviceType == "Workstation"
    | distinct DeviceName;
// Collect LDAP statistics for each device
let TimeSeriesData = IdentityQueryEvents
    | where ActionType == "LDAP query"
    // If you want to have all devices included remove line below.
    | where DeviceName in~ (Workstations)
    | make-series PerHourCount=count() on TimeGenerated from startofday(ago(starttime)) to startofday(ago(endtime)) step timeframe by DeviceName;
// Generate LDAP baseline for each device
let TimeSeriesAlerts=TimeSeriesData
    | extend (anomalies, score, baseline) = series_decompose_anomalies(PerHourCount, 1.5, -1, 'linefit')
    | mv-expand
        PerHourCount to typeof(double),
        TimeGenerated to typeof(datetime),
        anomalies to typeof(double),
        score to typeof(double),
        baseline to typeof(long);
TimeSeriesAlerts
| where anomalies > 0
// Baseline is the most important result, that is the avarage amount of LDAP queries executed by a device, the PerHourCount shows the deviation from this amount.
| project DeviceName, Timestamp, PerHourCount, baseline, anomalies, score
| where PerHourCount > TotalEventsThreshold

Leave a Reply

Your email address will not be published. Required fields are marked *