Merge pull request #10312 from recordedfuture/RecordedFutureIdentityUpdate

RecordedFutureIdentity solution update
This commit is contained in:
v-prasadboke 2024-07-04 17:53:45 +05:30 коммит произвёл GitHub
Родитель f1c1e5780d 46fa648ac7
Коммит cbdc8ea272
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
18 изменённых файлов: 4526 добавлений и 3116 удалений

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

@ -2,17 +2,18 @@
"Name": "Recorded Future Identity",
"Author": "Recorded Future Premier Integrations - support@recordedfuture.com",
"Logo": "<img src=\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Logos/RecordedFuture.svg\" width=\"75px\" height=\"75px\">",
"Description": "[Recorded Future](https://www.recordedfuture.com/) Identity Intelligence enables security and IT teams to detect identity compromises, for both employees and customers. To do this, Recorded Future automates the collection, analysis, and production of identity intelligence from a vast range of sources. Organizations can incorporate identity intelligence into automated workflows that regularly monitor for compromised credentials and take immediate action with applications such as Azure Active Directory and Microsoft Sentinel.\nThere are many ways organizations can utilize Recorded Future Identity Intelligence; the playbooks in this Solution are just a quick introduction to some of those ways. In particular, these playbooks include several actions that can be coordinated, or used separately. They include:\n1. searches for compromised workforce or external customer users\n2. looking up existing users and saving the compromised user data to a Log file\n3. confirming high risk Azure Active Directory (AAD) users\n4. adding a compromised user to an AAD security group\n\nFor more information, see the [Documentation for this Solution](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Recorded%20Future%20Identity/Playbooks).\n\nThe playbooks have internal dependencies where you have to install: \n- RecordedFutureIdentity-add-AAD-security-group-user \n- RecordedFutureIdentity-confirm-AAD-risky-user \n- RecordedFutureIdentity-lookup-and-save-user \n\nBefore: \n- RecordedFutureIdentity-search-workforce-user \n- RecordedFutureIdentity-search-external-user.",
"Description": "[Recorded Future](https://www.recordedfuture.com/) Identity Intelligence enables security and IT teams to detect identity compromises, for both employees and customers. To do this, Recorded Future automates the collection, analysis, and production of identity intelligence from a vast range of sources. Organizations can incorporate identity intelligence into automated workflows that regularly monitor for compromised credentials and take immediate action with applications such as Azure Active Directory and Microsoft Sentinel.\nThere are many ways organizations can utilize Recorded Future Identity Intelligence; the playbooks in this Solution are just a quick introduction to some of those ways. In particular, these playbooks include several actions that can be coordinated, or used separately. They include:\n1. searches for compromised workforce or external customer users\n2. looking up existing users and saving the compromised user data to a Log file\n3. confirming high risk Azure Active Directory (AAD) users\n4. adding a compromised user to an AAD security group\n\nFor more information, see the [Documentation for this Solution](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Recorded%20Future%20Identity/Playbooks).\n\nThe playbooks have internal dependencies where you have to install: \n- RecordedFutureIdentity-add-EntraID-security-group-user \n- RecordedFutureIdentity-confirm-EntraID-risky-user \n- RecordedFutureIdentity-lookup-and-save-user \n\nBefore: \n- RecordedFutureIdentity-search-workforce-user \n- RecordedFutureIdentity-search-external-user.\n\nThis solution depends on underlying Microsoft technologies. Some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:\n* [Log Analytics](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/workspace-design)\n* [Logic apps](https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-pricing)\n",
"PlaybooksBladeDescription": "This solution will install playbooks that import users with leaked credentials from Recorded Future and set them as RiskyUsers in Azure Active Directory.",
"Playbooks": [
"/Playbooks/RecordedFutureIdentity-add-AAD-security-group-user.json",
"/Playbooks/RecordedFutureIdentity-confirm-AAD-risky-user.json",
"/Playbooks/RecordedFutureIdentity-lookup-and-save-user.json",
"/Playbooks/RecordedFutureIdentity-search-workforce-user.json",
"/Playbooks/RecordedFutureIdentity-search-external-user.json"
"/Playbooks/RFI-CustomConnector-0-1-0/azuredeploy.json",
"/Playbooks/RFI-add-EntraID-security-group-user/azuredeploy.json",
"/Playbooks/RFI-confirm-EntraID-risky-user/azuredeploy.json",
"/Playbooks/RFI-lookup-and-save-user/azuredeploy.json",
"/Playbooks/RFI-search-workforce-user/azuredeploy.json",
"/Playbooks/RFI-search-external-user/azuredeploy.json"
],
"BasePath": "c:\\github\\Azure-Sentinel\\Solutions\\Recorded Future Identity\\",
"Version": "2.0.0",
"BasePath": "D:\\Azure-Sentinel\\Solutions\\Recorded Future Identity\\",
"Version": "3.0.0",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"Is1PConnector": false

Двоичные данные
Solutions/Recorded Future Identity/Package/3.0.0.zip Normal file

Двоичный файл не отображается.

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

@ -6,7 +6,7 @@
"config": {
"isWizard": false,
"basics": {
"description": "<img src=\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Logos/RecordedFuture.svg\" width=\"75px\" height=\"75px\">\n\n**Note:** _There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing._\n\n[Recorded Future](https://www.recordedfuture.com/) Identity Intelligence enables security and IT teams to detect identity compromises, for both employees and customers. To do this, Recorded Future automates the collection, analysis, and production of identity intelligence from a vast range of sources. Organizations can incorporate identity intelligence into automated workflows that regularly monitor for compromised credentials and take immediate action with applications such as Azure Active Directory and Microsoft Sentinel.\nThere are many ways organizations can utilize Recorded Future Identity Intelligence; the playbooks in this Solution are just a quick introduction to some of those ways. In particular, these playbooks include several actions that can be coordinated, or used separately. They include:\n1. searches for compromised workforce or external customer users\n2. looking up existing users and saving the compromised user data to a Log file\n3. confirming high risk Azure Active Directory (AAD) users\n4. adding a compromised user to an AAD security group\n\nFor more information, see the [Documentation for this Solution](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Recorded%20Future%20Identity/Playbooks).\n\nThe playbooks have internal dependencies where you have to install: \n- RecordedFutureIdentity-add-AAD-security-group-user \n- RecordedFutureIdentity-confirm-AAD-risky-user \n- RecordedFutureIdentity-lookup-and-save-user \n\nBefore: \n- RecordedFutureIdentity-search-workforce-user \n- RecordedFutureIdentity-search-external-user.\n\n**Playbooks:** 5\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
"description": "<img src=\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Logos/RecordedFuture.svg\" width=\"75px\" height=\"75px\">\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Recorded%20Future%20Identity/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\n[Recorded Future](https://www.recordedfuture.com/) Identity Intelligence enables security and IT teams to detect identity compromises, for both employees and customers. To do this, Recorded Future automates the collection, analysis, and production of identity intelligence from a vast range of sources. Organizations can incorporate identity intelligence into automated workflows that regularly monitor for compromised credentials and take immediate action with applications such as Azure Active Directory and Microsoft Sentinel.\nThere are many ways organizations can utilize Recorded Future Identity Intelligence; the playbooks in this Solution are just a quick introduction to some of those ways. In particular, these playbooks include several actions that can be coordinated, or used separately. They include:\n1. searches for compromised workforce or external customer users\n2. looking up existing users and saving the compromised user data to a Log file\n3. confirming high risk Azure Active Directory (AAD) users\n4. adding a compromised user to an AAD security group\n\nFor more information, see the [Documentation for this Solution](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Recorded%20Future%20Identity/Playbooks).\n\nThe playbooks have internal dependencies where you have to install: \n- RecordedFutureIdentity-add-EntraID-security-group-user \n- RecordedFutureIdentity-confirm-EntraID-risky-user \n- RecordedFutureIdentity-lookup-and-save-user \n\nBefore: \n- RecordedFutureIdentity-search-workforce-user \n- RecordedFutureIdentity-search-external-user.\n\nThis solution depends on underlying Microsoft technologies. Some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:\n* [Log Analytics](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/workspace-design)\n* [Logic apps](https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-pricing)\n\n\n**Custom Azure Logic Apps Connectors:** 1, **Playbooks:** 5\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
"subscription": {
"resourceProviders": [
"Microsoft.OperationsManagement/solutions",

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -0,0 +1,24 @@
{
"location": {
"type": "string",
"minLength": 1,
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace"
}
},
"workspace-location": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]"
}
},
"workspace": {
"defaultValue": "",
"type": "string",
"metadata": {
"description": "Workspace name for Log Analytics where Microsoft Sentinel is setup"
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1,27 +1,39 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"title": "RecordedFutureIdentity-add-AAD-security-group-user",
"description": "This playbook adds a compromised user to an AAD security group. Triage and remediation should be handled in follow up playbooks or actions.",
"lastUpdateTime": "2022-09-09T00:00:00.000Z",
"contentVersion": "1.1.0.0",
"metadata": {
"title": "RFI-add-EntraID-security-group-user",
"description": "This playbook adds a compromised user to an EntraID security group. Triage and remediation should be handled in follow up playbooks or actions.",
"lastUpdateTime": "2024-06-11T14:25:00.000Z",
"entities": [],
"tags": ["Identity protection"],
"support": {
"tier": "developer"
"tier": "Partner"
},
"author": {
"name": "Dmytro Branitskyi, Recorded Future (support@recordedfuture.com)"
}
"name": "Recorded Future"
},
"releaseNotes": [
{
"version": "1.0",
"title": "Initial version",
"notes": [ "Initial version" ]
},
{
"version": "1.1",
"title": "Updates",
"notes": [ "Solution update. Change PlaybookName prefix to RFI." ]
}
]
},
"parameters": {
"PlaybookName": {
"defaultValue": "RecordedFutureIdentity-add-AAD-security-group-user",
"defaultValue": "RFI-add-EntraID-security-group-user",
"type": "string"
}
},
"variables": {
"AzureADConnectionName": "[concat('azuread-', parameters('PlaybookName'))]"
"EntraIDConnectionName": "[concat('EntraID-', parameters('PlaybookName'))]"
},
"resources": [
{
@ -29,8 +41,11 @@
"apiVersion": "2019-05-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"tags": {
"hidden-SentinelTemplateVersion": "1.1"
},
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('AzureADConnectionName'))]"
"[resourceId('Microsoft.Web/connections', variables('EntraIDConnectionName'))]"
],
"properties": {
"state": "Enabled",
@ -359,8 +374,8 @@
"$connections": {
"value": {
"azuread": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureADConnectionName'))]",
"connectionName": "[variables('AzureADConnectionName')]",
"connectionId": "[resourceId('Microsoft.Web/connections', variables('EntraIDConnectionName'))]",
"connectionName": "[variables('EntraIDConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuread')]"
}
}
@ -371,13 +386,13 @@
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('AzureADConnectionName')]",
"name": "[variables('EntraIDConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuread')]"
},
"displayName": "[variables('AzureADConnectionName')]"
"displayName": "[variables('EntraIDConnectionName')]"
}
}
]

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

@ -1,28 +1,40 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"title": "RecordedFutureIdentity-confirm-AAD-risky-user",
"description": "This playbook confirms compromise of users deemed 'high risk' by AAD.",
"lastUpdateTime": "2022-09-09T00:00:00.000Z",
"contentVersion": "1.1.0.0",
"metadata": {
"title": "RFI-confirm-EntraID-risky-user",
"description": "This playbook confirms compromise of users deemed 'high risk' by EntraID.",
"lastUpdateTime": "2024-06-11T14:25:00.000Z",
"entities": [],
"tags": ["Identity protection"],
"support": {
"tier": "developer"
"tier": "Partner"
},
"author": {
"name": "Dmytro Branitskyi, Recorded Future (support@recordedfuture.com)"
}
"name": "Recorded Future"
},
"releaseNotes": [
{
"version": "1.0",
"title": "Initial version",
"notes": [ "Initial version" ]
},
{
"version": "1.1",
"title": "Updates",
"notes": [ "Solution update. Change PlaybookName prefix to RFI." ]
}
]
},
"parameters": {
"PlaybookName": {
"defaultValue": "RecordedFutureIdentity-confirm-AAD-risky-user",
"defaultValue": "RFI-confirm-EntraID-risky-user",
"type": "string"
}
},
"variables": {
"AzureADConnectionName": "[concat('azuread-', parameters('PlaybookName'))]",
"AzureADIdentityProtectionConnectionName": "[concat('azureadip-', parameters('PlaybookName'))]"
"EntraIDConnectionName": "[concat('EntraID-', parameters('PlaybookName'))]",
"EntraIDIdentityProtectionConnectionName": "[concat('EntraIDip-', parameters('PlaybookName'))]"
},
"resources": [
{
@ -30,9 +42,12 @@
"apiVersion": "2019-05-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"tags": {
"hidden-SentinelTemplateVersion": "1.1"
},
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('AzureADConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('AzureADIdentityProtectionConnectionName'))]"
"[resourceId('Microsoft.Web/connections', variables('EntraIDConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('EntraIDIdentityProtectionConnectionName'))]"
],
"properties": {
"state": "Enabled",
@ -375,13 +390,13 @@
"$connections": {
"value": {
"azuread": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureADConnectionName'))]",
"connectionName": "[variables('AzureADConnectionName')]",
"connectionId": "[resourceId('Microsoft.Web/connections', variables('EntraIDConnectionName'))]",
"connectionName": "[variables('EntraIDConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuread')]"
},
"azureadip": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureADIdentityProtectionConnectionName'))]",
"connectionName": "[variables('AzureADIdentityProtectionConnectionName')]",
"connectionId": "[resourceId('Microsoft.Web/connections', variables('EntraIDIdentityProtectionConnectionName'))]",
"connectionName": "[variables('EntraIDIdentityProtectionConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureadip')]"
}
}
@ -392,25 +407,25 @@
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('AzureADConnectionName')]",
"name": "[variables('EntraIDConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuread')]"
},
"displayName": "[variables('AzureADConnectionName')]"
"displayName": "[variables('EntraIDConnectionName')]"
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('AzureADIdentityProtectionConnectionName')]",
"name": "[variables('EntraIDIdentityProtectionConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureadip')]"
},
"displayName": "[variables('AzureADIdentityProtectionConnectionName')]"
"displayName": "[variables('EntraIDIdentityProtectionConnectionName')]"
}
}
]

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

@ -1,40 +1,65 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"title": "RecordedFutureIdentity-lookup-and-save-user",
"contentVersion": "1.2.0.0",
"metadata": {
"title": "RFI-lookup-and-save-user",
"description": "This playbook gets compromise identity details from Recorded Future Identity Intelligence and saves the data for further review and analysis.",
"lastUpdateTime": "2022-09-09T00:00:00.000Z",
"entities": [],
"tags": ["Identity protection"],
"prerequisites": [
"The custom connector RFI-CustomConnector-0-1-0 have to be deployed under the same subscription.",
"To use the Recorded Future for Azure connector, you will need a valid API token from Recorded Future as described in the [documentation](https://learn.microsoft.com/en-us/connectors/recordedfuturev2/#how-to-get-credentials)"
],
"postDeployment": [
"After deployment, open the playbook to configure all connections and press save."
],
"prerequisitesDeployTemplateFile": "../RFI-CustomConnector-0-1-0/azuredeploy.json",
"lastUpdateTime": "2024-06-11T14:25:00.000Z",
"entities": [],
"tags": [ "Identity protection" ],
"support": {
"tier": "developer"
"tier": "Partner"
},
"author": {
"name": "Dmytro Branitskyi, Recorded Future (support@recordedfuture.com)"
}
"name": "Recorded Future"
},
"releaseNotes": [
{
"version": "1.0",
"title": "Initial version",
"notes": [ "Initial version" ]
},
{
"version": "1.1",
"title": "Updates",
"notes": [ "Solution update. Change PlaybookName prefix to RFI." ]
},
{
"version": "1.2",
"title": "Identity endpoint update",
"notes": [ "Updated lookup envpoint to new version. Structure of data in the lookup_results_log_analytics_custom_log_name " ]
}
]
},
"parameters": {
"PlaybookName": {
"defaultValue": "RecordedFutureIdentity-lookup-and-save-user",
"PlaybookName": {
"defaultValue": "RFI-lookup-and-save-user",
"type": "string"
},
"IdentityCustomConnectorName": {
"defaultValue": "RFI-CustomConnector-0-1-0",
"type": "string",
"metadata": {
"description": "Name of the logic app connector which performs Recorded Future Communication. Normaly this dont change from RFI-CustomConnector-0-1-0"
}
}
},
"variables": {
"LogAnalyticsDataCollectorConnectionName": "[concat('azureloganalyticsdatacollector-', parameters('PlaybookName'))]",
"RecordedFutureIdentityConnectionName": "[concat('recordedfutureidenti-', parameters('PlaybookName'))]"
"IdentityconnectorupdateConnectionName": "RFI-CustomConnector-0-1-0",
"AzureloganalyticsdatacollectorConnectionName": "[concat('Azureloganalyticsdatacollector-', parameters('PlaybookName'))]"
},
"resources": [
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2019-05-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('LogAnalyticsDataCollectorConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('RecordedFutureIdentityConnectionName'))]"
],
"properties": {
"provisioningState": "Succeeded",
"state": "Enabled",
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
@ -49,7 +74,7 @@
"type": "String"
},
"lookup_lookback_days_default": {
"defaultValue": -365,
"defaultValue": -14,
"type": "Int"
}
},
@ -77,7 +102,7 @@
}
},
"actions": {
"Credential_Lookup_-_Look_up_credential_data_for_one_or_more_users": {
"Credential_Lookup_V2_-_Look_up_credential_data_for_one_or_more_users": {
"runAfter": {},
"type": "ApiConnection",
"inputs": {
@ -91,16 +116,16 @@
},
"host": {
"connection": {
"name": "@parameters('$connections')['recordedfutureidenti']['connectionId']"
"name": "@parameters('$connections')['IdentityConnectorUpdate']['connectionId']"
}
},
"method": "post",
"path": "/credentials/lookup"
"path": "/v2/credentials/lookup"
}
},
"Response_-_Failed_to_get_Lookup_data": {
"runAfter": {
"Credential_Lookup_-_Look_up_credential_data_for_one_or_more_users": [
"Credential_Lookup_V2_-_Look_up_credential_data_for_one_or_more_users": [
"Failed"
]
},
@ -110,7 +135,7 @@
"body": {
"data": {
"lookup_lookback_date": "@formatDateTime(addDays(utcNow(), if(equals(triggerBody()?['lookup_lookback_days'], null), parameters('lookup_lookback_days_default'), triggerBody()?['lookup_lookback_days'])), 'yyyy-MM-dd')",
"lookup_results": "@body('Credential_Lookup_-_Look_up_credential_data_for_one_or_more_users')",
"lookup_results": "@body('Credential_Lookup_V2_-_Look_up_credential_data_for_one_or_more_users')",
"lookup_results_log_analytics_custom_log_name": "@if(equals(triggerBody()?['lookup_results_log_analytics_custom_log_name'], null), parameters('lookup_results_log_analytics_custom_log_name_default'), triggerBody()?['lookup_results_log_analytics_custom_log_name'])",
"parameters_passed": {
"lookup_lookback_days": "@triggerBody()?['lookup_lookback_days']",
@ -132,7 +157,6 @@
"type": "string"
},
"lookup_results": {
"properties": {},
"type": "object"
},
"lookup_results_log_analytics_custom_log_name": {
@ -179,7 +203,7 @@
"body": {
"data": {
"lookup_lookback_date": "@formatDateTime(addDays(utcNow(), if(equals(triggerBody()?['lookup_lookback_days'], null), parameters('lookup_lookback_days_default'), triggerBody()?['lookup_lookback_days'])), 'yyyy-MM-dd')",
"lookup_results": "@body('Credential_Lookup_-_Look_up_credential_data_for_one_or_more_users')",
"lookup_results": "@body('Credential_Lookup_V2_-_Look_up_credential_data_for_one_or_more_users')",
"lookup_results_log_analytics_custom_log_name": "@if(equals(triggerBody()?['lookup_results_log_analytics_custom_log_name'], null), parameters('lookup_results_log_analytics_custom_log_name_default'), triggerBody()?['lookup_results_log_analytics_custom_log_name'])",
"parameters_passed": {
"lookup_lookback_days": "@triggerBody()?['lookup_lookback_days']",
@ -201,7 +225,6 @@
"type": "string"
},
"lookup_results": {
"properties": {},
"type": "object"
},
"lookup_results_log_analytics_custom_log_name": {
@ -248,7 +271,7 @@
"body": {
"data": {
"lookup_lookback_date": "@formatDateTime(addDays(utcNow(), if(equals(triggerBody()?['lookup_lookback_days'], null), parameters('lookup_lookback_days_default'), triggerBody()?['lookup_lookback_days'])), 'yyyy-MM-dd')",
"lookup_results": "@body('Credential_Lookup_-_Look_up_credential_data_for_one_or_more_users')",
"lookup_results": "@body('Credential_Lookup_V2_-_Look_up_credential_data_for_one_or_more_users')",
"lookup_results_log_analytics_custom_log_name": "@if(equals(triggerBody()?['lookup_results_log_analytics_custom_log_name'], null), parameters('lookup_results_log_analytics_custom_log_name_default'), triggerBody()?['lookup_results_log_analytics_custom_log_name'])",
"parameters_passed": {
"lookup_lookback_days": "@triggerBody()?['lookup_lookback_days']",
@ -269,7 +292,6 @@
"type": "string"
},
"lookup_results": {
"properties": {},
"type": "object"
},
"lookup_results_log_analytics_custom_log_name": {
@ -309,64 +331,82 @@
},
"type": "ApiConnection",
"inputs": {
"body": "@{body('Credential_Lookup_-_Look_up_credential_data_for_one_or_more_users')}",
"body": "@{body('Credential_Lookup_V2_-_Look_up_credential_data_for_one_or_more_users')}",
"headers": {
"Log-Type": "@{if(equals(triggerBody()?['lookup_results_log_analytics_custom_log_name'], null), parameters('lookup_results_log_analytics_custom_log_name_default'), triggerBody()?['lookup_results_log_analytics_custom_log_name'])}",
"time-generated-field": "@{utcNow()}"
},
"host": {
"connection": {
"name": "@parameters('$connections')['azureloganalyticsdatacollector']['connectionId']"
"name": "@parameters('$connections')['azureloganalyticsdatacollector_1']['connectionId']"
}
},
"method": "post",
"path": "/api/logs"
}
}
},
"outputs": {}
}
},
"parameters": {
"$connections": {
"value": {
"azureloganalyticsdatacollector": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('LogAnalyticsDataCollectorConnectionName'))]",
"connectionName": "[variables('LogAnalyticsDataCollectorConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureloganalyticsdatacollector')]"
"IdentityConnectorUpdate": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('IdentityconnectorupdateConnectionName'))]",
"connectionName": "[variables('IdentityconnectorupdateConnectionName')]",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Web/customApis/', parameters('IdentityCustomConnectorName'))]"
},
"recordedfutureidenti": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('RecordedFutureIdentityConnectionName'))]",
"connectionName": "[variables('RecordedFutureIdentityConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/recordedfutureidenti')]"
"azureloganalyticsdatacollector_1": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureloganalyticsdatacollectorConnectionName'))]",
"connectionName": "[variables('AzureloganalyticsdatacollectorConnectionName')]",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/Azureloganalyticsdatacollector')]"
}
}
}
}
},
"name": "[parameters('PlaybookName')]",
"type": "Microsoft.Logic/workflows",
"location": "[resourceGroup().location]",
"tags": {
"hidden-SentinelTemplateName": "RFI-lookup-and-save-user",
"hidden-SentinelTemplateVersion": "1.2"
},
"identity": {
"type": "SystemAssigned"
},
"apiVersion": "2017-07-01",
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('IdentityconnectorupdateConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('AzureloganalyticsdatacollectorConnectionName'))]"
]
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[variables('IdentityconnectorupdateConnectionName')]",
"location": "[resourceGroup().location]",
"kind": "V1",
"properties": {
"displayName": "[variables('IdentityconnectorupdateConnectionName')]",
"customParameterValues": {},
"api": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Web/customApis/', parameters('IdentityCustomConnectorName'))]"
}
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('LogAnalyticsDataCollectorConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureloganalyticsdatacollector')]"
},
"displayName": "[variables('LogAnalyticsDataCollectorConnectionName')]"
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('RecordedFutureIdentityConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/recordedfutureidenti')]"
},
"displayName": "[variables('RecordedFutureIdentityConnectionName')]"
}
}
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[variables('AzureloganalyticsdatacollectorConnectionName')]",
"location": "[resourceGroup().location]",
"kind": "V1",
"properties": {
"displayName": "[variables('AzureloganalyticsdatacollectorConnectionName')]",
"customParameterValues": {},
"api": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', resourceGroup().location, '/managedApis/Azureloganalyticsdatacollector')]"
}
}
}
]
}

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

@ -1,34 +1,46 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"contentVersion": "1.1.0.0",
"metadata": {
"title": "RecordedFutureIdentity-search-external-user",
"description": "This playbook searches the Recorded Future Identity Intelligence Module for compromised external (customer) users.\n\nThis playbook depends on:\n- RecordedFutureIdentity-add-AAD-security-group-user\n- RecordedFutureIdentity-confirm-AAD-risky-user\n- RecordedFutureIdentity-lookup-and-save-user\n\n Those playbooks need to be installed **manually** before installing current playbook.",
"lastUpdateTime": "2022-09-14T00:00:00.000Z",
"title": "RFI-search-external-user",
"description": "This playbook searches the Recorded Future Identity Intelligence Module for compromised external (customer) users.\n\nThis playbook depends on:\n- RFI-add-EntraID-security-group-user\n- RFI-confirm-EntraID-risky-user\n- RFI-lookup-and-save-user\n\n Those playbooks need to be installed **manually** before installing current playbook.",
"lastUpdateTime": "2024-06-11T14:25:00.000Z",
"entities": [],
"tags": ["Identity protection"],
"support": {
"tier": "developer"
"tier": "Partner"
},
"author": {
"name": "Dmytro Branitskyi, Recorded Future (support@recordedfuture.com)"
}
"name": "Recorded Future"
},
"releaseNotes": [
{
"version": "1.0",
"title": "Initial version",
"notes": [ "Initial version" ]
},
{
"version": "1.1",
"title": "Updates",
"notes": [ "Added subscriptionId as a parameter and updated solution to match V3. Change PlaybookName prefix to RFI." ]
}
]
},
"parameters": {
"PlaybookName": {
"defaultValue": "RecordedFutureIdentity-search-external-user",
"defaultValue": "RFI-search-external-user",
"type": "string"
},
"Playbook-Name-add-AAD-security-group-user": {
"defaultValue": "RecordedFutureIdentity-add-AAD-security-group-user",
"Playbook-Name-add-EntraID-security-group-user": {
"defaultValue": "RFI-add-EntraID-security-group-user",
"type": "string"
},
"Playbook-Name-lookup-and-save-user": {
"defaultValue": "RecordedFutureIdentity-lookup-and-save-user",
"defaultValue": "RFI-lookup-and-save-user",
"type": "string"
},
"Playbook-Name-confirm-AAD-risky-user": {
"defaultValue": "RecordedFutureIdentity-confirm-AAD-risky-user",
"Playbook-Name-confirm-EntraID-risky-user": {
"defaultValue": "RFI-confirm-EntraID-risky-user",
"type": "string"
}
},
@ -43,6 +55,9 @@
"apiVersion": "2019-05-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"tags": {
"hidden-SentinelTemplateVersion": "1.1"
},
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('LogAnalyticsDataCollectorConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('AzureMonitorLogsConnectionName'))]",
@ -203,7 +218,7 @@
"inputs": {},
"description": "This block is needed only to create 3 branches in this For each loop."
},
"RecordedFutureIdentity-add-AAD-security-group-user": {
"RFI-add-EntraID-security-group-user": {
"runAfter": {
"Current_time": [
"Succeeded"
@ -222,12 +237,12 @@
"host": {
"triggerName": "manual",
"workflow": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('Playbook-Name-add-AAD-security-group-user'))]"
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('Playbook-Name-add-EntraID-security-group-user'))]"
}
}
}
},
"RecordedFutureIdentity-confirm-AAD-risky-user": {
"RFI-confirm-EntraID-risky-user": {
"runAfter": {
"Current_time": [
"Succeeded"
@ -245,12 +260,12 @@
"host": {
"triggerName": "manual",
"workflow": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('Playbook-Name-confirm-AAD-risky-user'))]"
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('Playbook-Name-confirm-EntraID-risky-user'))]"
}
}
}
},
"RecordedFutureIdentity-lookup-and-save-user": {
"RFI-lookup-and-save-user": {
"runAfter": {
"Current_time": [
"Succeeded"
@ -361,7 +376,7 @@
"resourcegroups": "RF",
"resourcename": "RF-log-analyitics",
"resourcetype": "Log Analytics Workspace",
"subscriptions": "5129b3ff-c0c6-4e86-bd1c-70e5fcd579cf",
"subscriptions": "@subscription().subscriptionId",
"timerange": "@{formatDateTime(addDays(utcNow(), parameters('search_lookback_days')), 'yyyy-MM-dd')}"
}
}

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

@ -1,34 +1,46 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"contentVersion": "1.1.0.0",
"metadata": {
"title": "RecordedFutureIdentity-search-workforce-user",
"description": "This playbook searches the Recorded Future Identity Intelligence Module for compromised workforce users.\n\nThis playbook depends on:\n- RecordedFutureIdentity-add-AAD-security-group-user\n- RecordedFutureIdentity-confirm-AAD-risky-user\n- RecordedFutureIdentity-lookup-and-save-user\n\n Those playbooks need to be installed **manually** before installing current playbook.",
"lastUpdateTime": "2022-09-14T00:00:00.000Z",
"title": "RFI-search-workforce-user",
"description": "This playbook searches the Recorded Future Identity Intelligence Module for compromised workforce users.\n\nThis playbook depends on:\n- RFI-add-EntraID-security-group-user\n- RFI-confirm-EntraID-risky-user\n- RFI-lookup-and-save-user\n\n Those playbooks need to be installed **manually** before installing current playbook.",
"lastUpdateTime": "2024-06-11T14:25:00.000Z",
"entities": [],
"tags": ["Identity protection"],
"support": {
"tier": "developer"
"tier": "Partner"
},
"author": {
"name": "Dmytro Branitskyi, Recorded Future (support@recordedfuture.com)"
}
"name": "Recorded Future"
},
"releaseNotes": [
{
"version": "1.0",
"title": "Initial version",
"notes": [ "Initial version" ]
},
{
"version": "1.1",
"title": "Updates",
"notes": [ "Added subscriptionId as a parameter and updated solution to match V3. Change PlaybookName prefix to RFI." ]
}
]
},
"parameters": {
"PlaybookName": {
"defaultValue": "RecordedFutureIdentity-search-workforce-user",
"defaultValue": "RFI-search-workforce-user",
"type": "string"
},
"Playbook-Name-add-AAD-security-group-user": {
"defaultValue": "RecordedFutureIdentity-add-AAD-security-group-user",
"Playbook-Name-add-EntraID-security-group-user": {
"defaultValue": "RFI-add-EntraID-security-group-user",
"type": "string"
},
"Playbook-Name-lookup-and-save-user": {
"defaultValue": "RecordedFutureIdentity-lookup-and-save-user",
"defaultValue": "RFI-lookup-and-save-user",
"type": "string"
},
"Playbook-Name-confirm-AAD-risky-user": {
"defaultValue": "RecordedFutureIdentity-confirm-AAD-risky-user",
"Playbook-Name-confirm-EntraID-risky-user": {
"defaultValue": "RFI-confirm-EntraID-risky-user",
"type": "string"
}
},
@ -43,6 +55,9 @@
"apiVersion": "2019-05-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"tags": {
"hidden-SentinelTemplateVersion": "1.1"
},
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('LogAnalyticsDataCollectorConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('AzureMonitorLogsConnectionName'))]",
@ -297,7 +312,7 @@
"inputs": {},
"description": "This block is needed only to create 3 branches in this For each loop."
},
"RecordedFutureIdentity-add-AAD-security-group-user": {
"RFI-add-EntraID-security-group-user": {
"runAfter": {
"Current_time": [
"Succeeded"
@ -316,12 +331,12 @@
"host": {
"triggerName": "manual",
"workflow": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('Playbook-Name-add-AAD-security-group-user'))]"
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('Playbook-Name-add-EntraID-security-group-user'))]"
}
}
}
},
"RecordedFutureIdentity-lookup-and-save-user": {
"RFI-lookup-and-save-user": {
"runAfter": {
"Current_time": [
"Succeeded"
@ -345,7 +360,7 @@
}
}
},
"RecordedFutureIdentity-confirm-AAD-risky-user": {
"RFI-confirm-EntraID-risky-user": {
"runAfter": {
"Current_time": [
"Succeeded"
@ -363,7 +378,7 @@
"host": {
"triggerName": "manual",
"workflow": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('Playbook-Name-confirm-AAD-risky-user'))]"
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('Playbook-Name-confirm-EntraID-risky-user'))]"
}
}
}
@ -513,7 +528,7 @@
"resourcegroups": "RF",
"resourcename": "RF-log-analyitics",
"resourcetype": "Log Analytics Workspace",
"subscriptions": "5129b3ff-c0c6-4e86-bd1c-70e5fcd579cf",
"subscriptions": "@subscription().subscriptionId",
"timerange": "@{formatDateTime(addDays(utcNow(), parameters('search_lookback_days')), 'yyyy-MM-dd')}"
}
}
@ -538,7 +553,7 @@
"resourcegroups": "RF",
"resourcename": "RF-log-analyitics",
"resourcetype": "Log Analytics Workspace",
"subscriptions": "5129b3ff-c0c6-4e86-bd1c-70e5fcd579cf",
"subscriptions": "@subscription().subscriptionId",
"timerange": "@{formatDateTime(addDays(utcNow(), parameters('search_lookback_days')), 'yyyy-MM-dd')}"
}
}

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

@ -1,376 +0,0 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"comment": "",
"author": "Dmytro Branitskyi, Recorded Future"
},
"parameters": {
"PlaybookName": {
"defaultValue": "Recorded_Future_Identity_Add_Risky_User_to_Security_Group",
"type": "string"
}
},
"variables": {
"AzureADConnectionName": "[concat('azuread-', parameters('PlaybookName'))]"
},
"resources": [
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2019-05-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('AzureADConnectionName'))]"
],
"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"
}
},
"triggers": {
"manual": {
"type": "Request",
"kind": "Http",
"inputs": {
"method": "POST",
"schema": {
"properties": {
"active_directory_domain": {
"type": "string"
},
"active_directory_security_group_id": {
"type": "string"
},
"risky_user_email": {
"type": "string"
}
},
"type": "object"
}
}
}
},
"actions": {
"Add_risky_user_to_Active_Directory_security_group_for_users_at_risk": {
"runAfter": {
"Response_-_Risky_user_was_not_found_in_Active_Directory": [
"Skipped"
]
},
"type": "ApiConnection",
"inputs": {
"body": {
"@@odata.id": "@body('Get_User_-_Check_if_the_user_exists_in_Active_Directory')?['id']"
},
"host": {
"connection": {
"name": "@parameters('$connections')['azuread']['connectionId']"
}
},
"method": "post",
"path": "/v1.0/groups/@{encodeURIComponent(triggerBody()?['active_directory_security_group_id'])}/members/$ref"
}
},
"Get_User_-_Check_if_the_user_exists_in_Active_Directory": {
"runAfter": {
"If_Active_Directory_domain_parameter_is_not_null_and_not_empty": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azuread']['connectionId']"
}
},
"method": "get",
"path": "/v1.0/users/@{encodeURIComponent(variables('user_principal_name'))}"
},
"description": "Use the user's email as Active Directory user principal name."
},
"If_Active_Directory_domain_parameter_is_not_null_and_not_empty": {
"actions": {
"Set_Active_Directory_user_principal_name_to_user_email's_username_+_AD_domain": {
"runAfter": {},
"type": "SetVariable",
"inputs": {
"name": "user_principal_name",
"value": "@{concat(split(triggerBody()?['risky_user_email'], '@')[0], '@', triggerBody()?['active_directory_domain'])}"
},
"description": "Use [user email's username + Active Directory domain] as Active Directory user principal name."
}
},
"runAfter": {
"Initialize_-_Active_Directory_user_principal_name": [
"Succeeded"
]
},
"else": {
"actions": {
"Set_Active_Directory_user_principal_name_to_user's_email": {
"runAfter": {},
"type": "SetVariable",
"inputs": {
"name": "user_principal_name",
"value": "@triggerBody()?['risky_user_email']"
},
"description": "Use [user's email] as Active Directory user principal name."
}
}
},
"expression": {
"and": [
{
"not": {
"equals": [
"@triggerBody()?['active_directory_domain']",
"@null"
]
}
},
{
"not": {
"equals": [
"@triggerBody()?['active_directory_domain']",
""
]
}
}
]
},
"type": "If"
},
"Initialize_-_Active_Directory_user_principal_name": {
"runAfter": {},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "user_principal_name",
"type": "string"
}
]
}
},
"Response_-_Failed_to_add_risky_user_to_AD_security_group_for_users_at_risk": {
"runAfter": {
"Response_-_Successfully_added_risky_user_to_AD_security_group_for_users_at_risk": [
"Skipped"
]
},
"type": "Response",
"kind": "Http",
"inputs": {
"body": {
"data": {
"parameters_passed": {
"active_directory_domain": "@triggerBody()?['active_directory_domain']",
"active_directory_security_group_id": "@triggerBody()?['active_directory_security_group_id']",
"risky_user_email": "@triggerBody()?['risky_user_email']"
},
"user_id_in_active_directory": "@body('Get_User_-_Check_if_the_user_exists_in_Active_Directory')?['id']",
"user_principal_name": "@variables('user_principal_name')"
},
"reason": "Failed to add Active Directory risky user to Active Directory security group for users at risk. Check active_directory_security_group_id parameter.",
"status": "Error"
},
"headers": {
"Content-Type": "application/json"
},
"schema": {
"properties": {
"data": {
"properties": {
"parameters_passed": {
"properties": {
"active_directory_domain": {
"type": "string"
},
"active_directory_security_group_id": {
"type": "string"
},
"risky_user_email": {
"type": "string"
}
},
"type": "object"
},
"user_id_in_active_directory": {
"type": "string"
},
"user_principal_name": {
"type": "string"
}
},
"type": "object"
},
"reason": {
"type": "string"
},
"status": {
"type": "string"
}
},
"type": "object"
},
"statusCode": 422
}
},
"Response_-_Risky_user_was_not_found_in_Active_Directory": {
"runAfter": {
"Get_User_-_Check_if_the_user_exists_in_Active_Directory": [
"Failed"
]
},
"type": "Response",
"kind": "Http",
"inputs": {
"body": {
"data": {
"parameters_passed": {
"active_directory_domain": "@triggerBody()?['active_directory_domain']",
"active_directory_security_group_id": "@triggerBody()?['active_directory_security_group_id']",
"risky_user_email": "@triggerBody()?['risky_user_email']"
},
"user_principal_name_used": "@variables('user_principal_name')"
},
"reason": "Risky user was not found in Active Directory.",
"status": "Error"
},
"headers": {
"Content-Type": "application/json"
},
"schema": {
"properties": {
"data": {
"properties": {
"parameters_passed": {
"properties": {
"active_directory_domain": {
"type": "string"
},
"active_directory_security_group_id": {
"type": "string"
},
"risky_user_email": {
"type": "string"
}
},
"type": "object"
},
"user_principal_name_used": {
"type": "string"
}
},
"type": "object"
},
"reason": {
"type": "string"
},
"status": {
"type": "string"
}
},
"type": "object"
},
"statusCode": 404
}
},
"Response_-_Successfully_added_risky_user_to_AD_security_group_for_users_at_risk": {
"runAfter": {
"Add_risky_user_to_Active_Directory_security_group_for_users_at_risk": [
"Succeeded"
]
},
"type": "Response",
"kind": "Http",
"inputs": {
"body": {
"data": {
"parameters_passed": {
"active_directory_domain": "@triggerBody()?['active_directory_domain']",
"active_directory_security_group_id": "@triggerBody()?['active_directory_security_group_id']",
"risky_user_email": "@triggerBody()?['risky_user_email']"
},
"user_id_in_active_directory": "@body('Get_User_-_Check_if_the_user_exists_in_Active_Directory')?['id']",
"user_principal_name": "@variables('user_principal_name')"
},
"status": "Successfully added risky user to Active Directory security group for users at risk."
},
"headers": {
"Content-Type": "application/json"
},
"schema": {
"properties": {
"data": {
"properties": {
"parameters_passed": {
"properties": {
"active_directory_domain": {
"type": "string"
},
"active_directory_security_group_id": {
"type": "string"
},
"risky_user_email": {
"type": "string"
}
},
"type": "object"
},
"user_id_in_active_directory": {
"type": "string"
},
"user_principal_name": {
"type": "string"
}
},
"type": "object"
},
"status": {
"type": "string"
}
},
"type": "object"
},
"statusCode": 200
}
}
},
"outputs": {}
},
"parameters": {
"$connections": {
"value": {
"azuread": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureADConnectionName'))]",
"connectionName": "[variables('AzureADConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuread')]"
}
}
}
}
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('AzureADConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuread')]"
},
"displayName": "[variables('AzureADConnectionName')]"
}
}
]
}

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

@ -1,406 +0,0 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"comment": "",
"author": "Dmytro Branitskyi, Recorded Future"
},
"parameters": {
"PlaybookName": {
"defaultValue": "Recorded_Future_Identity_Add_Risky_User_to_Security_Group",
"type": "string"
}
},
"variables": {
"AzureADConnectionName": "[concat('azuread-', parameters('PlaybookName'))]",
"AzureADIdentityProtectionConnectionName": "[concat('azureadip-', parameters('PlaybookName'))]"
},
"resources": [
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2019-05-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('AzureADConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('AzureADIdentityProtectionConnectionName'))]"
],
"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"
}
},
"triggers": {
"manual": {
"type": "Request",
"kind": "Http",
"inputs": {
"method": "POST",
"schema": {
"properties": {
"active_directory_domain": {
"type": "string"
},
"risky_user_email": {
"type": "string"
}
},
"type": "object"
}
}
}
},
"actions": {
"Check_if_AD_Identity_Protection_risky_users_list_contains_the_user": {
"runAfter": {
"Response_-_Risky_user_was_not_found_in_Active_Directory": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azureadip']['connectionId']"
}
},
"method": "get",
"path": "/beta/riskyUsers/@{encodeURIComponent(body('Get_User_-_Check_if_the_user_exists_in_Active_Directory')?['id'])}"
}
},
"Confirm_the_user_is_indeed_compromised": {
"runAfter": {
"Check_if_AD_Identity_Protection_risky_users_list_contains_the_user": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": {
"userIds": [
"@body('Check_if_AD_Identity_Protection_risky_users_list_contains_the_user')?['id']"
]
},
"host": {
"connection": {
"name": "@parameters('$connections')['azureadip']['connectionId']"
}
},
"method": "post",
"path": "/beta/riskyUsers/confirmCompromised"
}
},
"Get_User_-_Check_if_the_user_exists_in_Active_Directory": {
"runAfter": {
"If_Active_Directory_domain_parameter_is_not_null_and_not_empty": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azuread']['connectionId']"
}
},
"method": "get",
"path": "/v1.0/users/@{encodeURIComponent(variables('user_principal_name'))}"
}
},
"If_Active_Directory_domain_parameter_is_not_null_and_not_empty": {
"actions": {
"Set_Active_Directory_user_principal_name_to_user_email's_username_+_AD_domain": {
"runAfter": {},
"type": "SetVariable",
"inputs": {
"name": "user_principal_name",
"value": "@{concat(split(triggerBody()?['risky_user_email'], '@')[0], '@', triggerBody()?['active_directory_domain'])}"
}
}
},
"runAfter": {
"Initialize_-_Active_Directory_user_principal_name": [
"Succeeded"
]
},
"else": {
"actions": {
"Set_Active_Directory_user_principal_name_to_user's_email": {
"runAfter": {},
"type": "SetVariable",
"inputs": {
"name": "user_principal_name",
"value": "@triggerBody()?['risky_user_email']"
}
}
}
},
"expression": {
"and": [
{
"not": {
"equals": [
"@triggerBody()?['active_directory_domain']",
"@null"
]
}
},
{
"not": {
"equals": [
"@triggerBody()?['active_directory_domain']",
""
]
}
}
]
},
"type": "If"
},
"Initialize_-_Active_Directory_user_principal_name": {
"runAfter": {},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "user_principal_name",
"type": "string"
}
]
}
},
"Response_-_Failed_to_confirm_user_at_risk_is_compromised": {
"runAfter": {
"Response_-_Successfully_confirmed_user_at_risk_is_indeed_compromised": [
"Skipped"
]
},
"type": "Response",
"kind": "Http",
"inputs": {
"body": {
"data": {
"active_directory_identity_protection_results_for_risky_user": "@body('Check_if_AD_Identity_Protection_risky_users_list_contains_the_user')",
"parameters_passed": {
"active_directory_domain": "@triggerBody()?['active_directory_domain']",
"risky_user_email": "@triggerBody()?['risky_user_email']"
},
"user_id_in_active_directory": "@body('Get_User_-_Check_if_the_user_exists_in_Active_Directory')?['id']",
"user_principal_name": "@variables('user_principal_name')"
},
"reason": "Failed to confirm user at risk is compromised. Maybe the user was not present in Active Directory Identity Protection risky users list.",
"status": "Error"
},
"headers": {
"Content-Type": "application/json"
},
"schema": {
"properties": {
"data": {
"properties": {
"active_directory_identity_protection_results_for_risky_user": {
"properties": {},
"type": "object"
},
"parameters_passed": {
"properties": {
"active_directory_domain": {
"type": "string"
},
"risky_user_email": {
"type": "string"
}
},
"type": "object"
},
"user_id_in_active_directory": {
"type": "string"
},
"user_principal_name": {
"type": "string"
}
},
"type": "object"
},
"reason": {
"type": "string"
},
"status": {
"type": "string"
}
},
"type": "object"
},
"statusCode": 422
}
},
"Response_-_Risky_user_was_not_found_in_Active_Directory": {
"runAfter": {
"Get_User_-_Check_if_the_user_exists_in_Active_Directory": [
"Succeeded"
]
},
"type": "Response",
"kind": "Http",
"inputs": {
"body": {
"data": {
"parameters_passed": {
"active_directory_domain": "@triggerBody()?['active_directory_domain']",
"risky_user_email": "@triggerBody()?['risky_user_email']"
},
"user_principal_name": "@variables('user_principal_name')"
},
"reason": "Risky user was not found in Active Directory.",
"status": "Error"
},
"headers": {
"Content-Type": "application/json"
},
"schema": {
"properties": {
"data": {
"properties": {
"parameters_passed": {
"properties": {
"active_directory_domain": {
"type": "string"
},
"risky_user_email": {
"type": "string"
}
},
"type": "object"
},
"user_principal_name": {
"type": "string"
}
},
"type": "object"
},
"reason": {
"type": "string"
},
"status": {
"type": "string"
}
},
"type": "object"
},
"statusCode": 404
}
},
"Response_-_Successfully_confirmed_user_at_risk_is_indeed_compromised": {
"runAfter": {
"Confirm_the_user_is_indeed_compromised": [
"Succeeded"
]
},
"type": "Response",
"kind": "Http",
"inputs": {
"body": {
"data": {
"active_directory_identity_protection_results_for_risky_user": "@body('Check_if_AD_Identity_Protection_risky_users_list_contains_the_user')",
"parameters_passed": {
"active_directory_domain": "@triggerBody()?['active_directory_domain']",
"risky_user_email": "@triggerBody()?['risky_user_email']"
},
"user_id_in_active_directory": "@body('Get_User_-_Check_if_the_user_exists_in_Active_Directory')?['id']",
"user_principal_name": "@variables('user_principal_name')"
},
"status": "Confirmed user at risk is indeed compromised."
},
"headers": {
"Content-Type": "application/json"
},
"schema": {
"properties": {
"data": {
"properties": {
"active_directory_identity_protection_results_for_risky_user": {
"properties": {},
"type": "object"
},
"parameters_passed": {
"properties": {
"active_directory_domain": {
"type": "string"
},
"risky_user_email": {
"type": "string"
}
},
"type": "object"
},
"user_id_in_active_directory": {
"type": "string"
},
"user_principal_name": {
"type": "string"
}
},
"type": "object"
},
"status": {
"type": "string"
}
},
"type": "object"
},
"statusCode": 200
}
}
},
"outputs": {}
},
"parameters": {
"$connections": {
"value": {
"azuread": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureADConnectionName'))]",
"connectionName": "[variables('AzureADConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuread')]"
},
"azureadip": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureADIdentityProtectionConnectionName'))]",
"connectionName": "[variables('AzureADIdentityProtectionConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureadip')]"
}
}
}
}
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('AzureADConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuread')]"
},
"displayName": "[variables('AzureADConnectionName')]"
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('AzureADIdentityProtectionConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureadip')]"
},
"displayName": "[variables('AzureADIdentityProtectionConnectionName')]"
}
}
]
}

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

@ -1,543 +0,0 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"PlaybookName": {
"defaultValue": "Recorded_Future_Identity_External",
"type": "string"
},
"PlaybookName_Add_Risky_User_to_Security_Group": {
"defaultValue": "Recorded_Future_Identity_Add_Risky_User_to_Security_Group",
"type": "string"
},
"PlaybookName_Lookup_and_Save": {
"defaultValue": "Recorded_Future_Identity_Lookup_And_Save",
"type": "string"
},
"PlaybookName_Identity_Protection_Confirm_User_Is_Risky": {
"defaultValue": "Recorded_Future_Identity_Add_Risky_User_to_Security_Group",
"type": "string"
}
},
"variables": {
"LogAnalyticsDataCollectorConnectionName": "[concat('azureloganalyticsdatacollector-', parameters('PlaybookName'))]",
"AzureMonitorLogsConnectionName": "[concat('azuremonitorlogs-', parameters('PlaybookName'))]",
"RecordedFutureIdentityConnectionName": "[concat('recordedfutureidenti-', parameters('PlaybookName'))]"
},
"resources": [
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2019-05-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('LogAnalyticsDataCollectorConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('AzureMonitorLogsConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('RecordedFutureIdentityConnectionName'))]"
],
"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"
}
},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Day",
"interval": 1
},
"evaluatedRecurrence": {
"frequency": "Day",
"interval": 1
},
"type": "Recurrence"
}
},
"actions": {
"Add_Log_Analytics_Malware_log_exposures_to_the_corresponding_array": {
"runAfter": {
"Query_Log_Analytics_for_Malware_log_exposures": [
"Succeeded"
]
},
"type": "SetVariable",
"inputs": {
"name": "known_malware_log_creds",
"value": "@body('Query_Log_Analytics_for_Malware_log_exposures')?['value']"
}
},
"Credential_Search_-_Search_credential_data_for_one_or_more_domains": {
"runAfter": {
"Initialize_-_Name_for_\"Malware_Logs\"_Log_Analytics_Custom_Log": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": {
"domain_type": "My Organization (workforce use case)",
"domains": [
"@variables('company_domain')"
],
"filter": {
"latest_downloaded_gte": "@{formatDateTime(addDays(utcNow(), variables('search_lookback_days')), 'yyyy-MM-dd')}"
},
"limit": 500
},
"host": {
"connection": {
"name": "@parameters('$connections')['recordedfutureidenti']['connectionId']"
}
},
"method": "post",
"path": "/credentials/search"
}
},
"For_Each_-_extend_new_exposures_array_with_new_Malware_log_exposures": {
"foreach": "@variables('unknown_malware_log_creds')",
"actions": {
"Add_new_Malware_log_exposure_email_to_the_array_of_all_new_exposures": {
"runAfter": {},
"type": "AppendToArrayVariable",
"inputs": {
"name": "newly_leaked_emails",
"value": "@items('For_Each_-_extend_new_exposures_array_with_new_Malware_log_exposures')?['login']"
}
}
},
"runAfter": {
"Initialize_-_Array_of_all_new_exposures_(emails)": [
"Succeeded"
]
},
"type": "Foreach"
},
"For_Each_new_Malware_log_exposures": {
"foreach": "@body('Credential_Search_-_Search_credential_data_for_one_or_more_domains')?['malware_logs']",
"actions": {
"If_Malware_log_exposure_is_new": {
"actions": {
"Add_new_exposure_to_the_new_Malware_log_exposures_array": {
"runAfter": {},
"type": "AppendToArrayVariable",
"inputs": {
"name": "unknown_malware_log_creds",
"value": "@items('For_Each_new_Malware_log_exposures')"
}
}
},
"runAfter": {},
"expression": {
"and": [
{
"not": {
"contains": [
"@variables('known_malware_log_creds')",
"@items('For_Each_new_Malware_log_exposures')"
]
}
}
]
},
"type": "If",
"description": "\"New\" - means it have not been previously seen by the Logic App."
}
},
"runAfter": {
"Initialize_-_Array_of_new_Malware_log_exposures": [
"Succeeded"
]
},
"type": "Foreach"
},
"For_each_new_exposures_-_do_protective_actions": {
"foreach": "@variables('newly_leaked_emails')",
"actions": {
"Current_time": {
"runAfter": {},
"type": "Expression",
"kind": "CurrentTime",
"inputs": {},
"description": "This block is needed only to create 3 branches in this For each loop."
},
"IdentityPlaybook_-_add_risky_user_to_AD_security_group": {
"runAfter": {
"Current_time": [
"Succeeded"
]
},
"type": "Workflow",
"inputs": {
"body": {
"active_directory_domain": "@variables('active_directory_domain')",
"active_directory_security_group_id": "@variables('risky_security_group_id')",
"risky_user_email": "@{items('For_each_new_exposures_-_do_protective_actions')}"
},
"headers": {
"Content-Type": "application/json"
},
"host": {
"triggerName": "manual",
"workflow": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('PlaybookName_Add_Risky_User_to_Security_Group'))]"
}
}
}
},
"IdentityPlaybook_-_identity_protection_confirm_user_is_risky": {
"runAfter": {
"Current_time": [
"Succeeded"
]
},
"type": "Workflow",
"inputs": {
"body": {
"active_directory_domain": "@variables('active_directory_domain')",
"risky_user_email": "@{items('For_each_new_exposures_-_do_protective_actions')}"
},
"headers": {
"Content-Type": "application/json"
},
"host": {
"triggerName": "manual",
"workflow": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('PlaybookName_Identity_Protection_Confirm_User_Is_Risky'))]"
}
}
}
},
"IdentityPlaybook_-_lookup_data_on_risky_user_and_save_it_into_LogAnalytics": {
"runAfter": {
"Current_time": [
"Succeeded"
]
},
"type": "Workflow",
"inputs": {
"body": {
"lookup_lookback_range": "@variables('lookup_lookback_days')",
"lookup_results_loganalytics_custom_log": "@variables('lookup_results_loganalytics_custom_log')",
"risky_user_email": "@{items('For_each_new_exposures_-_do_protective_actions')}"
},
"headers": {
"Content-Type": "application/json"
},
"host": {
"triggerName": "manual",
"workflow": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('PlaybookName_Lookup_and_Save'))]"
}
}
}
}
},
"runAfter": {
"Initialize_-_ID_of_Active_Directory_security_group_for_users_at_risk": [
"Succeeded"
]
},
"type": "Foreach",
"runtimeConfiguration": {
"concurrency": {
"repetitions": 1
}
}
},
"Initialize_-_Array_of_all_new_exposures_(emails)": {
"runAfter": {
"Send_Data_-_Save_new_Malware_log_exposures_into_Log_Analytics_Custom_Log": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "newly_leaked_emails",
"type": "array"
}
]
}
},
"Initialize_-_Array_of_known_Malware_log_exposures": {
"runAfter": {
"Credential_Search_-_Search_credential_data_for_one_or_more_domains": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "known_malware_log_creds",
"type": "array"
}
]
},
"description": "Existing Malware logs (collected during prior Logic App runs)"
},
"Initialize_-_Array_of_new_Malware_log_exposures": {
"runAfter": {
"Add_Log_Analytics_Malware_log_exposures_to_the_corresponding_array": [
"Succeeded",
"Skipped"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "unknown_malware_log_creds",
"type": "array"
}
]
},
"description": "Exposures that wasn't previously seen by the Logic App."
},
"Initialize_-_ID_of_Active_Directory_security_group_for_users_at_risk": {
"runAfter": {
"Initialize_-_[Optional]_Active_Directory_Domain": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "risky_security_group_id",
"type": "string"
}
]
},
"description": "Create an Active Directory security group that will store any users with exposed credentials."
},
"Initialize_-_Lookup_range_(days_back)": {
"runAfter": {
"Initialize_-_Name_for_Lookup_results_Log_Analytics_Custom_Log": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "lookup_lookback_days",
"type": "integer",
"value": -365
}
]
},
"description": "Number of days before today to lookup. E.g. input \"-14\" to search the last 14 days."
},
"Initialize_-_Name_for_\"Malware_Logs\"_Log_Analytics_Custom_Log": {
"runAfter": {
"Initialize_-_Search_range_(days_back)": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "malware_logs_loganalytics_custom_log",
"type": "string",
"value": "LeakedCredentials_MalwareLogs_CL"
}
]
},
"description": "Custom Log name (Value) must end with \"CL\""
},
"Initialize_-_Name_for_Lookup_results_Log_Analytics_Custom_Log": {
"runAfter": {
"For_Each_-_extend_new_exposures_array_with_new_Malware_log_exposures": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "lookup_results_loganalytics_custom_log",
"type": "string",
"value": "RiskyUsers_CL"
}
]
},
"description": "Custom Log name (Value) must end with \"CL\""
},
"Initialize_-_Organization_domain": {
"runAfter": {},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "company_domain",
"type": "string",
"value": "example.com"
}
]
},
"description": "Organization domain to search exposures for."
},
"Initialize_-_Search_range_(days_back)": {
"runAfter": {
"Initialize_-_Organization_domain": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "search_lookback_days",
"type": "integer",
"value": -14
}
]
},
"description": "Number of days before today to search. E.g. input \"-14\" to search the last 14 days."
},
"Initialize_-_[Optional]_Active_Directory_Domain": {
"runAfter": {
"Initialize_-_Lookup_range_(days_back)": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "active_directory_domain",
"type": "string"
}
]
},
"description": "If Active Directory (AD) and email use different domains, set AD domain here (Value). Syntax: \"company.onmicrosoft.com\" (exclude \"@\")."
},
"Query_Log_Analytics_for_Malware_log_exposures": {
"runAfter": {
"Initialize_-_Array_of_known_Malware_log_exposures": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": "@{variables('malware_logs_loganalytics_custom_log')}\n| project login=login_s, domain=domain_s",
"host": {
"connection": {
"name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
}
},
"method": "post",
"path": "/queryData",
"queries": {
"resourcegroups": "RF",
"resourcename": "RF-log-analyitics",
"resourcetype": "Log Analytics Workspace",
"subscriptions": "5129b3ff-c0c6-4e86-bd1c-70e5fcd579cf",
"timerange": "@{formatDateTime(addDays(utcNow(), variables('search_lookback_days')), 'yyyy-MM-dd')}"
}
}
},
"Send_Data_-_Save_new_Malware_log_exposures_into_Log_Analytics_Custom_Log": {
"runAfter": {
"Transform_new_Malware_log_exposures_array_into_a_JSON_object": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": "@{outputs('Transform_new_Malware_log_exposures_array_into_a_JSON_object')}",
"headers": {
"Log-Type": "@variables('malware_logs_loganalytics_custom_log')",
"time-generated-field": "@{utcNow()}"
},
"host": {
"connection": {
"name": "@parameters('$connections')['azureloganalyticsdatacollector']['connectionId']"
}
},
"method": "post",
"path": "/api/logs"
}
},
"Transform_new_Malware_log_exposures_array_into_a_JSON_object": {
"runAfter": {
"For_Each_new_Malware_log_exposures": [
"Succeeded"
]
},
"type": "Compose",
"inputs": "@variables('unknown_malware_log_creds')"
}
},
"outputs": {}
},
"parameters": {
"$connections": {
"value": {
"azureloganalyticsdatacollector": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('LogAnalyticsDataCollectorConnectionName'))]",
"connectionName": "[variables('LogAnalyticsDataCollectorConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureloganalyticsdatacollector')]"
},
"azuremonitorlogs": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureMonitorLogsConnectionName'))]",
"connectionName": "[variables('AzureMonitorLogsConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuremonitorlogs')]"
},
"recordedfutureidenti": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('RecordedFutureIdentityConnectionName'))]",
"connectionName": "[variables('RecordedFutureIdentityConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/recordedfutureidenti')]"
}
}
}
}
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('LogAnalyticsDataCollectorConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureloganalyticsdatacollector')]"
},
"displayName": "[variables('LogAnalyticsDataCollectorConnectionName')]"
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('AzureMonitorLogsConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuremonitorlogs')]"
},
"displayName": "[variables('AzureMonitorLogsConnectionName')]"
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('RecordedFutureIdentityConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/recordedfutureidenti')]"
},
"displayName": "[variables('RecordedFutureIdentityConnectionName')]"
}
}
]
}

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

@ -1,768 +0,0 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"comment": "",
"author": "Dmytro Branitskyi, Recorded Future"
},
"parameters": {
"PlaybookName": {
"defaultValue": "Recorded_Future_Identity_Workforce",
"type": "string"
},
"PlaybookName_Add_Risky_User_to_Security_Group": {
"defaultValue": "Recorded_Future_Identity_Add_Risky_User_to_Security_Group",
"type": "string"
},
"PlaybookName_Lookup_and_Save": {
"defaultValue": "Recorded_Future_Identity_Lookup_And_Save",
"type": "string"
},
"PlaybookName_Identity_Protection_Confirm_User_Is_Risky": {
"defaultValue": "Recorded_Future_Identity_Add_Risky_User_to_Security_Group",
"type": "string"
}
},
"variables": {
"LogAnalyticsDataCollectorConnectionName": "[concat('azureloganalyticsdatacollector-', parameters('PlaybookName'))]",
"AzureMonitorLogsConnectionName": "[concat('azuremonitorlogs-', parameters('PlaybookName'))]",
"RecordedFutureIdentityConnectionName": "[concat('recordedfutureidenti-', parameters('PlaybookName'))]"
},
"resources": [
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2019-05-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('LogAnalyticsDataCollectorConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('AzureMonitorLogsConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('RecordedFutureIdentityConnectionName'))]"
],
"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"
}
},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Day",
"interval": 1
},
"evaluatedRecurrence": {
"frequency": "Day",
"interval": 1
},
"type": "Recurrence"
}
},
"actions": {
"Add_Log_Analytics_Credential_dump_exposures_to_the_corresponding_array": {
"runAfter": {
"Query_Log_Analytics_for_Credential_dump_exposures": [
"Succeeded"
]
},
"type": "SetVariable",
"inputs": {
"name": "known_credential_dump_creds",
"value": "@body('Query_Log_Analytics_for_Credential_dump_exposures')?['value']"
}
},
"Add_Log_Analytics_Malware_log_exposures_to_the_corresponding_array": {
"runAfter": {
"Query_Log_Analytics_for_Malware_log_exposures": [
"Succeeded"
]
},
"type": "SetVariable",
"inputs": {
"name": "known_malware_log_creds",
"value": "@body('Query_Log_Analytics_for_Malware_log_exposures')?['value']"
}
},
"Credential_Search_-_Search_credential_data_for_one_or_more_domains": {
"runAfter": {
"Initialize_-_Name_for_\"Malware_Logs\"_Log_Analytics_Custom_Log": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": {
"domain_type": "My Organization (workforce use case)",
"domains": [
"@variables('company_domain')"
],
"filter": {
"latest_downloaded_gte": "@{formatDateTime(addDays(utcNow(), variables('search_lookback_days')), 'yyyy-MM-dd')}"
},
"limit": 500
},
"host": {
"connection": {
"name": "@parameters('$connections')['recordedfutureidenti']['connectionId']"
}
},
"method": "post",
"path": "/credentials/search"
}
},
"For_Each_-_Make_new_and_known_Credential_dumps_be_comparable": {
"foreach": "@body('Credential_Search_-_Search_credential_data_for_one_or_more_domains')?['credential_dumps']",
"actions": {
"Append_transformed_exposures_to_array": {
"runAfter": {},
"type": "AppendToArrayVariable",
"inputs": {
"name": "transformed_rf_api_credential_dump_creds",
"value": {
"email": "@items('For_Each_-_Make_new_and_known_Credential_dumps_be_comparable')"
}
}
}
},
"runAfter": {
"Initialize_-_Array_of_transformed_new_Credential_dump_exposures": [
"Succeeded"
]
},
"type": "Foreach"
},
"For_Each_-_extend_new_exposures_array_with_new_Credential_dump_exposures": {
"foreach": "@variables('unknown_credential_dump_creds')",
"actions": {
"Add_new_Credential_dump_exposure_email_to_the_array_of_all_new_exposures": {
"runAfter": {},
"type": "AppendToArrayVariable",
"inputs": {
"name": "newly_leaked_emails",
"value": "@items('For_Each_-_extend_new_exposures_array_with_new_Credential_dump_exposures')?['email']"
}
}
},
"runAfter": {
"For_Each_-_extend_new_exposures_array_with_new_Malware_log_exposures": [
"Succeeded"
]
},
"type": "Foreach"
},
"For_Each_-_extend_new_exposures_array_with_new_Malware_log_exposures": {
"foreach": "@variables('unknown_malware_log_creds')",
"actions": {
"Add_new_Malware_log_exposure_email_to_the_array_of_all_new_exposures": {
"runAfter": {},
"type": "AppendToArrayVariable",
"inputs": {
"name": "newly_leaked_emails",
"value": "@items('For_Each_-_extend_new_exposures_array_with_new_Malware_log_exposures')?['login']"
}
}
},
"runAfter": {
"Initialize_-_Array_of_all_new_exposures_(emails)": [
"Succeeded"
]
},
"type": "Foreach"
},
"For_Each_new_Credential_dump_exposures": {
"foreach": "@variables('transformed_rf_api_credential_dump_creds')",
"actions": {
"If_Credential_dump_exposure_is_new": {
"actions": {
"Add_new_exposure_to_the_new_Credential_dump_exposures_array": {
"runAfter": {},
"type": "AppendToArrayVariable",
"inputs": {
"name": "unknown_credential_dump_creds",
"value": "@items('For_Each_new_Credential_dump_exposures')"
}
}
},
"runAfter": {},
"expression": {
"and": [
{
"not": {
"contains": [
"@variables('known_credential_dump_creds')",
"@items('For_Each_new_Credential_dump_exposures')"
]
}
}
]
},
"type": "If",
"description": "\"New\" - means it have not been previously seen by the Logic App."
}
},
"runAfter": {
"Initialize_-_Array_of_new_Credential_dump_exposures": [
"Succeeded"
]
},
"type": "Foreach"
},
"For_Each_new_Malware_log_exposures": {
"foreach": "@body('Credential_Search_-_Search_credential_data_for_one_or_more_domains')?['malware_logs']",
"actions": {
"If_Malware_log_exposure_is_new": {
"actions": {
"Add_new_exposure_to_the_new_Malware_log_exposures_array": {
"runAfter": {},
"type": "AppendToArrayVariable",
"inputs": {
"name": "unknown_malware_log_creds",
"value": "@items('For_Each_new_Malware_log_exposures')"
}
}
},
"runAfter": {},
"expression": {
"and": [
{
"not": {
"contains": [
"@variables('known_malware_log_creds')",
"@items('For_Each_new_Malware_log_exposures')"
]
}
}
]
},
"type": "If",
"description": "\"New\" - means it have not been previously seen by the Logic App."
}
},
"runAfter": {
"Initialize_-_Array_of_new_Malware_log_exposures": [
"Succeeded"
]
},
"type": "Foreach"
},
"For_each_new_exposures_-_do_protective_actions": {
"foreach": "@variables('newly_leaked_emails')",
"actions": {
"Current_time": {
"runAfter": {},
"type": "Expression",
"kind": "CurrentTime",
"inputs": {},
"description": "This block is needed only to create 3 branches in this For each loop."
},
"IdentityPlaybook_-_add_risky_user_to_AD_security_group": {
"runAfter": {
"Current_time": [
"Succeeded"
]
},
"type": "Workflow",
"inputs": {
"body": {
"active_directory_domain": "@variables('active_directory_domain')",
"active_directory_security_group_id": "@variables('risky_security_group_id')",
"risky_user_email": "@{items('For_each_new_exposures_-_do_protective_actions')}"
},
"headers": {
"Content-Type": "application/json"
},
"host": {
"triggerName": "manual",
"workflow": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('PlaybookName_Add_Risky_User_to_Security_Group'))]"
}
}
}
},
"IdentityPlaybook_-_lookup_data_on_risky_user_and_save_it_into_LogAnalytics": {
"runAfter": {
"Current_time": [
"Succeeded"
]
},
"type": "Workflow",
"inputs": {
"body": {
"lookup_lookback_range": "@variables('lookup_lookback_days')",
"lookup_results_loganalytics_custom_log": "@variables('lookup_results_loganalytics_custom_log')",
"risky_user_email": "@{items('For_each_new_exposures_-_do_protective_actions')}"
},
"headers": {
"Content-Type": "application/json"
},
"host": {
"triggerName": "manual",
"workflow": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('PlaybookName_Lookup_and_Save'))]"
}
}
}
},
"IdentityPlaybook_-_identity_protection_confirm_user_is_risky": {
"runAfter": {
"Current_time": [
"Succeeded"
]
},
"type": "Workflow",
"inputs": {
"body": {
"active_directory_domain": "@variables('active_directory_domain')",
"risky_user_email": "@{items('For_each_new_exposures_-_do_protective_actions')}"
},
"headers": {
"Content-Type": "application/json"
},
"host": {
"triggerName": "manual",
"workflow": {
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Logic/workflows/', parameters('PlaybookName_Identity_Protection_Confirm_User_Is_Risky'))]"
}
}
}
}
},
"runAfter": {
"Initialize_-_ID_of_Active_Directory_security_group_for_users_at_risk": [
"Succeeded"
]
},
"type": "Foreach",
"runtimeConfiguration": {
"concurrency": {
"repetitions": 1
}
}
},
"Initialize_-_Array_of_all_new_exposures_(emails)": {
"runAfter": {
"Send_Data_-_Save_new_Credential_dump_exposures_into_Log_Analytics_Custom_Log": [
"Succeeded",
"TimedOut",
"Failed"
],
"Send_Data_-_Save_new_Malware_log_exposures_into_Log_Analytics_Custom_Log": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "newly_leaked_emails",
"type": "array"
}
]
}
},
"Initialize_-_Array_of_known_Credential_dump_exposures": {
"runAfter": {
"Credential_Search_-_Search_credential_data_for_one_or_more_domains": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "known_credential_dump_creds",
"type": "array"
}
]
},
"description": "Existing Credential dumps (collected during prior Logic App runs)"
},
"Initialize_-_Array_of_known_Malware_log_exposures": {
"runAfter": {
"Credential_Search_-_Search_credential_data_for_one_or_more_domains": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "known_malware_log_creds",
"type": "array"
}
]
},
"description": "Existing Malware logs (collected during prior Logic App runs)"
},
"Initialize_-_Array_of_new_Credential_dump_exposures": {
"runAfter": {
"For_Each_-_Make_new_and_known_Credential_dumps_be_comparable": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "unknown_credential_dump_creds",
"type": "array"
}
]
},
"description": "\"New\" - means that this are new leaks, which weren't seen on previous runs of the logic app."
},
"Initialize_-_Array_of_new_Malware_log_exposures": {
"runAfter": {
"Add_Log_Analytics_Malware_log_exposures_to_the_corresponding_array": [
"Succeeded",
"Skipped"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "unknown_malware_log_creds",
"type": "array"
}
]
},
"description": "Exposures that wasn't previously seen by the Logic App."
},
"Initialize_-_Array_of_transformed_new_Credential_dump_exposures": {
"runAfter": {
"Add_Log_Analytics_Credential_dump_exposures_to_the_corresponding_array": [
"Succeeded",
"Skipped"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "transformed_rf_api_credential_dump_creds",
"type": "array"
}
]
},
"description": "New Credential dumps are formatted to enable storing and comparing them with existing Credential dumps in Log Analytics."
},
"Initialize_-_ID_of_Active_Directory_security_group_for_users_at_risk": {
"runAfter": {
"Initialize_-_[Optional]_Active_Directory_Domain": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "risky_security_group_id",
"type": "string"
}
]
},
"description": "Create an Active Directory security group that will store any users with exposed credentials."
},
"Initialize_-_Lookup_range_(days_back)": {
"runAfter": {
"Initialize_-_Name_for_Lookup_results_Log_Analytics_Custom_Log": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "lookup_lookback_days",
"type": "integer",
"value": -365
}
]
},
"description": "Number of days before today to lookup. E.g. input \"-14\" to search the last 14 days."
},
"Initialize_-_Name_for_\"Credential_Dumps\"_Log_Analytics_Custom_Log": {
"runAfter": {
"Initialize_-_Search_range_(days_back)": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "credential_dumps_loganalytics_custom_log",
"type": "string",
"value": "LeakedCredentials_CredentialDumps_CL"
}
]
},
"description": "Custom Log name (Value) must end with \"CL\""
},
"Initialize_-_Name_for_\"Malware_Logs\"_Log_Analytics_Custom_Log": {
"runAfter": {
"Initialize_-_Name_for_\"Credential_Dumps\"_Log_Analytics_Custom_Log": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "malware_logs_loganalytics_custom_log",
"type": "string",
"value": "LeakedCredentials_MalwareLogs_CL"
}
]
},
"description": "Custom Log name (Value) must end with \"CL\""
},
"Initialize_-_Name_for_Lookup_results_Log_Analytics_Custom_Log": {
"runAfter": {
"For_Each_-_extend_new_exposures_array_with_new_Credential_dump_exposures": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "lookup_results_loganalytics_custom_log",
"type": "string",
"value": "RiskyUsers_CL"
}
]
},
"description": "Custom Log name (Value) must end with \"CL\""
},
"Initialize_-_Organization_domain": {
"runAfter": {},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "company_domain",
"type": "string",
"value": "example.com"
}
]
},
"description": "Organization domain to search exposures for."
},
"Initialize_-_Search_range_(days_back)": {
"runAfter": {
"Initialize_-_Organization_domain": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "search_lookback_days",
"type": "integer",
"value": -14
}
]
},
"description": "Number of days before today to search. E.g. input \"-14\" to search the last 14 days."
},
"Initialize_-_[Optional]_Active_Directory_Domain": {
"runAfter": {
"Initialize_-_Lookup_range_(days_back)": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "active_directory_domain",
"type": "string"
}
]
},
"description": "If Active Directory (AD) and email use different domains, set AD domain here (Value). Syntax: \"company.onmicrosoft.com\" (exclude \"@\")."
},
"Query_Log_Analytics_for_Credential_dump_exposures": {
"runAfter": {
"Initialize_-_Array_of_known_Credential_dump_exposures": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": "@{variables('credential_dumps_loganalytics_custom_log')}\n| project email=email_s",
"host": {
"connection": {
"name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
}
},
"method": "post",
"path": "/queryData",
"queries": {
"resourcegroups": "RF",
"resourcename": "RF-log-analyitics",
"resourcetype": "Log Analytics Workspace",
"subscriptions": "5129b3ff-c0c6-4e86-bd1c-70e5fcd579cf",
"timerange": "@{formatDateTime(addDays(utcNow(), variables('search_lookback_days')), 'yyyy-MM-dd')}"
}
}
},
"Query_Log_Analytics_for_Malware_log_exposures": {
"runAfter": {
"Initialize_-_Array_of_known_Malware_log_exposures": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": "@{variables('malware_logs_loganalytics_custom_log')}\n| project login=login_s, domain=domain_s",
"host": {
"connection": {
"name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
}
},
"method": "post",
"path": "/queryData",
"queries": {
"resourcegroups": "RF",
"resourcename": "RF-log-analyitics",
"resourcetype": "Log Analytics Workspace",
"subscriptions": "5129b3ff-c0c6-4e86-bd1c-70e5fcd579cf",
"timerange": "@{formatDateTime(addDays(utcNow(), variables('search_lookback_days')), 'yyyy-MM-dd')}"
}
}
},
"Send_Data_-_Save_new_Credential_dump_exposures_into_Log_Analytics_Custom_Log": {
"runAfter": {
"Transform_new_Credential_dump_exposures_array_into_a_JSON_object": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": "@{outputs('Transform_new_Credential_dump_exposures_array_into_a_JSON_object')}",
"headers": {
"Log-Type": "@variables('credential_dumps_loganalytics_custom_log')",
"time-generated-field": "@{utcNow()}"
},
"host": {
"connection": {
"name": "@parameters('$connections')['azureloganalyticsdatacollector']['connectionId']"
}
},
"method": "post",
"path": "/api/logs"
}
},
"Send_Data_-_Save_new_Malware_log_exposures_into_Log_Analytics_Custom_Log": {
"runAfter": {
"Transform_new_Malware_log_exposures_array_into_a_JSON_object": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": "@{outputs('Transform_new_Malware_log_exposures_array_into_a_JSON_object')}",
"headers": {
"Log-Type": "@variables('malware_logs_loganalytics_custom_log')",
"time-generated-field": "@{utcNow()}"
},
"host": {
"connection": {
"name": "@parameters('$connections')['azureloganalyticsdatacollector']['connectionId']"
}
},
"method": "post",
"path": "/api/logs"
}
},
"Transform_new_Credential_dump_exposures_array_into_a_JSON_object": {
"runAfter": {
"For_Each_new_Credential_dump_exposures": [
"Succeeded"
]
},
"type": "Compose",
"inputs": "@variables('unknown_credential_dump_creds')"
},
"Transform_new_Malware_log_exposures_array_into_a_JSON_object": {
"runAfter": {
"For_Each_new_Malware_log_exposures": [
"Succeeded"
]
},
"type": "Compose",
"inputs": "@variables('unknown_malware_log_creds')"
}
},
"outputs": {}
},
"parameters": {
"$connections": {
"value": {
"azureloganalyticsdatacollector": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('LogAnalyticsDataCollectorConnectionName'))]",
"connectionName": "[variables('LogAnalyticsDataCollectorConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureloganalyticsdatacollector')]"
},
"azuremonitorlogs": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('AzureMonitorLogsConnectionName'))]",
"connectionName": "[variables('AzureMonitorLogsConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuremonitorlogs')]"
},
"recordedfutureidenti": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('RecordedFutureIdentityConnectionName'))]",
"connectionName": "[variables('RecordedFutureIdentityConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/recordedfutureidenti')]"
}
}
}
}
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('LogAnalyticsDataCollectorConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureloganalyticsdatacollector')]"
},
"displayName": "[variables('LogAnalyticsDataCollectorConnectionName')]"
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('AzureMonitorLogsConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuremonitorlogs')]"
},
"displayName": "[variables('AzureMonitorLogsConnectionName')]"
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('RecordedFutureIdentityConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/recordedfutureidenti')]"
},
"displayName": "[variables('RecordedFutureIdentityConnectionName')]"
}
}
]
}

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

@ -1,322 +0,0 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"comment": "",
"author": "Dmytro Branitskyi, Recorded Future"
},
"parameters": {
"PlaybookName": {
"defaultValue": "Recorded_Future_Identity_Lookup_And_Save",
"type": "string"
}
},
"variables": {
"LogAnalyticsDataCollectorConnectionName": "[concat('azureloganalyticsdatacollector-', parameters('PlaybookName'))]",
"RecordedFutureIdentityConnectionName": "[concat('recordedfutureidenti-', parameters('PlaybookName'))]"
},
"resources": [
{
"type": "Microsoft.Logic/workflows",
"apiVersion": "2019-05-01",
"name": "[parameters('PlaybookName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('LogAnalyticsDataCollectorConnectionName'))]",
"[resourceId('Microsoft.Web/connections', variables('RecordedFutureIdentityConnectionName'))]"
],
"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"
}
},
"triggers": {
"manual": {
"type": "Request",
"kind": "Http",
"inputs": {
"method": "POST",
"schema": {
"properties": {
"lookup_lookback_range": {
"type": "integer"
},
"lookup_results_loganalytics_custom_log": {
"type": "string"
},
"risky_user_email": {
"type": "string"
}
},
"type": "object"
}
}
}
},
"actions": {
"Credential_Lookup_-_Look_up_credential_data_for_one_or_more_users": {
"runAfter": {
"Initialize_-_Default_name_for_Lookup_results_Log_Analytics_custom_log": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": {
"filter": {
"first_downloaded_gte": "@{formatDateTime(addDays(utcNow(), if(equals(triggerBody()?['lookup_lookback_range'], null), variables('default_value_for_lookup_lookback_days'), triggerBody()?['lookup_lookback_range'])), 'yyyy-MM-dd')}"
},
"subjects": [
"@triggerBody()?['risky_user_email']"
]
},
"host": {
"connection": {
"name": "@parameters('$connections')['recordedfutureidenti']['connectionId']"
}
},
"method": "post",
"path": "/credentials/lookup"
}
},
"Initialize_-_Default_name_for_Lookup_results_Log_Analytics_custom_log": {
"runAfter": {
"Initialize_-_Default_value_for_Lookup_range_(days_back)": [
"Succeeded"
]
},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "lookup_results_loganalytics_custom_log",
"type": "string",
"value": "RiskyUsersLookupResults_CL"
}
]
},
"description": "Table name must ends with \"CL\""
},
"Initialize_-_Default_value_for_Lookup_range_(days_back)": {
"runAfter": {},
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "default_value_for_lookup_lookback_days",
"type": "integer",
"value": -365
}
]
},
"description": "Default number of days before today to lookup. E.g. input \"-14\" to search the last 14 days. This value can be changed by passing corresponding parameter in requests' json body."
},
"Response_-_Failed": {
"runAfter": {
"Response_-_Successfully_saved_lookup_results_into_LogAnalytics": [
"Skipped"
]
},
"type": "Response",
"kind": "Http",
"inputs": {
"body": {
"data": {
"lookup_lookback_date": "@formatDateTime(addDays(utcNow(), if(equals(triggerBody()?['lookup_lookback_range'], null), variables('default_value_for_lookup_lookback_days'), triggerBody()?['lookup_lookback_range'])), 'yyyy-MM-dd')",
"lookup_results": "@body('Credential_Lookup_-_Look_up_credential_data_for_one_or_more_users')",
"lookup_results_loganalytics_custom_log": "@if(equals(triggerBody()?['lookup_results_loganalytics_custom_log'], null), variables('lookup_results_loganalytics_custom_log'), triggerBody()?['lookup_results_loganalytics_custom_log'])",
"parameters_passed": {
"lookup_lookback_range": "@triggerBody()?['lookup_lookback_range']",
"lookup_results_loganalytics_custom_log": "@triggerBody()?['lookup_results_loganalytics_custom_log']",
"risky_user_email": "@triggerBody()?['risky_user_email']"
}
},
"reason": "Unknown",
"status": "Error"
},
"headers": {
"Content-Type": "application/json"
},
"schema": {
"properties": {
"data": {
"properties": {
"lookup_lookback_date": {
"type": "string"
},
"lookup_results": {
"properties": {},
"type": "object"
},
"lookup_results_loganalytics_custom_log": {
"type": "string"
},
"parameters_passed": {
"properties": {
"lookup_lookback_range": {
"type": "integer"
},
"lookup_results_loganalytics_custom_log": {
"type": "string"
},
"risky_user_email": {
"type": "string"
}
},
"type": "object"
}
},
"type": "object"
},
"reason": {
"type": "string"
},
"status": {
"type": "string"
}
},
"type": "object"
},
"statusCode": 422
}
},
"Response_-_Successfully_saved_lookup_results_into_LogAnalytics": {
"runAfter": {
"Send_Data_-_Save_Lookup_results_to_LogAnalytics_Custom_Log": [
"Succeeded"
]
},
"type": "Response",
"kind": "Http",
"inputs": {
"body": {
"data": {
"lookup_lookback_date": "@formatDateTime(addDays(utcNow(), if(equals(triggerBody()?['lookup_lookback_range'], null), variables('default_value_for_lookup_lookback_days'), triggerBody()?['lookup_lookback_range'])), 'yyyy-MM-dd')",
"lookup_results": "@body('Credential_Lookup_-_Look_up_credential_data_for_one_or_more_users')",
"lookup_results_loganalytics_custom_log": "@if(equals(triggerBody()?['lookup_results_loganalytics_custom_log'], null), variables('lookup_results_loganalytics_custom_log'), triggerBody()?['lookup_results_loganalytics_custom_log'])",
"parameters_passed": {
"lookup_lookback_range": "@triggerBody()?['lookup_lookback_range']",
"lookup_results_loganalytics_custom_log": "@triggerBody()?['lookup_results_loganalytics_custom_log']",
"risky_user_email": "@triggerBody()?['risky_user_email']"
}
},
"status": "Successfully saved risky user lookup results into LogAnalytics table."
},
"headers": {
"Content-Type": "application/json"
},
"schema": {
"properties": {
"data": {
"properties": {
"lookup_lookback_date": {
"type": "string"
},
"lookup_results": {
"properties": {},
"type": "object"
},
"lookup_results_loganalytics_custom_log": {
"type": "string"
},
"parameters_passed": {
"properties": {
"lookup_lookback_range": {
"type": "integer"
},
"lookup_results_loganalytics_custom_log": {
"type": "string"
},
"risky_user_email": {
"type": "string"
}
},
"type": "object"
}
},
"type": "object"
},
"status": {
"type": "string"
}
},
"type": "object"
},
"statusCode": 200
}
},
"Send_Data_-_Save_Lookup_results_to_LogAnalytics_Custom_Log": {
"runAfter": {
"Credential_Lookup_-_Look_up_credential_data_for_one_or_more_users": [
"Succeeded"
]
},
"type": "ApiConnection",
"inputs": {
"body": "@{body('Credential_Lookup_-_Look_up_credential_data_for_one_or_more_users')}",
"headers": {
"Log-Type": "@{if(equals(triggerBody()?['lookup_results_loganalytics_custom_log'], null), variables('lookup_results_loganalytics_custom_log'), triggerBody()?['lookup_results_loganalytics_custom_log'])}",
"time-generated-field": "@{utcNow()}"
},
"host": {
"connection": {
"name": "@parameters('$connections')['azureloganalyticsdatacollector']['connectionId']"
}
},
"method": "post",
"path": "/api/logs"
}
}
},
"outputs": {}
},
"parameters": {
"$connections": {
"value": {
"azureloganalyticsdatacollector": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('LogAnalyticsDataCollectorConnectionName'))]",
"connectionName": "[variables('LogAnalyticsDataCollectorConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureloganalyticsdatacollector')]"
},
"recordedfutureidenti": {
"connectionId": "[resourceId('Microsoft.Web/connections', variables('RecordedFutureIdentityConnectionName'))]",
"connectionName": "[variables('RecordedFutureIdentityConnectionName')]",
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/recordedfutureidenti')]"
}
}
}
}
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('LogAnalyticsDataCollectorConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azureloganalyticsdatacollector')]"
},
"displayName": "[variables('LogAnalyticsDataCollectorConnectionName')]"
}
},
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"name": "[variables('RecordedFutureIdentityConnectionName')]",
"location": "[resourceGroup().location]",
"properties": {
"api": {
"id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/recordedfutureidenti')]"
},
"displayName": "[variables('RecordedFutureIdentityConnectionName')]"
}
}
]
}

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

@ -4,22 +4,22 @@
# Recorded Future Identity Solution
Recorded Future Identity Intelligence enables security and IT teams to detect identity compromises, for both employees and customers.
Recorded Future Identity Intelligence enables security and IT teams to detect identity compromises.
To do this, Recorded Future automates the collection, analysis, and production of identity intelligence from a vast range of sources.
Recorded Future automates the collection, analysis, and production of identity intelligence from a vast range of sources.
Organizations can incorporate identity intelligence into automated workflows that regularly monitor for compromised credentials and take immediate action with applications such as Azure Active Directory and Microsoft Sentinel.
You can incorporate identity intelligence into automated workflows that regularly monitor for compromised credentials and take immediate action using Recorded Future Identity data and Microsoft Entra ID.
There are many ways organizations can utilize Recorded Future Identity Intelligence; the playbooks in this Solution are just a quick introduction to some of those ways.
There are many ways organizations can utilize Recorded Future Identity Intelligence. The Azure Logic Apps in this Solution provided as exampes and are a quick introduction to some of those ways.
In particular, these playbooks include several actions that can be coordinated, or used separately.
These playbooks include several actions that can be coordinated, or used separately.
They include:
1. searches for compromised workforce or external customer users
2. looking up existing users and saving the compromised user data to a Log file
3. confirming high risk Azure Active Directory (AAD) users
4. adding a compromised user to an AAD security group
3. confirming high risk Microsoft Entra ID (EntraID) users
4. adding a compromised user to an EntraID security group
<br />
@ -52,21 +52,18 @@ Possible remediations include requiring a password reset, or temporarily locking
1) [Overview](#overview)
2) [Playbooks](#playbooks)
1) ["Base" playbooks (Workforce and External)](#base_playbooks)
2) ["Reactive" playbooks](#reactive_playbooks)
2) ["Search" playbooks](#search_playbooks)
1) [Add risky user to Active Directory Security Group](#add_risky_user_to_active_directory_security_group)
2) [Active Directory Identity Protection - confirm user is compromised](#active_directory_identity_protection_confirm_user_is_compromised)
3) [Lookup risky user and save results](#lookup_risky_user_and_save_results)
3) [Deployment](#deployment)
1) [Prerequisites](#prerequisites)
2) [Deployment using Azure Marketplace](#deployment_azure_marketplace)
3) [Deployment using "Deploy a custom template" service](#deployment_custom_template)
1) [Deploy the Solution](#deployment_custom_template_solution)
1) [Prerequisites](#prerequisites)
2) [Deploy Playbooks (Logic Apps) one by one](#deployment_custom_template_playbooks)
1) [RecordedFutureIdentity-add-AAD-security-group-user](#deployment_custom_template_playbooks_add_AAD_security_group_user)
2) [RecordedFutureIdentity-confirm-AAD-risky-user](#deployment_custom_template_playbooks_confirm_AAD_risky_user)
3) [RecordedFutureIdentity-lookup-and-save-user](#deployment_custom_template_playbooks_lookup_and_save_user)
4) [RecordedFutureIdentity-search-workforce-user](#deployment_custom_template_playbooks_search_workforce_user)
5) [RecordedFutureIdentity-search-external-user](#deployment_custom_template_playbooks_search_external_user)
1) [RFI-add-EntraID-security-group-user](#deployment_custom_template_playbooks_add_EntraID_security_group_user)
2) [RFI-confirm-EntraID-risky-user](#deployment_custom_template_playbooks_confirm_EntraID_risky_user)
3) [RFI-lookup-and-save-user](#deployment_custom_template_playbooks_lookup_and_save_user)
4) [RFI-search-workforce-user](#deployment_custom_template_playbooks_search_workforce_user)
5) [RFI-search-external-user](#deployment_custom_template_playbooks_search_external_user)
4) [How to configure playbooks](#configuration)
1) [How to find the playbooks (Logic Apps) after deployment](#find_playbooks_after_deployment)
2) [Configuring Logic Apps Connections](#configuration_connections)
@ -88,19 +85,20 @@ This Solution consists of 5 Playbooks (Logic Apps).
| Playbook Name | Description |
|---------------------------------------------------|-------------------------------------------|
| **RecordedFutureIdentity-search-workforce-user** | Search new exposures for Workforce users. |
| **RecordedFutureIdentity-search-external-user** | Search new exposures for External users. |
| **RFI-search-workforce-user** | Search new exposures for Workforce users. |
| **RFI-search-external-user** | Search new exposures for External users. |
<br/>
"Reactive" playbooks:
"Search" playbooks:
Theese are sub playbooks that are called by the base playbooks.
| Playbook Name | Description |
|--------------------------------------------------------|----------------------------------------------------------------------------------------|
| **RecordedFutureIdentity-add-AAD-security-group-user** | Add risky user to Active Directory Security Group for users at risk. |
| **RecordedFutureIdentity-confirm-AAD-risky-user** | Confirm to Active Directory Identity Protection that user is compromised. |
| **RecordedFutureIdentity-lookup-and-save-user** | Lookup additional information on a compromised user and save results to Log Analytics. |
| **RFI-add-EntraID-security-group-user** | Add risky user to Active Directory Security Group for users at risk. |
| **RFI-confirm-EntraID-risky-user** | Confirm to Active Directory Identity Protection that user is compromised. |
| **RFI-lookup-and-save-user** | Lookup additional information on a compromised user and save results to Log Analytics. |
<a id="playbooks"></a>
@ -126,11 +124,11 @@ Those playbooks search the Recorded Future Identity Intelligence Module for comp
| 2 | Pull previously seen/saved leaks data from Log Analytics Custom Log. |
| 3 | Compare data from step 1 and step 2 - to determine which leaks are new and haven't been seen previously by the Base Logic App. |
| 4 | Save the new leaks from step 3, so on the next run of the Base Logic App we would get that data on step 2. |
| 5 | Use "Reactive" Logic Apps to react / take actions on the newly leaked credentials. |
| 5 | Use "Search" Logic Apps to react / take actions on the newly leaked credentials. |
<br/>
If you are using External use case - you will get info on your clients leaks, so probably the most valuable "reactive" Logic App for you will be "Lookup risky user and save results", as "Add risky user to Active Directory Security Group" and "Active Directory Identity Protection - confirm user is compromised" assumes that the leaked email is a user in your organization Azure Active Directory, which is mostly probably not true for External use case.
If you are using External use case - you will get info on your clients leaks, so probably the most valuable "Search" Logic App for you will be "Lookup risky user and save results", as "Add risky user to Active Directory Security Group" and "Active Directory Identity Protection - confirm user is compromised" assumes that the leaked email is a user in your organization Microsoft Entra ID, which is mostly probably not true for External use case.
<br/>
@ -147,7 +145,7 @@ Logic App Parameters for Base Logic App Workforce use case:
| **active_directory_security_group_id** | ID of Active Directory Security Group for users at risk. You need to pre-create it by hand: search for "Groups" in Service search at the top of the page. For more information, see [Active Directory Security Groups](https://docs.microsoft.com/windows/security/identity-protection/access-control/active-directory-security-groups) documentation. |
| **lookup_lookback_days** | Time range for Lookup / number of days before today to search (e.g. input "-14" to search the last 14 days). **Make sure to use `lookup_lookback_days` same or larger than `search_lookback_days`. Otherwise you can encounter a situation when you get empty results on Lookup for the compromised credentials from the Search.** |
| **lookup_results_log_analytics_custom_log_name** | Name for Log Analytics Custom Log to save Lookup results at (**needs to end with "`_CL`"**). |
| **active_directory_domain** | (Optional, can be left empty) - in case your Active Directory domain is different from your organization domain, this parameter will be used to transform compromised credentials to find corresponding user in your Active Directory (ex. Compromised email: leaked@mycompany.com, your Active Directory domain: `@mycompany.onmicrosoft.com`, so you set parameter `active_directory_domain = mycompany.onmicrosoft.com` (**just domain, without "@"**), and reactive playbooks will replace the domain from the leaked email with the provided domain from the active_directory_domain parameter, before searching for the corresponding user in your Active Directory: `leaked@mycompany.com -> leaked@mycompany.onmicrosoft.com`. (Lookup playbook - will still use the original email to Lookup the data). |
| **active_directory_domain** | (Optional, can be left empty) - in case your Active Directory domain is different from your organization domain, this parameter will be used to transform compromised credentials to find corresponding user in your Active Directory (ex. Compromised email: leaked@mycompany.com, your Active Directory domain: `@mycompany.onmicrosoft.com`, so you set parameter `active_directory_domain = mycompany.onmicrosoft.com` (**just domain, without "@"**), and search playbooks will replace the domain from the leaked email with the provided domain from the active_directory_domain parameter, before searching for the corresponding user in your Active Directory: `leaked@mycompany.com -> leaked@mycompany.onmicrosoft.com`. (Lookup playbook - will still use the original email to Lookup the data). |
<br/>
@ -155,21 +153,21 @@ Logic App Parameters for Base Logic App "External use case" are the same as for
<br/>
<a id="reactive_playbooks"></a>
<a id="search_playbooks"></a>
### "Reactive" playbooks
### "Search" playbooks
<br/>
"Reactive" playbooks can be used to react to leaked credentials and mitigate the risks.
"Search" playbooks can be used to react to leaked credentials and mitigate the risks.
<br/>
<a id="add_risky_user_to_active_directory_security_group"></a>
#### RecordedFutureIdentity-add-AAD-security-group-user
#### RFI-add-EntraID-security-group-user
This playbook adds a compromised user to an AAD security group. Triage and remediation should be handled in follow up playbooks or actions.
This playbook adds a compromised user to an EntraID security group. Triage and remediation should be handled in follow up playbooks or actions.
By applying security policies to the security group and adding leaked users to that group - you can react to a leak and mitigate the risks.
@ -198,18 +196,20 @@ HTTP request parameters:
|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **risky_user_email** | Compromised user email. |
| **active_directory_security_group_id** | ID of Active Directory Security Group for users at risk. You need to pre-create security group by hand: search for "Groups" in Service search at the top of the page. For more information, see [Active Directory Security Groups](https://docs.microsoft.com/windows/security/identity-protection/access-control/active-directory-security-groups) documentation. |
| **active_directory_domain** | (Optional, can be left empty) - in case your Active Directory domain is different from your organization domain, this parameter will be used to transform compromised credentials to find corresponding user in your Active Directory (ex. Compromised email: leaked@mycompany.com, your Active Directory domain: `@mycompany.onmicrosoft.com`, so you set parameter `active_directory_domain = mycompany.onmicrosoft.com` (**just domain, without "@"**), and reactive playbooks will replace the domain from the leaked email with the provided domain from the active_directory_domain parameter, before searching for the corresponding user in your Active Directory: `leaked@mycompany.com -> leaked@mycompany.onmicrosoft.com`. (Lookup playbook - will still use the original email to Lookup the data). |
| **active_directory_domain** | (Optional, can be left empty) - in case your Active Directory domain is different from your organization domain, this parameter will be used to transform compromised credentials to find corresponding user in your Active Directory (ex. Compromised email: leaked@mycompany.com, your Active Directory domain: `@mycompany.onmicrosoft.com`, so you set parameter `active_directory_domain = mycompany.onmicrosoft.com` (**just domain, without "@"**), and search playbooks will replace the domain from the leaked email with the provided domain from the active_directory_domain parameter, before searching for the corresponding user in your Active Directory: `leaked@mycompany.com -> leaked@mycompany.onmicrosoft.com`. (Lookup playbook - will still use the original email to Lookup the data). |
<br/>
<a id="active_directory_identity_protection_confirm_user_is_compromised"></a>
#### RecordedFutureIdentity-confirm-AAD-risky-user
#### RFI-confirm-EntraID-risky-user
This playbook confirms compromise of users deemed "high risk" by Azure Active Directory Identity Protection.
This playbook confirms compromise of users deemed "high risk" by Microsoft Entra ID Protection.
More on Active Directory Identity Protection you can read here: [link1](https://docs.microsoft.com/azure/active-directory/identity-protection/) and [link2](https://docs.microsoft.com/azure/active-directory/identity-protection/overview-identity-protection) and [link3](https://docs.microsoft.com/azure/active-directory/identity-protection/howto-identity-protection-remediate-unblock).
For more info on Entra ID Protection, read here: [link1](https://learn.microsoft.com/en-gb/entra/id-protection/) and [link2](https://learn.microsoft.com/en-gb/entra/id-protection/overview-identity-protection) and [link3](https://learn.microsoft.com/en-gb/entra/id-protection/howto-identity-protection-remediate-unblock).
Note that this playbook only runs on already flagged risky users. If a user isn't flagged as a risky user by Entra ID Protection, this playbook won't do anything.
<br/>
@ -232,14 +232,14 @@ HTTP request parameters:
| Parameter | Description |
|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **risky_user_email** | Compromised user email. |
| **active_directory_domain** | (Optional, can be left empty) - in case your Active Directory domain is different from your organization domain, this parameter will be used to transform compromised credentials to find corresponding user in your Active Directory (ex. Compromised email: leaked@mycompany.com, your Active Directory domain: `@mycompany.onmicrosoft.com`, so you set parameter `active_directory_domain = mycompany.onmicrosoft.com` (**just domain, without "@"**), and reactive playbooks will replace the domain from the leaked email with the provided domain from the active_directory_domain parameter, before searching for the corresponding user in your Active Directory: `leaked@mycompany.com -> leaked@mycompany.onmicrosoft.com`. (Lookup playbook - will still use the original email to Lookup the data). |
| **active_directory_domain** | (Optional, can be left empty) - in case your Active Directory domain is different from your organization domain, this parameter will be used to transform compromised credentials to find corresponding user in your Active Directory (ex. Compromised email: leaked@mycompany.com, your Active Directory domain: `@mycompany.onmicrosoft.com`, so you set parameter `active_directory_domain = mycompany.onmicrosoft.com` (**just domain, without "@"**), and search playbooks will replace the domain from the leaked email with the provided domain from the active_directory_domain parameter, before searching for the corresponding user in your Active Directory: `leaked@mycompany.com -> leaked@mycompany.onmicrosoft.com`. (Lookup playbook - will still use the original email to Lookup the data). |
<br/>
<a id="lookup_risky_user_and_save_results"></a>
#### RecordedFutureIdentity-lookup-and-save-user
#### RFI-lookup-and-save-user
This playbook gets compromise identity details from Recorded Future Identity Intelligence and saves the data for further review and analysis.
@ -283,7 +283,7 @@ Logic App Parameters:
If you use this playbook to Lookup leaks info for an email and response lookup data is empty (for specified email and lookback range) - the playbook will still save empty results to the Log Analytics Custom Log.
This case is possible if you set up the Logic Apps in that way that Lookup lookback range (in `RecordedFutureIdentity-lookup-and-save-user` playbook) is smaller than Search lookback range (in `RecordedFutureIdentity-search-workforce-user` and `RecordedFutureIdentity-search-external-user` playbooks).
This case is possible if you set up the Logic Apps in that way that Lookup lookback range (in `RFI-lookup-and-save-user` playbook) is smaller than Search lookback range (in `RFI-search-workforce-user` and `RFI-search-external-user` playbooks).
In that case you will see some empty records in the corresponding Log Analytics Custom Log (see the screenshot).
@ -292,7 +292,7 @@ In that case you will see some empty records in the corresponding Log Analytics
To mitigate this case: make sure you set up the Lookup lookback range equal to or larger than the Search lookback range.
Another way to cover this case - you can add a corresponding check to RecordedFutureIdentity-lookup-and-save-user playbook and not save the results to Log Analytics if the result is empty.
Another way to cover this case - you can add a corresponding check to RFI-lookup-and-save-user playbook and not save the results to Log Analytics if the result is empty.
@ -300,182 +300,40 @@ Another way to cover this case - you can add a corresponding check to RecordedFu
## Deployment
There is several ways you can deploy this Solution:
- Deployment of complete Solution from Azure Marketplace
- Using ["Deploy a Custom template"](https://portal.azure.com/#create/Microsoft.Template)
- Deploy the Solution (one step to deploy all resources in the Solution)
- Deploy each playbook one by one
**Important:**
- **Make sure you deploy all 3 "Reactive" playbooks before deploying "Base" playbooks. And make sure you configure all 3 "Reactive" playbooks before running "Base" playbooks.**
- **Make sure to specify correct "Reactive" playbook names while deploying "Base" playbooks.** "Correct" - are just the same as you have used while deploying "Reactive" playbooks.
> [!IMPORTANT]
> Make sure you deploy all "Base" playbooks before deploying any of the "search" playbooks. And make sure you configure all 3 base playbooks before running "RFI-search..." playbooks.
> Make sure to specify correct playbook names while deploying "search" playbooks.** "Correct" - are just the same as you have used while deploying playbooks.
<a id="prerequisites"></a>
### Prerequisites
- An Azure account and subscription. If you don't have a subscription, [sign up for a free Azure account](https://azure.microsoft.com/free/?WT.mc_id=A261C142F).
- Azure subscription Owner or Contributor permissions so you can install the Logic Apps Management solution from the Azure Marketplace. For more information, review [Permission to purchase - Azure Marketplace purchasing](https://docs.microsoft.com/marketplace/azure-purchasing-invoicing#permission-to-purchase) and [Azure roles - Classic subscription administrator roles, Azure roles, and Azure AD roles](https://docs.microsoft.com/azure/role-based-access-control/rbac-and-directory-admin-roles#azure-roles).
- An Entra ID Tenant and subscription. If you don't have a subscription, [sign up for a free Azure account](https://azure.microsoft.com/free/?WT.mc_id=A261C142F).
- Azure subscription Owner or Contributor permissions so you can install the Logic Apps Management solution from the Azure Marketplace. For more information, review [Permission to purchase - Azure Marketplace purchasing](https://docs.microsoft.com/marketplace/azure-purchasing-invoicing#permission-to-purchase) and [Azure roles - Classic subscription administrator roles, Azure roles, and Entra ID roles](https://docs.microsoft.com/azure/role-based-access-control/rbac-and-directory-admin-roles#azure-roles).
- A [Log Analytics workspace](https://docs.microsoft.com/azure/azure-monitor/essentials/resource-logs#send-to-log-analytics-workspace). If you don't have a workspace, learn [how to create a Log Analytics workspace](https://docs.microsoft.com/azure/azure-monitor/logs/quick-create-workspace). Note that the custom logs specified as parameters in these playbooks will be created automatically if they dont already exist.
- In Consumption logic apps, before you can create or manage logic apps and their connections, you need specific permissions. For more information about these permissions, review [Secure operations - Secure access and data in Azure Logic Apps](https://docs.microsoft.com/azure/logic-apps/logic-apps-securing-a-logic-app#secure-operations).
- For `Recorded Future Identity` Connections you will need `Recorded Future Identity API` token. To obtain one - check out [this section](#how_to_obtain_Recorded_Future_API_token).
<a id="deployment_azure_marketplace"></a>
### Deployment using [Azure Marketplace](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/)
1) Open Recorded Future Identity Solution page in Azure Marketplace in one of two ways:
1) Use the direct link to [Recorded Future Identity Solution](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/recordedfuture1605638642586.recorded_future_identity_solution).
1) Open [Azure Marketplace](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/). Search for "Recorded Future Identity Solution".
1) On the Recorded Future Identity Solution page click "Create".
1) Follow the installation process as described below.
Parameters for deployment:
| Parameter | Description |
|--------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
| **Workspace** | Log Analytics Workspace name. |
| **Playbook Name for "Add ADD security group user" playbook** | Playbook name to use for "RecordedFutureIdentity-add-AAD-security-group-user" playbook. |
| **Playbook Name for "Confirm AAD risky user" playbook** | Playbook name to use for "RecordedFutureIdentity-confirm-AAD-risky-user" playbook. |
| **Playbook Name for "Lookup and save user" playbook** | Playbook name to use for "RecordedFutureIdentity-lookup-and-save-user" playbook. |
| **Playbook Name for "Search workforce user" playbook** | Playbook name to use for "RecordedFutureIdentity-search-workforce-user" playbook. |
| **Playbook Name for "Search external user" playbook** | Playbook name to use for "RecordedFutureIdentity-search-external-user" playbook. |
<br/>
<img src="./images/microsoft_sentinel_4.png" alt="Microsoft Sentinel Content Hub Installation #4" width="60%"/>
<img src="./images/microsoft_sentinel_5.png" alt="Microsoft Sentinel Content Hub Installation #5" width="60%"/>
<img src="./images/microsoft_sentinel_6.png" alt="Microsoft Sentinel Content Hub Installation #6" width="60%"/>
<br/>
At the end it should look like this:
<img src="./images/microsoft_sentinel_7.png" alt="Microsoft Sentinel Content Hub Installation #6" width="60%"/>
<img src="./images/microsoft_sentinel_8.png" alt="Microsoft Sentinel Content Hub Installation #6" width="60%"/>
<br/>
<br/>
<a id="deployment_custom_template"></a>
### Deployment using "Deploy a custom template" service
You can deploy resources (Solution, Playbooks, etc) from templates using `Deploy a custom template` service.
<br/>
**Important:**
- **Make sure you deploy all 3 "Reactive" playbooks before deploying "Base" playbooks. And make sure you configure all 3 "Reactive" playbooks before running "Base" playbooks.**
- **Make sure to specify correct "Reactive" playbook names while deploying "Base" playbooks.** "Correct" - are just the same as you have used while deploying "Reactive" playbooks.
<br/>
**! If you decided deploy the Solution using `Deploy a custom template` service - THE EASIEST WAY TO DEPLOY templates of the current Solution - just by using corresponding `Deploy to Azure` ![Deploy to Azure](https://aka.ms/deploytoazurebutton) button or `Deploy to Azure Gov` ![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton) buttons in the next sections.**
<br/>
You can find `Deploy a custom template` service using search on [Azure portal home page](https://portal.azure.com).
Here is how icons for this service looks:
<img src="./images/deploy_custom_template_service_icon_1.png" alt="Deploy a Custom Template Icon #1" width="70px"/>
<img src="./images/deploy_custom_template_service_icon_2.png" alt="Deploy a Custom Template Icon #2" width="170px"/>
<img src="./images/deploy_custom_template_service_icon_3.png" alt="Deploy a Custom Template Icon #3" width="250px"/>
<br/>
<br/>
Here is the interface and short usage tutorial:
<img src="./images/deploy_custom_template_service_1.png" alt="Deploy a Custom Template Installation #1" width="60%"/>
You can click on `Build your own template in the editor` button.
There you can paste any template to deploy:
<img src="./images/deploy_custom_template_service_2.png" alt="Deploy a Custom Template Installation #2" width="60%"/>
<br/>
"Templates" - are just content of corresponding files. For example:
- use content of [../Package/mainTemplate.json](../Package/mainTemplate.json) file to deploy this whole Solution (all in one).
- or use content of [./RecordedFutureIdentity-add-AAD-security-group-user.json](./RecordedFutureIdentity-add-AAD-security-group-user.json) file to deploy ONLY `RecordedFutureIdentity-add-AAD-security-group-user` playbook.
After you paste your template to deploy - click `Save` button:
<img src="./images/deploy_custom_template_service_3.png" alt="Deploy a Custom Template Installation #3" width="60%"/>
Regarding next steps specific parameters descriptions - check out a corresponding section below for your specific template deployment (as each template have its own deployment parameters).
But in general, next steps will look like this:
<img src="./images/deploy_custom_template_service_4.png" alt="Deploy a Custom Template Installation #4" width="60%"/>
<img src="./images/deploy_custom_template_service_5.png" alt="Deploy a Custom Template Installation #4" width="60%"/>
<img src="./images/after_solution_deployed_1.png" alt="Deploy a Custom Template Installation #4" width="60%"/>
<img src="./images/after_solution_deployed_2.png" alt="Deploy a Custom Template Installation #4" width="60%"/>
<br/>
<br/>
<a id="deployment_custom_template_solution"></a>
#### Deploy the Solution (all in one step)
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPackage%2FmainTemplate.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPackage%2FmainTemplate.json)
Parameters for deployment:
| Parameter | Description |
|-----------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
| **Region** | Choose the Azure region that's right for you and your customers. Not every resource is available in every region. |
| **Location** | Not used. Leave default value. |
| **Workspace-location** | Region in which your Log Analytics Workspace is deployed (ex. "`eastus`" - for East US). |
| **Workspace** | Log Analytics Workspace name. |
| **Playbook-Name-add-AAD-security-group-user** | Playbook name to use for "RecordedFutureIdentity-add-AAD-security-group-user" playbook. |
| **Playbook-Name-confirm-AAD-risky-user** | Playbook name to use for "RecordedFutureIdentity-confirm-AAD-risky-user" playbook. |
| **Playbook-Name-lookup-and-save-user** | Playbook name to use for "RecordedFutureIdentity-lookup-and-save-user" playbook. |
| **Playbook-Name-search-workforce-user** | Playbook name to use for "RecordedFutureIdentity-search-workforce-user" playbook. |
| **Playbook-Name-search-external-user** | Playbook name to use for "RecordedFutureIdentity-search-external-user" playbook. |
<br/>
<a id="deployment_custom_template_playbooks"></a>
#### Deploy Playbooks one by one
Important:
- **Make sure you deploy all 3 "Reactive" playbooks before deploying "Base" playbooks. And make sure you configure all 3 "Reactive" playbooks before running "Base" playbooks.**
- **Make sure to specify correct "Reactive" playbook names while deploying "Base" playbooks.** "Correct" - are just the same as you have used while deploying "Reactive" playbooks.
> [!IMPORTANT]
> Make sure you deploy all "Base" playbooks before deploying any of the "search" playbooks. And make sure you configure all 3 base playbooks before running "RFI-search..." playbooks.
> Make sure to specify correct playbook names while deploying "search" playbooks.** "Correct" - are just the same as you have used while deploying playbooks.
<a id="deployment_custom_template_playbooks_add_EntraID_security_group_user"></a>
<br/>
##### RecordedFuture-CustomConnector
Logic-app custom connector\
<a id="deployment_custom_template_playbooks_add_AAD_security_group_user"></a>
This connector is used by other logic apps in this solution to comunicate with Recorded Future backend API.
##### RecordedFutureIdentity-add-AAD-security-group-user
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRecordedFutureIdentity-add-AAD-security-group-user.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRecordedFutureIdentity-add-AAD-security-group-user.json)
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-CustomConnector-0-1-0%2Fazuredeploy.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-CustomConnector-0-1-0%2Fazuredeploy.json)
Parameters for deployment:
@ -484,17 +342,14 @@ Parameters for deployment:
| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
| **Region** | Choose the Azure region that's right for you and your customers. Not every resource is available in every region. |
| **Playbook-Name** | Playbook name to use for this playbook (ex. "RecordedFutureIdentity-add-AAD-security-group-user"). |
| **Connector-Name** | Connector name to use for this playbook (ex. "RFI-CustomConnector-0-1-0"). |
|**Service Endpoint**| API Endpoint, always use the default ```https://api.recordedfuture.com/gw/azure-identity```|
<br/>
##### RFI-add-EntraID-security-group-user
<a id="deployment_custom_template_playbooks_confirm_AAD_risky_user"></a>
##### RecordedFutureIdentity-confirm-AAD-risky-user
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRecordedFutureIdentity-confirm-AAD-risky-user.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRecordedFutureIdentity-confirm-AAD-risky-user.json)
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-add-EntraID-security-group-user%2Fazuredeploy.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-add-EntraID-security-group-user%2Fazuredeploy.json)
Parameters for deployment:
@ -503,17 +358,36 @@ Parameters for deployment:
| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
| **Region** | Choose the Azure region that's right for you and your customers. Not every resource is available in every region. |
| **Playbook-Name** | Playbook name to use for this playbook (ex. "RecordedFutureIdentity-confirm-AAD-risky-user"). |
| **Playbook-Name** | Playbook name to use for this playbook (ex. "RFI-add-EntraID-security-group-user"). |
<br/>
<a id="deployment_custom_template_playbooks_confirm_EntraID_risky_user"></a>
##### RFI-confirm-EntraID-risky-user
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-confirm-EntraID-risky-user%2Fazuredeploy.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-confirm-EntraID-risky-user%2Fazuredeploy.json)
Parameters for deployment:
| Parameter | Description |
|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
| **Region** | Choose the Azure region that's right for you and your customers. Not every resource is available in every region. |
| **Playbook-Name** | Playbook name to use for this playbook (ex. "RFI-confirm-EntraID-risky-user"). |
<br/>
<a id="deployment_custom_template_playbooks_lookup_and_save_user"></a>
##### RecordedFutureIdentity-lookup-and-save-user
##### RFI-lookup-and-save-user
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRecordedFutureIdentity-lookup-and-save-user.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRecordedFutureIdentity-lookup-and-save-user.json)
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-lookup-and-save-user%2Fazuredeploy.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-lookup-and-save-user%2Fazuredeploy.json)
Parameters for deployment:
@ -522,17 +396,17 @@ Parameters for deployment:
| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
| **Region** | Choose the Azure region that's right for you and your customers. Not every resource is available in every region. |
| **Playbook-Name** | Playbook name to use for this playbook (ex. "RecordedFutureIdentity-lookup-and-save-user"). |
| **Playbook-Name** | Playbook name to use for this playbook (ex. "RFI-lookup-and-save-user"). |
<br/>
<a id="deployment_custom_template_playbooks_search_workforce_user"></a>
##### RecordedFutureIdentity-search-workforce-user
##### RFI-search-workforce-user
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRecordedFutureIdentity-search-workforce-user.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRecordedFutureIdentity-search-workforce-user.json)
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-search-workforce-user%2Fazuredeploy.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-search-workforce-user%2Fazuredeploy.json)
Parameters for deployment:
@ -541,20 +415,20 @@ Parameters for deployment:
| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
| **Region** | Choose the Azure region that's right for you and your customers. Not every resource is available in every region. |
| **Playbook-Name** | Playbook name to use for this playbook (ex. "RecordedFutureIdentity-search-workforce-user"). |
| **Playbook-Name-add-AAD-security-group-user** | Playbook name to use for "RecordedFutureIdentity-add-AAD-security-group-user" playbook. |
| **Playbook-Name-confirm-AAD-risky-user** | Playbook name to use for "RecordedFutureIdentity-confirm-AAD-risky-user" playbook. |
| **Playbook-Name-lookup-and-save-user** | Playbook name to use for "RecordedFutureIdentity-lookup-and-save-user" playbook. |
| **Playbook-Name** | Playbook name to use for this playbook (ex. "RFI-search-workforce-user"). |
| **Playbook-Name-add-EntraID-security-group-user** | Playbook name to use for "RFI-add-EntraID-security-group-user" playbook. |
| **Playbook-Name-confirm-EntraID-risky-user** | Playbook name to use for "RFI-confirm-EntraID-risky-user" playbook. |
| **Playbook-Name-lookup-and-save-user** | Playbook name to use for "RFI-lookup-and-save-user" playbook. |
<br/>
<a id="deployment_custom_template_playbooks_search_external_user"></a>
##### RecordedFutureIdentity-search-external-user
##### RFI-search-external-user
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRecordedFutureIdentity-search-external-user.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRecordedFutureIdentity-search-external-user.json)
[![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%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-search-external-user%2Fazuredeploy.json)
[![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FSolutions%2FRecorded%20Future%20Identity%2FPlaybooks%2FRFI-search-external-user%2Fazuredeploy.json)
Parameters for deployment:
@ -563,10 +437,10 @@ Parameters for deployment:
| **Subscription** | Your Azure Subscription to deploy the Solution in. All resources in an Azure subscription are billed together. |
| **Resource group** | Resource group in your Subscription to deploy the Solution in. A resource group is a collection of resources that share the same lifecycle, permissions, and policies. |
| **Region** | Choose the Azure region that's right for you and your customers. Not every resource is available in every region. |
| **Playbook-Name** | Playbook name to use for this playbook (ex. "RecordedFutureIdentity-search-external-user"). |
| **Playbook-Name-add-AAD-security-group-user** | Playbook name to use for "RecordedFutureIdentity-add-AAD-security-group-user" playbook. |
| **Playbook-Name-confirm-AAD-risky-user** | Playbook name to use for "RecordedFutureIdentity-confirm-AAD-risky-user" playbook. |
| **Playbook-Name-lookup-and-save-user** | Playbook name to use for "RecordedFutureIdentity-lookup-and-save-user" playbook. |
| **Playbook-Name** | Playbook name to use for this playbook (ex. "RFI-search-external-user"). |
| **Playbook-Name-add-EntraID-security-group-user** | Playbook name to use for "RFI-add-EntraID-security-group-user" playbook. |
| **Playbook-Name-confirm-EntraID-risky-user** | Playbook name to use for "RFI-confirm-EntraID-risky-user" playbook. |
| **Playbook-Name-lookup-and-save-user** | Playbook name to use for "RFI-lookup-and-save-user" playbook. |
<br/>
@ -588,8 +462,8 @@ After deployment - initial set up for each deployed Logic App (playbook) include
<br/>
**Important:**
- **Make sure you deploy all 3 "Reactive" playbooks before deploying "Base" playbooks. And make sure you configure all 3 "Reactive" playbooks before running "Base" playbooks.**
- **Make sure to specify correct "Reactive" playbook names while deploying "Base" playbooks.** "Correct" - are just the same as you have used while deploying "Reactive" playbooks.
- **Make sure you deploy all 3 "Search" playbooks before deploying "Base" playbooks. And make sure you configure all 3 "Search" playbooks before running "Base" playbooks.**
- **Make sure to specify correct "Search" playbook names while deploying "Base" playbooks.** "Correct" - are just the same as you have used while deploying "Search" playbooks.
- **Make sure to use `lookup_lookback_days` same or larger than `search_lookback_days`. Otherwise you can encounter a situation when you get empty results on Lookup for the compromised credentials from the Search.**
<br/>
@ -682,7 +556,7 @@ Permissions / Roles:
## How to obtain Recorded Future API token
Recorded Future clients interested in API access for custom scripts or to enable a paid integration can request an API Token via this Integration Support Ticket form. Please fill out the following fields, based on intended API usage.
Recorded Future clients interested in API access for custom scripts or to enable a paid integration can request an API Token via this [Integration Support Ticket form](https://support.recordedfuture.com/hc/en-us/articles/4411077373587-Requesting-API-Tokens). Please fill out the following fields, based on intended API usage.
Recorded Future API Services - Choose if your token is pertaining to one of the below Recorded Future API offerings:
- Connect API

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

@ -0,0 +1,4 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
|-------------|--------------------------------|---------------------------------------------|
| 3.0.0 | 15-04-2024 | Fixedhardcoded SubscriptionID.<br> Entra ID renaming of **Playbooks** and readme.<br> Using solution format V3<br>Change prefix on all logic app installation names from RecordedFutureIdentity to RFI due to logic app name size limitation of 64 characters. |
| 2.0.0 | 14-09-2022 | Initial Solution Release |