briandelmsft / SentinelAutomationModules

The Microsoft Sentinel Triage AssistanT (STAT) enables easy to create incident triage automation in Microsoft Sentinel
MIT License
201 stars 55 forks source link

Run playbook module error 400 bad request #427

Closed BlydCL closed 11 months ago

BlydCL commented 11 months ago

Very impressed with V2! I have been trying to use the run playbook module to run the 'prompt user incident' playbook. The grantpermissions.ps1 has been run successfully and Sample-stat-triage playbook has contributor rights on the subscription. I am receiving an 400 bad request error. Do you have any suggestions on how to solve the issue?

Input:

{ "method": "post", "path": "/api/modules/aadrisks", "host": { "connection": { "name": "/subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.Web/connections/stat-deleted" } }, "body": { "AddIncidentComments": true, "AddIncidentTask": true, "BaseModuleBody": { "Accounts": [ { "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users(userPrincipalName,id,onPremisesSecurityIdentifier,onPremisesDistinguishedName,onPremisesDomainName,onPremisesSamAccountName,onPremisesSyncEnabled,mail,city,state,country,department,jobTitle,officeLocation,accountEnabled,manager(userPrincipalName,mail,id))/$entity", "userPrincipalName": "deleted", "id": "deleted", "onPremisesSecurityIdentifier": null, "onPremisesDistinguishedName": null, "onPremisesDomainName": null, "onPremisesSamAccountName": null, "onPremisesSyncEnabled": null, "mail": "deleted", "city": null, "state": null, "country": null, "department": "Cyber Security Consultant", "jobTitle": null, "officeLocation": null, "accountEnabled": true, "AssignedRoles": [ "Global Administrator" ], "isAADPrivileged": true, "isMfaRegistered": true, "isSSPREnabled": true, "isSSPRRegistered": true, "RawEntity": { "accountName": "deleted", "upnSuffix": "deleted", "friendlyName": "deleted" } } ], "AccountsCount": 1, "Alerts": [ { "id": "/subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.OperationalInsights/workspaces/deleted-sentinel-production/providers/Microsoft.SecurityInsights/Entities/deleted", "name": "deleted", "type": "Microsoft.SecurityInsights/Entities", "kind": "SecurityAlert", "properties": { "systemAlertId": "deleted", "tactics": [ "Persistence", "PrivilegeEscalation" ], "alertDisplayName": "User added to Azure Active Directory Privileged Groups", "description": "This will alert when a user is added to any of the Privileged Groups.\nFor further information on AuditLogs please see https://docs.microsoft.com/azure/active-directory/reports-monitoring/reference-audit-activities.\nFor Administrator role permissions in Azure Active Directory please see https://docs.microsoft.com/azure/active-directory/users-groups-roles/directory-assign-admin-roles", "confidenceLevel": "Unknown", "severity": "Medium", "vendorName": "Microsoft", "productName": "Azure Sentinel", "productComponentName": "Scheduled Alerts", "alertType": "5b619b32-8728-46dc-9d14-16613096f2c5_4d94d4a9-dc96-410a-8dea-4d4d4584188b", "processingEndTime": "2023-08-03T10:46:57.8222468Z", "status": "New", "endTimeUtc": "2023-08-03T10:36:42.8416642Z", "startTimeUtc": "2023-08-03T10:36:42.8416642Z", "timeGenerated": "2023-08-03T10:46:57.8789418Z", "providerAlertId": "5013018e-097b-4094-adbb-facb18a23ab1", "resourceIdentifiers": [ { "type": "LogAnalytics", "workspaceId": "deleted" } ], "additionalData": { "ProcessedBySentinel": "True", "Alert generation status": "Full alert created", "Query Period": "01:00:00", "Trigger Operator": "GreaterThan", "Trigger Threshold": "0", "Correlation Id": "deleted", "Search Query Results Overall Count": "1", "Data Sources": "[\"deleted\"]", "Query": "// The query_now parameter represents the time (in UTC) at which the scheduled analytics rule ran to produce this alert.\nset query_now = datetime(2023-08-03T10:41:56.9320000Z);\nlet OperationList = dynamic([\"Add member to role\",\"Add member to role in PIM requested (permanent)\"]);\nlet PrivilegedGroups = dynamic([\"UserAccountAdmins\",\"PrivilegedRoleAdmins\",\"TenantAdmins\"]);\nAuditLogs\n//| where LoggedByService =~ \"Core Directory\"\n| where Category =~ \"RoleManagement\"\n| where OperationName in~ (OperationList)\n| mv-apply TargetResource = TargetResources on \n (\n where TargetResource.type =~ \"User\"\n | extend TargetUserPrincipalName = tostring(TargetResource.userPrincipalName),\n modProps = TargetResource.modifiedProperties\n )\n| mv-apply Property = modProps on \n (\n where Property.displayName =~ \"Role.WellKnownObjectName\"\n | extend DisplayName = trim('\"',tostring(Property.displayName)),\n GroupName = trim('\"',tostring(Property.newValue))\n )\n| extend AppId = InitiatedBy.app.appId,\n InitiatedByDisplayName = case(isnotempty(InitiatedBy.app.displayName), InitiatedBy.app.displayName, isnotempty(InitiatedBy.user.displayName), InitiatedBy.user.displayName, \"not available\"),\n ServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId),\n ServicePrincipalName = tostring(InitiatedBy.app.servicePrincipalName),\n UserId = InitiatedBy.user.id,\n UserIPAddress = InitiatedBy.user.ipAddress,\n UserRoles = InitiatedBy.user.roles,\n UserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)\n| where GroupName in~ (PrivilegedGroups)\n// If you don't want to alert for operations from PIM, remove below filtering for MS-PIM.\n//| where InitiatedByDisplayName != \"MS-PIM\"\n| project TimeGenerated, AADOperationType, Category, OperationName, AADTenantId, AppId, InitiatedByDisplayName, ServicePrincipalId, ServicePrincipalName, DisplayName, GroupName, UserId, UserIPAddress, UserRoles, UserPrincipalName, TargetUserPrincipalName\n| extend AccountCustomEntity = case(isnotempty(ServicePrincipalName), ServicePrincipalName, \n isnotempty(UserPrincipalName), UserPrincipalName, \n \"\")\n| extend AccountName = tostring(split(AccountCustomEntity,'@',0)[0]), AccountUPNSuffix = tostring(split(AccountCustomEntity,'@',1)[0])\n| extend TargetName = tostring(split(TargetUserPrincipalName,'@',0)[0]), TargetUPNSuffix = tostring(split(TargetUserPrincipalName,'@',1)[0])", "Query Start Time UTC": "2023-08-03T09:41:56Z", "Query End Time UTC": "2023-08-03T10:41:57Z", "Analytic Rule Ids": "[\"4d94d4a9-dc96-410a-8dea-4d4d4584188b\"]", "Event Grouping": "SingleAlert", "Analytic Rule Name": "User added to Azure Active Directory Privileged Groups", "Analytics Template Id": "4d94d4a9-dc96-410a-8dea-4d4d4584188b" }, "friendlyName": "User added to Azure Active Directory Privileged Groups" } } ], "Domains": [], "DomainsCount": 0, "EntitiesCount": 1, "FileHashes": [], "FileHashesCount": 0, "Files": [], "FilesCount": 0, "Hosts": [], "HostsCount": 0, "IPs": [], "IPsCount": 0, "IncidentARMId": "/subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.OperationalInsights/workspaces/deleted/providers/Microsoft.SecurityInsights/Incidents/deleted", "IncidentTriggered": true, "IncidentAvailable": true, "ModuleVersions": { "AADRisksModule": "0.1.0", "BaseModule": "0.4.0", "FileModule": "0.1.2", "KQLModule": "0.3.0", "MCASModule": "0.0.8", "MDEModule": "0.2.1", "OOFModule": "0.0.3", "RelatedAlerts": "0.3.0", "RunPlaybook": "0.0.1", "ScoringModule": "0.1.0", "STATConnector": "1.5.0", "STATFunction": "1.5.0", "TIModule": "0.2.0", "UEBAModule": "0.1.1", "WatchlistModule": "0.1.0" }, "MultiTenantConfig": {}, "OtherEntities": [], "OtherEntitiesCount": 0, "RelatedAnalyticRuleIds": [ "/subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.OperationalInsights/workspaces/deleted/providers/Microsoft.SecurityInsights/alertRules/4d94d4a9-dc96-410a-8dea-4d4d4584188b" ], "SentinelRGARMId": "/subscriptions/deleted/resourceGroups/deleted", "TenantDisplayName": "deleted", "TenantId": "deleted", "URLs": [], "URLsCount": 0, "WorkspaceARMId": "/subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.OperationalInsights/workspaces/deleted", "WorkspaceId": "deleted" }, "IncidentTaskInstructions": "Check investigation graph for [{\"id\":\"/subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.OperationalInsights/workspaces/deleted/providers/Microsoft.SecurityInsights/Entities/deleted\",\"name\":\"deleted\",\"type\":\"Microsoft.SecurityInsights/Entities\",\"kind\":\"Account\",\"properties\":{\"accountName\":\"deleted\",\"upnSuffix\":\"deleted\",\"friendlyName\":\"deleted\"}}] related to this incident User added to Azure Active Directory Privileged Groups", "LookbackInDays": 14, "MFAFailureLookup": true, "MFAFraudLookup": true, "SuspiciousActivityReportLookup": true } }

Output:

{ "statusCode": 400, "headers": { "Transfer-Encoding": "chunked", "Request-Context": "appId=cid-v1:5d750880-75fb-4a49-a161-56a7b8fd8a79", "Date": "Thu, 03 Aug 2023 11:28:44 GMT", "Content-Type": "application/json", "Content-Length": "2309" }, "body": { "Error": "The API call to arm with path /subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.OperationalInsights/workspaces/deleted/providers/Microsoft.SecurityInsights/Incidents/deleted/runPlaybook?api-version=2022-07-01-preview failed with status 400", "InvocationId": "deleted", "SourceError": { "status_code": 400, "reason": "Bad Request" }, "Traceback": [ "Traceback (most recent call last):\n", " File \"/home/site/wwwroot/modules/playbook.py\", line 31, in execute_playbook_module\n response = rest.rest_call_post(base_object, api='arm', path=path, body=body)\n", " File \"/home/site/wwwroot/shared/rest.py\", line 106, in rest_call_post\n raise STATError(f'The API call to {api} with path {path} failed with status {response.status_code}', source_error={'status_code': int(response.status_code), 'reason': str(response.reason)})\n", "classes.STATError: The API call to arm with path /subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.OperationalInsights/workspaces/deleted/Microsoft.SecurityInsights/Incidents/deleted/runPlaybook?api-version=2022-07-01-preview failed with status 400\n", "\nDuring handling of the above exception, another exception occurred:\n\n", "Traceback (most recent call last):\n", " File \"/home/site/wwwroot/modules/init.py\", line 19, in main\n return_data = coordinator.initiate_module(module_name=module_name, req_body=req_body)\n", " File \"/home/site/wwwroot/shared/coordinator.py\", line 33, in initiate_module\n return_data = playbook.execute_playbook_module(req_body)\n", " File \"/home/site/wwwroot/modules/playbook.py\", line 35, in execute_playbook_module\n raise STATError(e.error, e.source_error, e.status_code)\n", "classes.STATError: ('The API call to arm with path /subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.OperationalInsights/workspaces/deleted/providers/Microsoft.SecurityInsights/Incidents/deleted/runPlaybook?api-version=2022-07-01-preview failed with status 400', {'status_code': 400, 'reason': 'Bad Request'}, 400)\n" ] } }

piaudonn commented 11 months ago

Thanks @BlydCL for the question! And thanks for the level of details!

@briandelmsft, could it be that the runPlaybook endpoint need a different api-version now? https://learn.microsoft.com/en-us/rest/api/securityinsights/preview/incidents/run-playbook

BlydCL commented 11 months ago

Hi,

Managed to get it working with an HTTP post as in the link you provided.

Input

Method: POST

{ "uri": "https://management.azure.com/subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.OperationalInsights/workspaces/deleted/providers/Microsoft.SecurityInsights/incidents/deleted/runPlaybook?api-version=2023-06-01-preview", "method": "POST", "authentication": { "type": "ManagedServiceIdentity" }, "body": { "logicAppsResourceId": "/subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.Logic/workflows/Prompt-User-Incident", "tenantId": "deleted" } }

Authentication

{ "type": "ManagedServiceIdentity" }

Output:

{ "statusCode": 204, "headers": { "Pragma": "no-cache", "x-ms-ratelimit-remaining-subscription-writes": "1199", "x-ms-request-id": "0194f8c2-c702-439b-8f11-662700602c29", "x-ms-correlation-request-id": "0194f8c2-c702-439b-8f11-662700602c29", "x-ms-routing-request-id": "WESTEUROPE:20230807T090752Z:0194f8c2-c702-439b-8f11-662700602c29", "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "X-Content-Type-Options": "nosniff", "Cache-Control": "no-cache", "Date": "Mon, 07 Aug 2023 09:07:52 GMT", "Server": "Kestrel", "Expires": "-1", "Content-Length": "0" } }

BlydCL commented 11 months ago

Apologies, didn't mean to close it as you might still want to improve things at your side. Let me know if I can be of any help.

briandelmsft commented 11 months ago

Hi @BlydCL the inputs you provided appear to be from a different module, from the aadrisks

{ "method": "post", "path": "/api/modules/aadrisks", "host": { "connection": { "name": "/subscriptions/deleted/resourceGroups/deleted/providers/Microsoft.Web/connections/stat-deleted" }

Can you provide the inputs from the playbook module?

briandelmsft commented 11 months ago

Hi @BlydCL I did some testing on this and I can only reproduce the error if the identity STAT is running under doesn't have the permissions to the playbook you are trying to start. That does in fact throw a 400 / Bad Request. Are you sure the identity you are running STAT under has Microsoft Sentinel Playbook Operator on the Logic app you are trying to run?

BlydCL commented 11 months ago

Hi @briandelmsft, managed to get it working with the run playbook module. Problem might have been that I only assigned the permissions to the STAT playbook and not to the backend function. Thanks for your help!

briandelmsft commented 11 months ago

@BlydCL thanks for the update, we'll enhance the error message in that module to include the permissions needed as Playbooks could exist in many RGs and it's not really possible to cover them all with the GrantPermissions.ps1 script