Using Microsoft Security APIs for Incident Response - Part 1
Published Aug 19 2022 11:04 AM 14.9K Views
Microsoft

This blog is part one of a three-part series focused on facilitating programmatic data pulls from Microsoft APIs. 

 

Data collection and analysis is one of the most important aspects of a reactive Incident Response investigation or a proactive threat hunt exercise. Often one of the major contributing factors to the success of these investigations is not only how comprehensive your data collection is, but how fast the data is collected, what data is highlighted, and how consistent the data collection is across different investigations.

 

This blog series highlights ways you can leverage an Azure AD application registration and OAuth authentication to allow API access to alerts, incidents, and data in Microsoft 365 Defender and Microsoft Defender for Endpoint. This API access can enable programmatic Advanced Hunting queries and data pulls to improve hunting consistency, efficiency, speed, and completeness. While we will provide examples for Microsoft 365 Defender APIs, Microsoft Defender for Endpoint APIs, and Microsoft Graph API endpoints, the general guidance is suitable for any service that have APIs exposed.

 

Methodology overview

To facilitate programmatic data pulls from Microsoft APIs there are 5 main steps, which we will cover in this blog series:

  1. Part 1:
    • Step 1: Prepare an Azure AD OAuth app registration
      • Create a new OAuth App registration in the Azure AD tenant that hosts the data you need (“the App”)
      • Assign permissions to the App for the APIs you intend to access
      • Create a secret (easy) or configure a certificate (more secure) for the App
      • Store the key material securely leveraging Azure Key Vault
  2. Part 2:
    • Step 2: Get an access token from the appropriate authorization for the API resource you intend to access
    • Step 3: Provide the access token in a request to the API resource endpoint
  3. Part 3:
    • Step 4: Retrieve and parse the results
    • Step 5: Store the results for analysis

This blog will provide examples for leveraging PowerShell and C# code in Azure Functions. The same C# code can be used for a desktop app or a web API according to your need.

 

Why leverage an OAuth application?

Registering an app in Azure AD allows us to facilitate programmatic access to the Microsoft Security APIs, since Azure AD is the identity authority authorizing access to the tenant data. Using an OAuth application can also simplify cross-tenant authentication, in the case where a third-party Incident Response provider, like Microsoft Incident Response (formerly DART/CRSP), or another external party needs access to the tenant security information in a secure, programmatic manner.

 

What about streaming APIs?

Microsoft 365 Streaming API supports events streaming to an Azure Event Hub or an Azure Storage account. The Streaming API is often used in situations in which an organization would need to send all live, ongoing events to a location for continuous, permanent monitoring or consumption. For example, it can be used when an organization is integrating Microsoft 365 data into a Security Information and Event Management (SIEM) solution, such as Microsoft Sentinel.

 

However, streaming APIs may not be the best option for a targeted incident response investigation. The Streaming API does not allow for specific, custom Advanced Hunting queries to be executed nor does it allow for time targeting, both of which can be critical for finding the data or malicious events. Additionally, streaming all events will come with storage, Compute, and networking costs depending on your processing method. Finally, if the OAuth application is leveraged to provide access to a third-party or different organization for the purposes of an investigation, streaming all events may provide way more data than desired and may make it significantly more challenging to find “the needle in the haystack”.

 

Step 1 – Prepare an Azure AD OAuth app registration

The first thing that must be done is create an OAuth application that will be granted the permissions necessary to the desired resources. For the purposes of this blog series, we will focus on Azure AD.

 

To leverage an OAuth application there are a few things that must be done:

  1. Create a new OAuth App registration in the Azure AD tenant that hosts the data you need (“the App”)
  2. Assign permissions to the App for the APIs you intend to access
  3. Create a secret (easy) or configure a certificate (more secure) for the App
  4. Store the key material securely leveraging Azure Key Vault

1.1 Create a new OAuth app

The OAuth application can be created as either a single-tenant or multi-tenant application.  Which option you leverage will depend on your circumstances, but for the purposes of this content we will provide an example of a single-tenant application.  The single-tenant OAuth app is designed to be used just for a single Azure Active Directory tenant, whereas a multi-tenant OAuth app can be granted permission to multiple tenants.

 

The Azure account used in this section must have permission to manage applications in Azure AD. Any of the following Azure AD roles include the required permissions:

 

 

Here's a detailed set of steps to create a basic OAuth application to suit our needs:

 

  1. Navigate to Azure AD > App registrations in a web browser
  2. Click “New registration”
  3. Type in a name in “Name \ The user-facing display name for this application (this can be changed later).”
  4. Choose either “Accounts in this organizational directory only (<tenantName> only - Single tenant)” to create a single-tenant application or “Accounts in any organizational directory (Any Azure AD directory – Multitenant)” for “Supported account types” to create a multi-tenant application based upon your needs; here we are choosing to use a single-tenant application

    Choose a Supported account type - either single-tenant or multi-tenantChoose a Supported account type - either single-tenant or multi-tenant

     

  5. Click “Register” and you will be taken to the “Overview” page for your new OAuth application; make note of the “Application (client ID)” and “Directory (tenant) ID” values, you will need these later. Note: do not navigate away from this page yet, we will continue the configuration from here in the next section

1.2 Assign permissions

Depending on the intended purpose of the OAuth application you will be creating, for most API resources there are often either “Read” or “ReadWrite” permissions options. To adhere to the concept of least privilege we will configure the application with the minimum required permissions and choose read-only permissions.

 

For the sake of simplicity, you can configure permissions for multiple API endpoints in a single application. As you go through the steps below keep in mind that you should not configure permissions you do not intend to use

To complete these steps, you will need to grant tenant-wide admin consent which requires you to use an Azure AD user account with one of the following roles:

 

  • Global Administrator or Privileged Role Administrator, for granting consent for apps requesting any permission, for any API.
  • Cloud Application Administrator or Application Administrator, for granting consent for apps requesting any permission for any API, except Azure AD Graph or Microsoft Graph app roles (application permissions).
  • A custom directory role that includes the permission to grant permissions to applications, for the permissions required by the application.

Here's a detailed set of steps to configure the new OAuth application permissions to suit our needs:

 

  1. If you are still on the “Overview” page from when created the application, click “API permissions” on the left; otherwise, you will need to find your application Azure AD > App registrations.  If you are using the same account that created the application, then it should be listed under “Owned applications”.
  2. Click “Add a permission”
  3. Click “APIs my organization uses”
  4. Type in the name of the API you wish to use and then click on the full name when it appears in the list. 
    1. Microsoft Graph” is the name under which a variety of Microsoft Graph API permissions about Azure AD and other sources.  Some examples of Microsoft Graph permissions are “SecurityEvents.Read.All”, “IdentityRiskyUser.Read.All“, “IdentityRiskEvent.Read.All”, and “Directory.Read.all”.  The APIs exposed under this umbrella will continue to grow.
    2. Microsoft Threat Protection” is the name under which the Microsoft 365 Defender API permissions are listed.  Recommended permissions include “AdvancedHunting.Read.All” and “Incident.Read.All”.
    3. WindowsDefenderATP” is the name under which the Microsoft Defender for Endpoint API permissions are listed.  “AdvancedQuery.Read.All”, “Alert.Read.All”, “Machine.Read.All”, “SecurityConfiguration.Read.All”, “SecurityRecommendation.Read.All”, and “Vulnerability.Read.All” are recommended at a minimum, although there are a variety of other useful permissions as well.

Find the API you wish to assign permissions forFind the API you wish to assign permissions for

 

  1. Click “Application Permissions”
  2. Find the permission you want to assign in the list. You can filter the list by typing in the partial name and you can add multiple permissions at a time. This can always be updated later, although permissions added later will also need to have admin consent granted.

 

Find the permission you want to assignFind the permission you want to assign

 

  1. Click “Add permissions”
  2. Repeat steps 2-7 as needed to add all the required permissions

At this point you should have all the permissions you need assigned to the application. However, they are not quite effective yet – under “Status” they should all be showing as “Not granted for <tenant name>”. The next step is to remedy that by granting consent for the permissions for the tenant.

The permissions do not yet have admin consent for the tenantThe permissions do not yet have admin consent for the tenant

 

  1. Click “Grant admin consent for <tenant name>”, then click “Yes” when prompted for “Grant admin consent confirmation”
  2. Validate status is “Granted for <tenant name>”

The permissions should now be effective for the tenant. Below is an example screenshot that depicts an application with permissions successfully configured for the tenant and shows an example set of permissions that can be valuable for Incident Response purposes.

 

Example list of permissions for an app registrationExample list of permissions for an app registration

 

1.3 Configure Credentials

After the application is configured as described above, everything is ready for the application to be used except for setting the authentication mechanism – you can configure either certificate-based authentication or a client secret (text string). Certificates are more secure and should be used where possible. 

 

To complete the steps in this section you will need to use an Azure AD account that is configured as an owner of the application if you are not using an administrative Azure AD role.  These steps should also be ideally performed on a privileged access workstation to further reduce the risk of credential theft.

 

1.3.1 Certificates

If you choose to use a certificate for authenticating to the application then we recommend that these two steps, “Creating a certificate” and “Uploading the certificate”, are done at the same time and by the same person.  That will eliminate the need to transmit any key material via email or chat, because the certificate will only need to be stored in memory or temporarily on disk on a single system.  If you choose to use a secret for authentication instead of a certificate you can go directly to “1.3.2 Secrets”.

 

1.3.1.1 Creating a certificate

The creation of certificate should be done by the process recommended by your organization – For this blog we will demonstrate creating a certificate in an Azure Key Vault.

 

  1. Open a key vault where you want to create the certificate and navigate to the certificate blade.
  2. Click Generate/Import.
  3. Enter the details. Click the “Create” button.

Create_06_cert.jpg

 

  1. Wait for the certificate to be created and enabled.
  2. Navigate to the certificate and download it in either CER or PFX/PEM format.

Download the created certificateDownload the created certificate

 

 

1.3.1.2 Uploading the certificate

The certificate generated in the above step needs to be uploaded to the OAuth app created above.

  1. On the “Overview” page from when you created the application, click “Certificates & secrets” on the left.
  2. Click “Certificates” > “Upload certificate.”
  3. Upload the certificate downloaded in previous step.

 

Microsoft_DART_7-1660850020099.png

 

1.3.2 Secrets

An alternate authentication mechanism is through client secrets in the app. If you choose to use a secret for authenticating to the application then we recommend that these two steps, “Create a secret” and “Store the key material”, are done at the same time and by the same person. Doing this will eliminate the need to transmit any key material via email or chat, because the will only need to be stored in memory or temporarily on disk on a single system. If you choose to use a certificate for authentication instead of a secret, you will need to complete the previous section “1.3.1 Certificates”. NOTE: As mentioned above certificate-based authentication is the recommended approach as certificates are more secure and should be used where possible.

1.3.2.1 Create a secret

These steps will be used to generate a client secret in the OAuth application. 

  1. On the “Overview” page where the application was created, click “Certificates & secrets” on the left. Otherwise, locate your application on Azure AD > App registrations. If you are using the same account that created the application, it should be listed under “Owned applications”.
  2. Click “Client Secrets” > “New client secret”
  3. Enter a valid “Description” and set an appropriate “Expires” value based upon your needs. Note: the “Expires” value should not be any longer than the credential is needed for, but short enough to force a periodic rotation of the secret. Do not exceed the default value of 6 months unless necessary.
  4. Temporarily copy the “Value” of the secret that is generated.  This value is never displayed again, so if the value is not copied now this secret will not be able to be used. The value will be securely stored in the next step, “1.3.2.2 Store the key material”, using Azure Key Vault as an example.

 A new secret was createdA new secret was created

1.3.2.2 Store the key material

The key value generated in the previous step, in this case a secret, should be stored securely.  While it may be tempting to hard code the secret in a PowerShell script or C# Azure function, that is not secure and should be avoided. There are several methods securely store it. In this case, we will demonstrate using an Azure Key Vault. If you do not already have an Azure Key Vault created, read the quickstart article on creating an Azure Key Vault with the Azure CLI.

 

Here we will leverage the Azure CLI to store the secret in a key vault. To complete these steps, you will need to use an Azure AD account that has permissions to write secrets, such as “Key Vault Secrets Officer” or “Key Vault Certificate Office”. See the following article for additional details: Grant permission to applications to access an Azure key vault using Azure RBAC for additional details. These steps should also be ideally performed on a privileged access workstation to further reduce the risk of credential theft.

  1. Open PowerShell or a command prompt
  2. Execute the following to authenticate to Azure AD. A browser window will pop up and ask for you to sign in.
    az login
  3. Execute the following to store the secret into your Azure Key Vault.
    az keyvault secret set --vault-name "<keyVaultName>" --name "<nameYouWillUseToRetrieveTheSecretInTheFuture>" --value "<SecretValue>"

    1. "<keyVaultName>" – replace this with the name of your Azure Key Vault.
    2. "<nameYouWillUseToRetrieveTheSecretInTheFuture>" – replace this with whatever identifier you will use to retrieve the secret value in the future.  We recommend you include some combination of either the “Directory (tenant) ID” or “Application (client) ID” because that will uniquely identify what application the secret belongs to.  In the next steps we will always be using both the “Directory (tenant) ID” and “Application (client) ID” values in conjunction with the secret anyway, so needing those values to retrieve the secret is a logical solution.
    3. “<SecretValue>” – replace this with the secret value that was displayed in step 4 of the “Create a secret” section.
  4. The secret is now stored.  You can retrieve this in the future by executing the following command:
    az keyvault secret show --vault-name "<keyVaultName>" --name "<nameYouWillUseToRetrieveTheSecretInTheFuture>"

 

StoreSecret_01_SecretStored.jpg

Conclusion

In this first blog of a planned three-part series, we introduced a method by which an organization can leverage an Azure AD OAuth application to collect data as part of an Incident Response investigation. We discussed 5 broad steps to this methodology:

 

  1. Prepare an Azure AD OAuth app registration
  2. Get an access token from the appropriate authorization for the API resource you intend to access
  3. Provide the access token in a request to the API resource endpoint
  4. Retrieve and parse the results
  5. Store the results for analysis

The overall objective of this method is to enable programmatic access for data collection and analysis purposes, which will in turn improve collection speed and consistency. Once collection of Incident Response-pertinent data is automated and stored someplace where it can be easily accessed, the sky is the limit – rules can be written to highlight specific events, data can be correlated with external sources, and so on.

 

In addition to an overview of the methodology we also detailed “step 1” of the methodology, how to prepare an Azure AD OAuth application registration. Examples were provided for a few Microsoft security APIs, but the method is applicable to any API that is exposed and supports OAuth authentication.

 

In the next blog in the series, we plan to cover steps 2 and 3, how to get an access token for the API resource and how to provide that access token to the API resource. In the final blog in the series, we plan to cover steps 4 and 5, how to review and parse the results and storing the results for analysis.

3 Comments
Co-Authors
Version history
Last update:
‎May 22 2023 01:49 PM
Updated by: