Create an Azure Role Assignment Watchlist in Azure Sentinel

Watchlist in Azure Sentinel allows you to build your own data from external data sources for correlation with analytics or hunting rules in your Azure Sentinel environment.

In this article, what we are going to do is explore Azure Sentinel Watchlist REST API and then create Azure Role Assignment watchlist.

TL;DR: You can skip this article and use this script to create a watchlist which stores Azure role assignments in your environment.

The API (2021-03-01-preview) used in this article is still in preview. Use at your own risk.

Use Case

Privilege escalation is one of the most common techniques threat actor use in cloud environment. Part of your monitoring & hunting work, you may want to correlate with Azure Role Assignment in Azure to find out if there are any suspicious role assignment activities in your environment.

In the illustration above, the threat actor harvests credentials in non-production environment. Once he successfully gains a credential of an account that is granted Owner role he may have the authorization to add the compromised to the same subscription or another subscription to laterally move across all subscriptions in the environment.

In this scenario, as a SecOps analyst, you need to monitor role assignments in your Azure environment. There are several approaches. One approach is to write a simple script to export role assignments and store the report in a storage account. Another approach is to build an Azure automation runbook to retrieve role assignments and write to Log Analytics workspace using HTTP Data Collector API. In this article, Watchlist is chosen as a data store for tenant’s role assignments.

Azure Sentinel Watchlist REST API

To create a new Azure Sentinel watchlist, use the following API:

$uri = "https://management.azure.com" + $workspaceId `
                                      + "/providers/Microsoft.SecurityInsights/watchlists/" `
                                      + "$($WatchListAlias)" `
                                      + "?api-version=2021-04-01"
  • WorkspaceId: the Id of the Log Analytics workspace that Azure Sentinel connects to.
  • WatchListAlias:  the alias of the watchlist. It will be used to query data.

This API accepts PUT method. Every PUT request needs a request body. Azure Sentinel Watchlist API requires the following request body to create a new watchlist.

{
  "properties": {
    "displayName": "role_assignment",
    "source": "Local file",
    "provider": "Microsoft",
    "numberOfLinesToSkip": "1",
    "rawContent": "raw content of CSV data",
    "contentType": "text/csv"
  }
}
  • displayName: the display name of the watchlist
  • source: the source of the watchlist. It can be a local file if you pass CSV data directly in rawContent: the source of the watchlist. It can be a local file path if you want to upload a CSV file and let Azure handles the rest.
  • provider: the provider of the watchlist. Use Microsoft if you don’t know any ‘fancy’ name.
  • numberOfLinesToSkip: the number of lines before row with headings.
  • rawContent: if you don’t specify a file path in source field you need to pass raw CSV data to this field.
  • contentType: the content type of the raw content

Below is the output of succeeded creation:

id         : /subscriptions/67d6179d-a99d-4ccd-8c56-4d3ff2e13349/resourceGroups/azsec-corporate-rg/providers/Microsoft.Operatio
             /workspaces/azsec-shared-workspace/providers/Microsoft.SecurityInsights/Watchlists/azsec_role_assignment
name       : azsec_role_assignment
etag       : "3e02f7a0-0000-0100-0000-60ed16e50000"
type       : Microsoft.SecurityInsights/Watchlists
systemData : @{createdAt=2021-07-13T04:30:29.2097568Z; createdBy=ad@azsec.net; createdByType=User;
             lastModifiedAt=2021-07-13T04:30:29.2097568Z; lastModifiedBy=ad@azsec.net; lastModifiedByType=User}
properties : @{watchlistId=493fddb2-586d-4175-8b6d-4c4c9f18e47e; displayName=azsec_role_assignment; provider=Microsoft; source=
             file; itemsSearchKey=RoleDefinitionName; created=2021-07-13T04:30:29.2097568+00:00;
             updated=2021-07-13T04:30:29.2097568+00:00; createdBy=; updatedBy=; watchlistType=watchlist; 
             watchlistAlias=azsec_role_assignment; isDeleted=False; labels=System.Object[];
             tenantId=03987603-0fc0-4103-bd94-cdffbefb2226; numberOfLinesToSkip=0; uploadStatus=New}

Once the watchlist is successfully created, wait for data ingestion and then perform a query to test:

let watchlist = (_GetWatchlist('azsec_role_assignment') | project SignInName);
AuditLogs
| where TargetResources[0].userPrincipalName == 'audrey_dickens@azsec.net' 
| where TargetResources[0].userPrincipalName in (watchlist)
| project TimeGenerated, OperationName, InitiatedBy, AdditionalDetails

The query is used to find the specified name in both Role Assignment watch list and Azure AD AuditLogs to see related events.

Using file path

The sample script reads role assignment data and pass it directly to Azue Sentinel watchlist API.  You can specify a file in your local computer or a virtual machine (as long as it is accessible such as Hybrid Worker) or a remote file. When using file, your request body doesn’t need rawContent and contentType fields. If contentType exists, rawContent must not be empty. Otherwise, you will receive “There is an issue with the payload: the payload rawContent is empty!” error message.

$path = "C:\Workspace\azsec_role_assignment_2021_07_12_213000.csv"
$properties = @{
    "displayName"         = "$WatchListAlias";
    "provider"            = "Microsoft";
    "numberOfLinesToSkip" = "0";
    "itemsSearchKey"      = "RoleDefinitionName";
    "source"              = "$path";
}

Automation

You can create an automation runbook and modify the sample script a bit to log into Azure with service principal’s credential or a managed identity.

This entry was posted in Security Automation, Security Operation and tagged , . Bookmark the permalink.

4 Responses to Create an Azure Role Assignment Watchlist in Azure Sentinel

  1. james says:

    Hello Brother im trying to upload csv file but what table or row need data to input?

    • azsec says:

      Hi James,

      It is just a normal CSV. Run my script and find the CSV. Open it with Notepad you can see the format.

      Watchlist is just a feature that allows you to store dataset (something that Azure doesn’t support by default) that you would like to correlate. In this article, I want to extract Azure Role Assignment and use it as an external dataset.

  2. Pingback: Notes on Azure Backup Soft-delete feature in a cybersecurity context - Microsoft Azure Security Randomness

  3. james says:

    I see awesome bro thank you

Leave a Reply

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