New Logic watchlist add/update - timer based this logic app weekly connects to Defender for Cloud App and pulls risky users, some user context information, threat score, and direct user url.
This commit is contained in:
swiftsolves-msft 2022-04-13 00:41:42 -04:00
Родитель f2a6270b40
Коммит 9a52f7f541
2 изменённых файлов: 700 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,666 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata":{
"comments": "This Logic App will run weekly and create/update a Risky User watchlist with users from Microsoft Defender for cloud app with additional data for threatscore, information, and a url",
"author": "Jhonny Paulino, Nathan Swift"
},
"parameters": {
"PlaybookName": {
"defaultValue": "Update-RiskyUserWatchlist",
"type": "string"
},
"CloudAppAADServicePrincipal": {
"defaultValue": "Azure AD Service principal AppId",
"type": "securestring"
},
"KeyVaultName": {
"defaultValue": "kevaultname-to-create",
"type": "string"
},
"CloudAppAADServicePrincipalSecretKey": {
"defaultValue": "Azure AD Service principal key for keyvault secret",
"type": "securestring"
},
"MCASURL": {
"defaultValue": "https://xxxxxxx.yyy.portal.cloudappsecurity.com",
"type": "string"
},
"SubscriptionID": {
"defaultValue": "Your Subscription ID of Microsoft Sentinel",
"type": "string"
},
"WorkspaceID": {
"defaultValue": "Your Log analytics workspace ID of Microsoft Sentinel",
"type": "string"
},
"WorkspaceRGName": {
"defaultValue": "Your Log analytics workspace resource group of Microsoft Sentinel",
"type": "string"
},
"TenantID": {
"defaultValue": "Your Tenant ID of Defender for Cloud App",
"type": "string"
}
},
"variables": {
"secretName": "cloudapplist",
"azuresentinelConnectionName": "[concat('azuresentinel-', parameters('PlaybookName'))]",
"keyvaultConnectionName": "[concat('keyvault-', parameters('PlaybookName'))]"
},
"resources": [
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[variables('azuresentinelConnectionName')]",
"location": "[resourceGroup().location]",
"kind": "V1",
"properties": {
"displayName": "SentinelMSI",
"parameterValueType": "Alternative",
"customParameterValues": {},
"api": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]"
}
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[variables('keyvaultConnectionName')]",
"location": "[resourceGroup().location]",
"kind": "V1",
"properties": {
"displayName": "KeyvaultMSI",
"parameterValueType": "Alternative",
"customParameterValues": {},
"api": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/keyvault')]"
}
}
},
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2021-11-01-preview",
"name": "[parameters('KeyVaultName')]",
"location": "[resourceGroup().location]",
"properties": {
"sku": {
"family": "A",
"name": "Standard"
},
"tenantId": "[parameters('TenantID')]",
"accessPolicies": [],
"enabledForDeployment": false,
"enabledForDiskEncryption": false,
"enabledForTemplateDeployment": false,
"enableSoftDelete": true,
"softDeleteRetentionInDays": 90,
"enableRbacAuthorization": true,
"publicNetworkAccess": "Enabled"
}
},
{
"type": "Microsoft.KeyVault/vaults/secrets",
"apiVersion": "2021-11-01-preview",
"name": "[format('{0}/{1}', parameters('KeyVaultName'), variables('secretName'))]",
"properties": {
"value": "[parameters('CloudAppAADServicePrincipalSecretKey')]"
},
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]"
]
},
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2017-07-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"tags": {
"LogicAppsCategory": "security"
},
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('azuresentinelConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('keyvaultConnectionName'))]"
],
"identity": {
"type": "SystemAssigned"
},
"properties": {
"state": "Enabled",
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
},
"CloudAppAADServicePrincipal": {
"defaultValue": "[parameters('CloudAppAADServicePrincipal')]",
"type": "String"
},
"KeyVaultName": {
"defaultValue": "[parameters('KeyVaultName')]",
"type": "String"
},
"MCASURL": {
"defaultValue": "[parameters('MCASURL')]",
"type": "String"
},
"SubscriptionID": {
"defaultValue": "[parameters('SubscriptionID')]",
"type": "String"
},
"TenantID": {
"defaultValue": "[parameters('TenantID')]",
"type": "String"
},
"WorkspaceID": {
"defaultValue": "[parameters('WorkspaceID')]",
"type": "String"
},
"WorkspaceRGName": {
"defaultValue": "[parameters('WorkspaceRGName')]",
"type": "String"
}
},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Week",
"interval": 1,
"schedule": {
"hours": [
"6"
]
}
},
"evaluatedRecurrence": {
"frequency": "Week",
"interval": 1,
"schedule": {
"hours": [
"6"
]
}
},
"type": "Recurrence"
}
},
"actions": {
"Condition": {
"actions": {
"Watchlists_-_Create_a_new_watchlist_with_data": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
"body": {
"contentType": "text/csv",
"description": "Cloud App risky users with threatscore, information, and user url",
"displayName": "CloudAppRiskyUsers",
"itemsSearchKey": "emailAddress",
"numberOfLinesToSkip": 1,
"provider": "Microsoft",
"rawContent": "emailAddress, isAdmin, isExternal, threatScore, userCloudAppUrl\r\ntest, False, True, 0, https",
"source": "Local file",
"watchlistAlias": "cloudappriskyusers",
"watchlistId": "@{guid()}"
},
"host": {
"connection": {
"name": "@parameters('$connections')['azuresentinel_1']['connectionId']"
}
},
"method": "put",
"path": "/Watchlists/subscriptions/@{encodeURIComponent(parameters('SubscriptionID'))}/resourceGroups/@{encodeURIComponent(parameters('WorkspaceRGName'))}/workspaces/@{encodeURIComponent(parameters('WorkspaceID'))}/watchlists/@{encodeURIComponent('cloudappriskyusers')}"
}
}
},
"runAfter": {
"Watchlists_-_Get_a_watchlist_by_alias": [
"Succeeded",
"Failed"
]
},
"else": {
"actions": {
"Delay": {
"runAfter": {
"Watchlists_-_Delete_a_watchlist": [
"Succeeded"
]
},
"type": "Wait",
"inputs": {
"interval": {
"count": 2,
"unit": "Minute"
}
}
},
"Watchlists_-_Create_a_new_watchlist_with_data_2": {
"runAfter": {
"Delay": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": {
"contentType": "text/csv",
"description": "Cloud App risky users with threatscore, information, and user url",
"displayName": "CloudAppRiskyUsers",
"itemsSearchKey": "emailAddress",
"numberOfLinesToSkip": 1,
"provider": "Microsoft",
"rawContent": "emailAddress, isAdmin, isExternal, threatScore, userCloudAppUrl\r\ntest, False, True, 0, https",
"source": "Local file",
"watchlistAlias": "cloudappriskyusers",
"watchlistId": "@{guid()}"
},
"host": {
"connection": {
"name": "@parameters('$connections')['azuresentinel_1']['connectionId']"
}
},
"method": "put",
"path": "/Watchlists/subscriptions/@{encodeURIComponent(parameters('SubscriptionID'))}/resourceGroups/@{encodeURIComponent(parameters('WorkspaceRGName'))}/workspaces/@{encodeURIComponent(parameters('WorkspaceID'))}/watchlists/@{encodeURIComponent('cloudappriskyusers')}"
}
},
"Watchlists_-_Delete_a_watchlist": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azuresentinel_1']['connectionId']"
}
},
"method": "delete",
"path": "/Watchlists/subscriptions/@{encodeURIComponent(parameters('SubscriptionID'))}/resourceGroups/@{encodeURIComponent(parameters('WorkspaceRGName'))}/workspaces/@{encodeURIComponent(parameters('WorkspaceID'))}/watchlists/@{encodeURIComponent('cloudappriskyusers')}"
}
}
}
},
"expression": {
"and": [
{
"equals": [
"@body('Watchlists_-_Get_a_watchlist_by_alias')?['StatusCode']",
"NotFound"
]
}
]
},
"type": "If"
},
"Delay_2": {
"runAfter": {
"Filter_array": [
"Succeeded"
]
},
"type": "Wait",
"inputs": {
"interval": {
"count": 2,
"unit": "Minute"
}
}
},
"Filter_array": {
"runAfter": {
"HTTP": [
"Succeeded"
]
},
"type": "Query",
"inputs": {
"from": "@body('HTTP')?['data']",
"where": "@equals(item()?['type'], 2)"
}
},
"For_each": {
"foreach": "@body('Filter_array')",
"actions": {
"Compose": {
"runAfter": {
"Set_variable_3": [
"Succeeded"
]
},
"type": "Compose",
"inputs": {
"emailAddress": "@{body('Parse_JSON')?['email']}",
"isAdmin": "@{body('Parse_JSON')?['isAdmin']}",
"isExternal": "@{body('Parse_JSON')?['isExternal']}",
"threatScore": "@{body('Parse_JSON')?['threatScore']}",
"userCloudAppUrl": "@{variables('userCloudAppUrl')}"
}
},
"Parse_JSON": {
"runAfter": {},
"type": "ParseJson",
"inputs": {
"content": "@items('For_each')",
"schema": {
"properties": {
"_id": {
"type": "string"
},
"actions": {
"type": "array"
},
"appData": {
"properties": {
"appId": {
"type": "integer"
},
"instance": {
"type": "integer"
},
"name": {
"type": "string"
},
"saas": {
"type": "integer"
}
},
"type": "object"
},
"displayName": {
"type": "string"
},
"domain": {},
"email": {},
"id": {
"type": "string"
},
"idType": {
"type": "integer"
},
"identifiers": {
"type": "array"
},
"ii": {
"type": "string"
},
"isAdmin": {
"type": "boolean"
},
"isExternal": {
"type": "boolean"
},
"isFake": {
"type": "boolean"
},
"organization": {},
"role": {},
"scoreTrends": {},
"sctime": {},
"sid": {},
"status": {},
"subApps": {
"items": {
"properties": {
"appId": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"appId",
"name"
],
"type": "object"
},
"type": "array"
},
"threatScore": {},
"type": {
"type": "integer"
},
"userGroups": {
"items": {
"properties": {
"_id": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"usersCount": {
"type": "integer"
}
},
"required": [
"_id",
"id",
"name",
"description",
"usersCount"
],
"type": "object"
},
"type": "array"
},
"username": {
"type": "string"
}
},
"type": "object"
}
}
},
"Set_variable": {
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "SetVariable",
"inputs": {
"name": "userCloudAppB64Input",
"value": "{\"id\":\"@{body('Parse_JSON')?['id']}\",\"saas\":@{body('Parse_JSON')?['appData']?['saas']},\"inst\":@{body('Parse_JSON')?['appData']?['instance']}}"
}
},
"Set_variable_2": {
"runAfter": {
"Set_variable": [
"Succeeded"
]
},
"type": "SetVariable",
"inputs": {
"name": "userCloudAppB64Output",
"value": "@{base64(variables('userCloudAppB64Input'))}"
}
},
"Set_variable_3": {
"runAfter": {
"Set_variable_2": [
"Succeeded"
]
},
"type": "SetVariable",
"inputs": {
"name": "userCloudAppUrl",
"value": "@{parameters('MCASURL')}/#/users/@{variables('userCloudAppB64Output')}"
}
},
"Watchlists_-_Add_a_new_watchlist_item": {
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": "@outputs('Compose')",
"host": {
"connection": {
"name": "@parameters('$connections')['azuresentinel_1']['connectionId']"
}
},
"method": "put",
"path": "/Watchlists/subscriptions/@{encodeURIComponent(parameters('SubscriptionID'))}/resourceGroups/@{encodeURIComponent(parameters('WorkspaceRGName'))}/workspaces/@{encodeURIComponent(parameters('WorkspaceID'))}/watchlists/@{encodeURIComponent('cloudappriskyusers')}/watchlistItem"
}
}
},
"runAfter": {
"Delay_2": [
"Succeeded"
]
},
"type": "Foreach",
"runtimeConfiguration": {
"concurrency": {
"repetitions": 1
}
}
},
"Get_secret": {
"runAfter": {
"Initialize_variable_3": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['keyvault_1']['connectionId']"
}
},
"method": "get",
"path": "/secrets/@{encodeURIComponent('cloudapplist')}/value"
}
},
"HTTP": {
"runAfter": {
"Get_secret": [
"Succeeded"
]
},
"type": "Http",
"inputs": {
"authentication": {
"audience": "05a65629-4c1b-48c1-a78b-804c4abdd4af",
"clientId": "@parameters('CloudAppAADServicePrincipal')",
"secret": "@body('Get_secret')?['value']",
"tenant": "@parameters('TenantID')",
"type": "ActiveDirectoryOAuth"
},
"headers": {
"Content-type ": "application-json"
},
"method": "GET",
"uri": "@{parameters('MCASURL')}/api/v1/entities/"
}
},
"Initialize_variable": {
"runAfter": {
"Condition": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "userCloudAppB64Input",
"type": "string",
"value": "@{null}"
}
]
}
},
"Initialize_variable_2": {
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "userCloudAppB64Output",
"type": "string",
"value": "@{null}"
}
]
}
},
"Initialize_variable_3": {
"runAfter": {
"Initialize_variable_2": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "userCloudAppUrl",
"type": "string",
"value": "@{null}"
}
]
}
},
"Watchlists_-_Get_a_watchlist_by_alias": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azuresentinel_1']['connectionId']"
}
},
"method": "get",
"path": "/Watchlists/subscriptions/@{encodeURIComponent(parameters('SubscriptionID'))}/resourceGroups/@{encodeURIComponent(parameters('WorkspaceRGName'))}/workspaces/@{encodeURIComponent(parameters('WorkspaceID'))}/watchlists/@{encodeURIComponent('cloudappriskyusers')}"
}
}
},
"outputs": {}
},
"parameters": {
"$connections": {
"value": {
"azuresentinel_1": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('azuresentinelConnectionName'))]",
"connectionName": "[variables('azuresentinelConnectionName')]",
"connectionProperties": {
"authentication": {
"type": "ManagedServiceIdentity"
}
},
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]"
},
"keyvault_1": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('keyvaultConnectionName'))]",
"connectionName": "[variables('keyvaultConnectionName')]",
"connectionProperties": {
"authentication": {
"type": "ManagedServiceIdentity"
}
},
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/keyvault')]"
}
}
}
}
}
}
]
}

Просмотреть файл

@ -0,0 +1,34 @@
# Update-RiskyUserWatchlist
Author: Jhonny Paulino, Nathan Swift
This Logic App will run weekly and create/update a Risky User watchlist with users from Microsoft Defender for cloud app with additional data for threatscore, information, and a url.
**Prerequisites for the solution**:
1. You must create a Azure AD Service Principal, record the AppId, tenantID, and create a secrets and record the secret. This service principal will be used in the solution to query the Defender for Cloud App /entities rest api
2. Be sure to add the following 'Microsoft Cloud App Security' Application Permissions to the created service principal discovery.read, investigation.read . Also be sure to grant admin consent to those application permissions.
**Deploying the solution**:
1. Add/Update the missing parameters in the ARM template deployment
The Watchlist name will be also the alias name that you will use to query the data, for example
_GetWatchlist(**'cloudappriskyusers'**)
[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FWatchlists%2FUpdate-RiskyUserWatchlist%2Fazuredeploy.json)
**Post Deployment**:
1. Manually check/update the Key Vault secret called 'cloudapplist' with the Azure AD Service Principal key
The Logic App as a Managed Service Indetity - MSI needs to have the following RBAC Roles:
2. Key Vault Secrets User on the deployed Key Vault resource.
This is required for obtaining the AAD SPN secret key encrypted through Logic App.
3. Azure Sentinel Contributor Role on the Azure Sentinel Resource Group.
This is required for deleting and updating the watchlist in Microsoft Sentinel.