readme has code samples

trigger is now http request and response if multiple options to bulk change status of incidents

kql
ids [array]
all
This commit is contained in:
swiftsolves-msft 2020-08-12 19:28:33 -04:00
Родитель 632bfc2ff8
Коммит 8fd8ed0f2a
2 изменённых файлов: 682 добавлений и 0 удалений

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

@ -0,0 +1,597 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata":{
"comments": "This Logic App will act as listner, you can pass json object to a HTTP Endpoint to use KQL query to discover Azure Sentinel Security Incidents through the SecurityIncident table you wish to bulk change on. It includes a method to slective update by array []. It also includes a method to bulk change all",
"author": "Priscila Viana, Nathan Swift"
},
"parameters": {
"PlaybookName": {
"defaultValue": "Update-BulkIncidents",
"type": "String"
},
"UserName": {
"defaultValue": "<username>@<domain>",
"type": "string"
},
"AzureSentinelSubscriptionID": {
"defaultValue": "<AZURE SENTINEL - SUBSCRIPTION ID>",
"type": "string"
},
"AzureSentinelResourceGroup": {
"defaultValue": "<AZURE SENTINEL - RESOURCEGROUP>",
"type": "string"
},
"AzureSentinelWorkspaceName": {
"defaultValue": "<AZURE SENTINEL - WORKSPACE NAME>",
"type": "string"
},
"AzureSentinelWorkspaceId": {
"defaultValue": "<AZURE SENTINEL - WORKSPACE ID>",
"type": "string"
}
},
"variables": {
"azuremonitorlogsConnectionName": "[concat('azuremonitorlogs-', parameters('PlaybookName'))]",
"azuresentinelConnectionName": "[concat('azuresentinel-', parameters('PlaybookName'))]"
},
"resources": [
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[variables('azuremonitorlogsConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"displayName": "[parameters('UserName')]",
"customParameterValues": {},
"api": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuremonitorlogs')]"
}
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[variables('AzureSentinelConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"displayName": "[parameters('UserName')]",
"customParameterValues": {},
"api": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]"
}
}
},
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2017-07-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"tags": {
"LogicAppsCategory": "security"
},
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('azuremonitorlogsConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('azuresentinelConnectionName'))]"
],
"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"
},
"SentinelResourceGroup": {
"defaultValue": "[parameters('AzureSentinelResourceGroup')]",
"type": "String"
},
"SentinelSubId": {
"defaultValue": "[parameters('AzureSentinelSubscriptionId')]",
"type": "String"
},
"SentinelWorkspaceId": {
"defaultValue": "[parameters('AzureSentinelWorkspaceId')]",
"type": "String"
},
"SentinelWorkspaceName": {
"defaultValue": "[parameters('AzureSentinelWorkspaceName')]",
"type": "String"
}
},
"triggers": {
"request": {
"type": "Request",
"kind": "Http",
"inputs": {
"method": "POST",
"schema": {
"properties": {
"bulkoperation": {
"anyOf": [
{
"not": {
"properties": {
"operationtype": {
"const": "kql"
}
},
"required": [
"operationtype"
]
}
},
{
"required": [
"operationquery"
]
}
],
"properties": {
"ids": {
"items": {
"type": "string"
},
"type": "array"
},
"operationquery": {
"type": "string"
},
"operationstatus": {
"type": "string"
},
"operationtype": {
"type": "string"
}
},
"type": "object"
}
},
"type": "object"
}
}
}
},
"actions": {
"Current_time": {
"runAfter": {},
"type": "Expression",
"kind": "CurrentTime",
"inputs": {}
},
"Response": {
"runAfter": {
"Current_time": [
"Succeeded"
]
},
"type": "Response",
"kind": "Http",
"inputs": {
"statusCode": 202
}
},
"Switch": {
"runAfter": {
"Response": [
"Succeeded"
]
},
"cases": {
"Case": {
"case": "kql",
"actions": {
"Condition": {
"actions": {
"Condition_3": {
"actions": {
"For_each_4": {
"foreach": "@body('SearchSecurityIncident')?['value']",
"actions": {
"Change_incident_status_4": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
"body": {
"CloseReasonText": "Bulk Close from KQL - via Playbook"
},
"host": {
"connection": {
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
}
},
"method": "put",
"path": "/Case/@{encodeURIComponent(parameters('SentinelSubId'))}/@{encodeURIComponent(parameters('SentinelWorkspaceId'))}/@{encodeURIComponent(parameters('SentinelResourceGroup'))}/@{encodeURIComponent('Incident')}/@{encodeURIComponent(items('For_each_4')?['IncidentNumber'])}/Status/@{encodeURIComponent('Closed')}"
}
}
},
"runAfter": {},
"type": "Foreach"
}
},
"runAfter": {
"SearchSecurityIncident": [
"Succeeded"
]
},
"else": {
"actions": {
"For_each": {
"foreach": "@body('SearchSecurityIncident')?['value']",
"actions": {
"Change_incident_status": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
}
},
"method": "put",
"path": "/Case/@{encodeURIComponent(parameters('SentinelSubId'))}/@{encodeURIComponent(parameters('SentinelWorkspaceId'))}/@{encodeURIComponent(parameters('SentinelResourceGroup'))}/@{encodeURIComponent('Incident')}/@{encodeURIComponent(items('For_each')?['IncidentNumber'])}/Status/@{encodeURIComponent(triggerBody()?['bulkoperation']?['operationstatus'])}"
}
}
},
"runAfter": {},
"type": "Foreach"
}
}
},
"expression": {
"and": [
{
"equals": [
"@triggerBody()?['bulkoperation']?['operationstatus']",
"Closed"
]
}
]
},
"type": "If"
},
"SearchSecurityIncident": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
"body": "@triggerBody()?['bulkoperation']?['operationquery']",
"host": {
"connection": {
"name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
}
},
"method": "post",
"path": "/queryData",
"queries": {
"resourcegroups": "@parameters('SentinelResourceGroup')",
"resourcename": "@parameters('SentinelWorkspaceName')",
"resourcetype": "Log Analytics Workspace",
"subscriptions": "@parameters('SentinelSubId')",
"timerange": "Set in query"
}
}
}
},
"runAfter": {},
"expression": {
"and": [
{
"not": {
"equals": [
"@triggerBody()?['bulkoperation']?['operationquery']",
"@null"
]
}
}
]
},
"type": "If"
}
}
},
"Case_2": {
"case": "ids",
"actions": {
"Condition_2": {
"actions": {
"Condition_4": {
"actions": {
"For_each_5": {
"foreach": "@triggerBody()?['bulkoperation']?['operationids']",
"actions": {
"Change_incident_status_5": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
"body": {
"CloseReasonText": "Bulk Close from IDs - via Playbook"
},
"host": {
"connection": {
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
}
},
"method": "put",
"path": "/Case/@{encodeURIComponent(parameters('SentinelSubId'))}/@{encodeURIComponent(parameters('SentinelWorkspaceId'))}/@{encodeURIComponent(parameters('SentinelResourceGroup'))}/@{encodeURIComponent('Incident')}/@{encodeURIComponent(items('For_each_5'))}/Status/@{encodeURIComponent('Closed')}"
}
}
},
"runAfter": {},
"type": "Foreach"
}
},
"runAfter": {},
"else": {
"actions": {
"For_each_2": {
"foreach": "@triggerBody()?['bulkoperation']?['operationids']",
"actions": {
"Change_incident_status_2": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
}
},
"method": "put",
"path": "/Case/@{encodeURIComponent(parameters('SentinelSubId'))}/@{encodeURIComponent(parameters('SentinelWorkspaceId'))}/@{encodeURIComponent(parameters('SentinelResourceGroup'))}/@{encodeURIComponent('Incident')}/@{encodeURIComponent(items('For_each_2'))}/Status/@{encodeURIComponent(triggerBody()?['bulkoperation']?['operationstatus'])}"
}
}
},
"runAfter": {},
"type": "Foreach"
}
}
},
"expression": {
"and": [
{
"equals": [
"@triggerBody()?['bulkoperation']?['operationstatus']",
"Closed"
]
}
]
},
"type": "If"
}
},
"runAfter": {},
"expression": {
"and": [
{
"not": {
"equals": [
"@triggerBody()?['bulkoperation']?['operationstatus']",
"@null"
]
}
}
]
},
"type": "If"
}
}
},
"Case_3": {
"case": "all",
"actions": {
"For_each_3": {
"foreach": "@body('Parse_JSON')?['value']",
"actions": {
"Change_incident_status_3": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
"body": {
"CloseReasonText": "Bulk Close All - via Playbook"
},
"host": {
"connection": {
"name": "@parameters('$connections')['azuresentinel']['connectionId']"
}
},
"method": "put",
"path": "/Case/@{encodeURIComponent(parameters('SentinelSubId'))}/@{encodeURIComponent(parameters('SentinelWorkspaceId'))}/@{encodeURIComponent(parameters('SentinelResourceGroup'))}/@{encodeURIComponent('Incident')}/@{encodeURIComponent(items('For_each_3')?['properties']?['incidentNumber'])}/Status/@{encodeURIComponent('Closed')}"
}
}
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Foreach"
},
"HTTP": {
"runAfter": {},
"type": "Http",
"inputs": {
"authentication": {
"audience": "https://management.azure.com/",
"type": "ManagedServiceIdentity"
},
"method": "GET",
"uri": "https://management.azure.com/subscriptions/@{parameters('SentinelSubId')}/resourceGroups/@{parameters('SentinelResourceGroup')}/providers/Microsoft.OperationalInsights/workspaces/@{parameters('SentinelWorkspaceName')}/providers/Microsoft.SecurityInsights/incidents/?api-version=2020-01-01"
}
},
"Parse_JSON": {
"runAfter": {
"HTTP": [
"Succeeded"
]
},
"type": "ParseJson",
"inputs": {
"content": "@body('HTTP')",
"schema": {
"properties": {
"nextLink": {
"type": "string"
},
"value": {
"items": {
"properties": {
"etag": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"properties": {
"properties": {
"additionalData": {
"properties": {
"alertProductNames": {
"items": {
"type": "string"
},
"type": "array"
},
"alertsCount": {
"type": "integer"
},
"bookmarksCount": {
"type": "integer"
},
"commentsCount": {
"type": "integer"
},
"tactics": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"createdTimeUtc": {
"type": "string"
},
"description": {
"type": "string"
},
"firstActivityTimeGenerated": {
"type": "string"
},
"firstActivityTimeUtc": {
"type": "string"
},
"incidentNumber": {
"type": "integer"
},
"incidentUrl": {
"type": "string"
},
"labels": {
"type": "array"
},
"lastActivityTimeGenerated": {
"type": "string"
},
"lastActivityTimeUtc": {
"type": "string"
},
"lastModifiedTimeUtc": {
"type": "string"
},
"owner": {
"properties": {
"assignedTo": {},
"email": {},
"objectId": {},
"userPrincipalName": {}
},
"type": "object"
},
"relatedAnalyticRuleIds": {
"items": {
"type": "string"
},
"type": "array"
},
"severity": {
"type": "string"
},
"status": {
"type": "string"
},
"title": {
"type": "string"
}
},
"type": "object"
},
"type": {
"type": "string"
}
},
"required": [
"id",
"name",
"etag",
"type",
"properties"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
}
}
}
}
},
"default": {
"actions": {
"ResponseInvalid": {
"runAfter": {},
"type": "Response",
"kind": "Http",
"inputs": {
"body": "operationtype must be kql or ids",
"statusCode": 400
}
}
}
},
"expression": "@triggerBody()?['bulkoperation']?['operationtype']",
"type": "Switch"
}
},
"outputs": {}
},
"parameters": {
"$connections": {
"value": {
"azuremonitorlogs": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('azuremonitorlogsConnectionName'))]",
"connectionName": "[variables('azuremonitorlogsConnectionName')]",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuremonitorlogs')]"
},
"azuresentinel": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('azuresentinelConnectionName'))]",
"connectionName": "[variables('azuresentinelConnectionName')]",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/azuresentinel')]"
}
}
}
}
}
}
]
}

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

@ -0,0 +1,85 @@
# Update-BulkIncidents
authors: Priscila Viana, Nathan Swift
This Logic App will act as listner, you can pass json object to a HTTP Endpoint to use KQL query to discover Azure Sentinel Security Incidents through the SecurityIncident table you wish to bulk change on. It includes a method to slective update by array []. It also includes a method to bulk change all
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FPlaybooks%2FUpdate-BulkIncidents%2Fazuredeploy.json" target="_blank">
<img src="https://aka.ms/deploytoazurebutton"/>
</a>
<a href="https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FPlaybooks%2FUpdate-BulkIncidents%2Fazuredeploy.json" target="_blank">
<img src="https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazuregov.png"/>
</a>
**Additional Post Install Notes:**
The Logic App requires the SecurityIncident Table preview | You need to change the KQL Query within the action to close selective Security incidents else it will bulk close all Incidents creates. There is a seprate path as well so if you want to bulk close all security incidents via API you can, need to turn on MSI and assign RBAC 'Reader' role to the Logic App at the RG of the Azure Sentinel Workspace.
**Usage Notes**
You can use Postman, PowerShell, or your favorite shell to send a JSON body to the Logic App Endpoint. Below are some code examples of usage.
At this time the Logic App can only bulk update the Status of Azure Sentinel Incidents.
```
<#
Object parameters accepted are:
operationtype - acceptable values are 'kql' or 'ids' or 'all' | 'kql' = you will pass a parameter 'operationquery' with the kql language, those results will be passed to bulk update incidents | 'ids' = use an array list in parameter 'operationids'
operationstatus - Closed, New, InProgress
operationkql - use a kql query to send results of Azure Sentinel Incidents to bulk update
operationids - using an array list of Azure Sentinel Incident Ids/case numbers to bulk update
See below for examples
#>
# Your URI from the Deployed LogicApp -
$uri = "https://prod-38.eastus.logic.azure.com:443/workflows/r794bb6/triggers/request/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Frequest%2Frun&sv=1.0&sig=b_7K3GTyGxvJ2V"
# Header should be JSON
$header = @{'Content-Type' = 'application/json'}
```
```
## Example 1 using the KQL query to bulk update incidents
$json = @"
{ "bulkoperation": {
"operationtype": "kql",
"operationquery": "SecurityIncident | where TimeGenerated >= ago(7d) | where Status == 'New'",
"operationstatus": "InProgress"
}
}
"@
```
```
## Example 2 using an array of incidents you want to update
$json = @"
{ "bulkoperation": {
"operationtype": "ids",
"operationids": [933, 934, 935, 935, 936],
"operationstatus": "New"
}
}
"@
```
```
## Example 3 Bulk update all incidents
$json = @"
{ "bulkoperation": {
"operationtype": "all",
"operationstatus": "Closed"
}
}
"@
```
```
# Invoke call to Logic App
Invoke-WebRequest -Uri $uri -Method Post -Body $json -Headers $header
```