Query Details

Azure Dev Ops High Volume Search Activity

Query

# *Azure DevOps High Volume Search Activity*

## Query Information

#### MITRE ATT&CK Technique(s)

| Technique ID | Title    | Link    |
| ---  | --- | --- |
| T1526 | Cloud Service Discovery | https://attack.mitre.org/techniques/T1526 |
| T1550.001 | Use Alternate Authentication Material: Application Access Token | https://attack.mitre.org/techniques/T1550/001 |

#### Description

Detects unusually high volumes of search activity within Azure DevOps by a single user from a specific IP address and user agent within a defined time window. This could indicate an adversary attempting to enumerate project details, source code, or other sensitive information.


#### Author <Optional>
- **Name: Benjamin Zulliger**
- **Github: https://github.com/benscha/KQLAdvancedHunting**
- **LinkedIn: https://www.linkedin.com/in/benjamin-zulliger/**

#### Possible false positives
- Legitimate administrative tasks involving extensive searching.
- Automated scripts or integrations performing numerous queries.
- Users conducting legitimate, in-depth research or investigations within Azure DevOps.

## Defender XDR
```KQL
let CorporateIPRange = "xx.xx.0.0/16";
// Threshold for the minimum number of search queries within the time window
let Threshold = 20;
// Time window size for aggregating search activities (e.g., 20 minutes)
let Window = 20m;
// Target table for Azure DevOps Audit Logs (Custom Log)
ADOAuditLogs_CL
// Filter for search-related activities in either the ActionId or Area fields
| where ActionId has "Search" or Area =~ "Search"
// Extract the actual search query string from the JSON payload in the 'Data' column
| extend SearchQuery = tostring(parse_json(Data).SearchQuery)
// Aggregate data by user (ActorUPN), source IP, UserAgent, and the defined time window buckets
| summarize 
    StartTime = min(TimeGenerated),        // Timestamp of the first search in this window
    EndTime = max(TimeGenerated),          // Timestamp of the last search in this window
    TotalCount = count(),                  // Total number of search requests executed
    UniqueQueries = dcount(SearchQuery),   // Count of distinct search terms used
    QueryList = make_set(SearchQuery)      // Array containing the unique search terms
    by bin(TimeGenerated, Window), ActorUPN, IpAddress, UserAgent
// Alert trigger: Only keep records that meet or exceed the defined threshold
| where TotalCount >= Threshold
// use this Filter for noise reduction
//| where not(ipv4_is_in_range( IpAddress, (CorporateIPRange))) 
```

Explanation

This query is designed to detect suspiciously high volumes of search activity in Azure DevOps by a single user. It focuses on identifying potential unauthorized attempts to gather sensitive information, such as project details or source code, by monitoring search activities.

Here's a simplified breakdown of the query:

  1. Corporate IP Range: The query defines a specific IP range (xx.xx.0.0/16) that represents the corporate network. This can be used to filter out internal traffic if needed.

  2. Threshold and Time Window: It sets a threshold of 20 search queries within a 20-minute window. This means that if a user performs 20 or more searches within this time frame, it will be flagged for further investigation.

  3. Data Source: The query examines Azure DevOps Audit Logs, specifically looking for activities related to searches.

  4. Search Activity Filtering: It filters logs to include only those related to search actions, identified by the presence of "Search" in the ActionId or Area fields.

  5. Data Aggregation: The query aggregates search data by user, IP address, user agent, and time window. It calculates:

    • The start and end times of the search activity.
    • The total number of search requests.
    • The number of unique search queries.
    • A list of unique search terms used.
  6. Alert Trigger: It only keeps records where the total number of search requests meets or exceeds the threshold, indicating potentially suspicious activity.

  7. Noise Reduction: There's an optional filter to exclude searches from the corporate IP range, which can help reduce false positives by ignoring internal, possibly legitimate, search activities.

Overall, this query helps identify users who might be conducting excessive searches, which could be a sign of malicious activity, while also considering possible legitimate reasons for such behavior.

Details

Benjamin Zulliger profile picture

Benjamin Zulliger

Released: June 18, 2026

Tables

ADOAuditLogs_CL

Keywords

AzureDevOpsUserIPAddressUserAgentProjectSourceCodeInformationLogsSearchQueryDataTimeWindow

Operators

lethasor=~tostringparse_jsonsummarizeminmaxcountdcountmake_setbybinwhere>=

Actions