In today’s blog, we’re diving into the world of hunting through APIs. In the blog, the advantages, limitations, and scopes of the Graph API, Azure Monitor API, and Defender ATP API are discussed. For all of these solutions, a ready-to-use PowerShell script is shared.
These APIs can enhance security operations, automate threat detection, and enable bigger automation potential. In this blog the following topics are discussed:
The next blog explains how these APIs can be used in Logic Apps, so stay tuned for the next one!
When working with the different APIs, understanding the scope and available tables of each API is crucial for planning your API strategy. The summary of the available data is shown in the table below.
Azure Monitor API | ❌ | ✅ |
Graph API | ✅ | ✅ |
Defender ATP API | ⚠️ - MDE Data only | ❌ |
Azure Monitor API: This API enables querying data within the Log Analytics Workspace and therefore the data you ingest into Sentinel. The actual data returned is dependent on the configuration of your Sentinel connectors. The Azure Monitor API can list and visualize the results.
Graph API: The Graph API can query both Defender XDR and Sentinel tables. When Unified XDR is enabled, it offers a unified querying experience across these platforms. If Unified XDR is not enabled, you can still query all Defender XDR tables.
Defender ATP API: This API is specifically designed to query tables within Defender for Endpoint. It can return both the Devices and Defender Vulnerability Management tables, this limits the capabilities of the API as the scope is very limited.
Defender ATP API: It is not recommended to use the Defender ATP Advanced Hunting API, as it is an older version with limited capabilities (More info available in the documentation). This biggest limitation is that the Defender ATP API is limited to Defender For Endpoint data only, the Graph API is more futureproof as it supports hunting across Unified XDR.
Table Support
Diving into the more specific comparison the differences in scope become very clear. Knowing these results the best practice is to use the Graph API as it has support for both Defender XDR and Sentinel data. If you have not migrated to Unified XDR yet, a combination of Graph API and Azure Monitor API is recommended, this gives full query coverage for the tables in both solutions.
Alerts & behaviors | ❌ | ✅ | ✅ | ❌ |
Apps & identities | ❌ | ✅ | ✅ | ❌ |
Email & collaboration | ❌ | ✅ | ✅ | ❌ |
Devices | ❌ | ✅ | ✅ | ✅ |
Defender Vulnerability Management | ❌ | ✅ | ✅ | ✅ |
Email & collaboration | ❌ | ✅ | ✅ | ❌ |
Cloud Infrastructure | ❌ | ✅ | ✅ | ❌ |
Sentinel - Connector Data | ✅ | ✅ | ❌ | ❌ |
Sentinel - Custom Logs | ✅ | ✅ | ❌ | ❌ |
For each API a different permission is needed, these permissions should be assigned to Service Principals or Managed Identities. The permissions required for each API are listed below. Logic App permissions should not be assigned to personal accounts as this has multiple disadvantages.
Azure Monitor API | Log Analytics API | Data.Read | Required |
Graph API | Graph | ThreatHunting.Read.Al | Required |
Defender ATP API | WindowsDefenderATP | AdvancedQuery.Read.All | Required |
Azure Monitor API
Configuration steps:
- Create App Registrations
- API Permissions -> Add Permissions -> APIs my organization uses
- Log Analytics API -> Application Permissions -> Data.Read
- Grant admin consent
Graph API
Configuration steps:
- Create App Registrations
- API Permissions -> Add Permissions -> Microsoft Graph
- Application Permissions -> ThreatHunting -> ThreatHunting.Read.All
- Grant admin consent
Defender ATP API
Configuration steps:
- Create App Registrations
- API Permissions -> Add Permissions -> APIs my organization uses
- WindowsDefenderATP -> Application Permissions -> AdvancedQuery -> AdvancedQuery.Read.All
- Grant admin consent
Next up the API limitations, be aware of these limitations before deciding on an API strategy. The limitations again highlight one of the limitations of the Defender ATP API, the query timeframes are limited to the 30 days of the MDE tables, whereas the Azure Monitor and Graph API can return the results based on the retention settings of the tables.
Both the Query Execution Time and Total Execution Time highlight the importance of query optimization. Using KQL best practices will allow you to execute more calls, as the total CPU time needed per query will be limited. The query resources used for the APIs can be found in the query resources report in Defender XDR.
Timeframe | Table retention | Table retention | 30 Days |
Max Rows | 500.000 | 100.000 | 100.000 |
Calls | 200 requests per 30 seconds per Microsoft Entra user or client IP address. | You can make up to at least 45 calls per minute per tenant. The number of calls varies per tenant based on its size. | 45 calls per minute, and up to 1,500 calls per hour. |
Query Execution Time (Seconds) | 600 | 180 | 200 |
Total Execution Time | Not specified | 15-minute CPU cycles | 10 minutes of running time every hour and 3 hours of running time a day. |
High query volumes: In case you work with very high query volumes it is recommended to use the Graph API for Defender XDR data only, the Azure Monitor API should in that case only be used to query your Sentinel data. This approach can double the amount of executed requests per minute.
Service limits documentation:
Graph API Benchmark
The Graph API call limitations are dependable on the size of your tenant, with 45 calls per minute being a low number this had to be put to the test. The tenant size that was used for this benchmark is small (20 users). The results are shown in the visual below, in this small test tenant it is possible to constantly perform more than 45 calls per minute. These results show the potential to call the API 100s times per minute for large tenants.
Benchmark Graph API
You can benchmark the Graph API Limit yourself by running the query below.
We know which data can be queried through each API and what permissions are required it becomes time to execute queries. The PowerShell scripts below run a KQL query that is executed over the corresponding API. Before you can execute the PowerShell scripts an App Registration must be completed in Azure, with the permissions as mentioned above. Once the App Registration is completed Admin consent is needed before the permissions can be used. The example script uses a secret for easy use, this secret needs to be added to the application to make the API connections work.
Azure Monitor API
Graph API
Defender ATP API
The executed API calls can be traced to the application or user that makes the API calls. The executed API calls covering Defender XDR are available in the query resources report, but the fun does not end there.
Graph API
The most obvious one to monitor is the Graph API runHuntingQuery call, this can can be monitored using the query below. The logs only list who executed the query and if it was successful. The body of the Graph API call is not logged in the MicrosoftGraphActivityLogs table, meaning that you cannot get information on the executed query.
Azure Monitor
For the Azure Monitor API we can again leverage the LAQueryLogs to determine who executed which query. Combining the LAQueryLogs with the AADSpnSignInEventsBeta it is also possible to enrich the ApplicationId with the ApplicationName, the analysts will love you for it. The results state the executed query, the request client application, the target LAW and the application/user that performed the action.
The next blog will explain how the above APIs can be leveraged in Logic Apps, stay tuned for more! :)
Happy hunting! 🏹