Recently, I shared on Twitter how you could run a query to detect if a user has clicked on a link within their Outlook using Microsoft Defender Advanced Threat Protection (MDATP). If you are not familiar, MDATP is available within your Microsoft 365 E5 license and is an enhancement to the traditional Windows Defender you might be used to.
What is Microsoft Defender Advanced Threat Protection?
Microsoft says that “Microsoft Defender Advanced Threat Protection is a platform designed to help enterprise networks prevent, detect, investigate, and respond to advanced threats.” MDATP offers quite a few endpoints that you can leverage in both incident response and threat hunting.
The official documentation has several API endpoints that you can use to get, create, and update Alerts & Indicators. Additionally, here is a small list of some of the information you can retrieve, or actions you can perform, with the Microsoft Defender advanced threat protection APIs:
- Get all alerts related to a domain, file, IP, machine, or user.
- Retrieve information about who is logged on to a certain machine.
- Determine if a domain or IP has been seen in your organization.
These are just a few of the interesting APIs available, but to me, the most compelling—and the one we’re going to talk about—is advanced hunting.
Interacting with Microsoft Defender Advanced Threat Protection
I wrote a new bundle for Swimlane that wraps the entire Microsoft Defender ATP API endpoints, but for our non-customers, I would like to share with you how you can interact with the Microsoft Defender ATP API’s using both PowerShell Core and Python.
In order to interact with the Microsoft Defender advanced threat protection APIs, you must have the following:
- Microsoft 365 E5 License or access to MDATP.
- At least one endpoint must have MDATP installed and running.
- The ability to create a new application in Azure Active Directory.
First, let’s create a new application in Azure Active Directory. You can create a new application in Azure AD under the Azure Active Directory section and then navigating to App registrations. Click the New Registration button, and give your application a name. Then click Register.
Copy and save your Client Id and Tenant Id in a safe place (we will need this information shortly). Next, select the API Permissions section and click Add a permission. You should have a new blade on the left hand side.
When this new blade is open, select the APIs my organizations uses tab. You may need to filter in the search bar, but you should see WindowsDefenderATP listed as an option. If you do not, please make sure you have access to this API before proceeding.
Select the WindowsDefenderATP API and then select Application Permissions. Once you have selected the Application Permissions, you will be presented with a list of permissions. For this example I am selecting all so that I have access to all the endpoints available, but please use your discretion.
Once you have selected the desired permissions, click Add Permissions at the bottom and then on the main screen you will want to make sure that you select the Grand Admin consent to.
Next, go to the Certificates & Secrets section and create a New Client Secret. Once this is created, please save this with the other secrets we saved earlier.
Now that we have our secrets, we can use the two different files I have created that demonstrate how to use the MDATP APIs to retrieve a Token for future authentication as well as interact with the MDATP API directly.
I have provided a ps1 file that you can use as a reference. This file contains two PowerShell functions and at the bottom we are calling these functions as needed:
- Get-MDATPToken: Performs an OAuth2 authentication and retrieves a Token that we will use in all subsequent calls to the MDATP API endpoints.
- Invoke-MDATPQuery: Invokes an advanced hunting query to the MDATP advancedqueries/run endpoint.
By using these two functions, we can run queries on our endpoints that have MDATP installed.
First, let’s get our Token:
$Token = Get-MDATPToken -ClientId 'OUR_CLIENT_ID' -ClientSecret 'CLIENT_SECRET' -TenantId 'TENANT_ID'
Next, we can define a simple query:
$query = @" "RegistryEvents | limit 10" "@
$query = @" let minTimeRange = ago(7d); let outlookLinks = MiscEvents | where EventTime > minTimeRange and ActionType == "BrowserLaunchedToOpenUrl" and isnotempty(RemoteUrl) | where InitiatingProcessFileName =~ "outlook.exe" or InitiatingProcessFileName =~ "runtimebroker.exe" | project EventTime, MachineId, ComputerName, RemoteUrl, InitiatingProcessFileName, ParsedUrl=parse_url(RemoteUrl) | extend WasOutlookSafeLink=(tostring(ParsedUrl.Host) endswith "safelinks.protection.outlook.com") | project EventTime, MachineId, ComputerName, WasOutlookSafeLink, InitiatingProcessFileName, OpenedLink=iff(WasOutlookSafeLink, url_decode(tostring(ParsedUrl["Query Parameters"]["url"])), RemoteUrl); let alerts = AlertEvents | summarize (FirstDetectedActivity, Title)=argmin(EventTime, Title) by AlertId, MachineId | where FirstDetectedActivity > minTimeRange; alerts | join kind=inner (outlookLinks) on MachineId | where FirstDetectedActivity - EventTime between (0min..3min) | summarize FirstDetectedActivity=min(FirstDetectedActivity), AlertTitles=makeset(Title) by OpenedLink, InitiatingProcessFileName, EventTime=bin(EventTime, 1tick), ComputerName, MachineId, WasOutlookSafeLink "@
Now that we have our Token and Query, we can run our query using the Invoke-MDATPQuery function:
Invoke-MDATPTQuery -Token $Token -Query $query
Just like our PowerShell example, I have created two Python classes that will help with authentication and running advanced queries:
- MDATPConnector: Performs an OAuth2 authentication and retrieves a Token that we will use in all subsequent calls to the MDATP API endpoints.
- MDATPQuery: Invokes an advanced hunting query to the MDATP advancedqueries/run endpoint.
First, create a MDATPConnector object by providing your secrets:
connector = MDATPConnector( __CLIENT_ID__, __CLIENT_SECRET__, __TENANT_ID__ )
Next, for simplicity, let’s just run this smaller query:
query = ''' "RegistryEvents | limit 10" '''
Now, we need to pass in our MDATPConnector object and our query to the MDATPQuery class and then execute:
mdatp = MDATPQuery( connector, query ) print(mdatp.execute())
I hope you enjoyed learning about Microsoft Defender Advanced Threat Protection! Be on the lookout for our new bundle that covers Advanced Queries and all other endpoints available within the MDATP API.
Gartner: Create a SOC Target Operating Model to Drive Success
“Security and risk management leaders often struggle to convey the business value of their security operations centers to non security leaders, resulting in reduced investment, poor collaboration and eroding support…” — Access this Gartner SOC Operating Model report – courtesy of Swimlane.