Analytic rule catalog
SAP BTP - Cloud Integration artifact deployment
Back
| Id | a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d |
| Rulename | SAP BTP - Cloud Integration artifact deployment |
| Description | Identifies deployment and undeployment of integration artifacts in SAP Cloud Integration. Integration flows are executable code that can process, transform, and route data between systems. Unauthorized artifact deployment could indicate: - Attacker deploying malicious integration flows for data exfiltration - Deployment of rogue code for persistent access - Undeployment of critical integrations causing denial of service |
| Severity | High |
| Tactics | Execution Persistence |
| Techniques | T1059 T1546 |
| Required data connectors | SAPBTPAuditEvents |
| Kind | Scheduled |
| Query frequency | 15m |
| Query period | 15m |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SAP%20BTP/Analytic%20Rules/BTP%20-%20Cloud%20Integration%20artifact%20deployment.yaml |
| Version | 1.1.1 |
| Arm template | a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d.json |
SAPBTPAuditLog_CL
| where Category == "audit.configuration"
| extend objectType = tostring(Message.object.type)
| where objectType in ("Deployment", "Undeployment")
| extend attributes = todynamic(Message.attributes)
| mv-apply attr = attributes on (
summarize
SymbolicName = take_anyif(tostring(coalesce(attr.["new"], attr.["old"])), tostring(attr.name) == "symbolicName"),
ArtifactId = take_anyif(tostring(coalesce(attr.["new"], attr.["old"])), tostring(attr.name) == "id"),
ArtifactVersion = take_anyif(tostring(coalesce(attr.["new"], attr.["old"])), tostring(attr.name) == "version"),
DeployedBy = take_anyif(tostring(attr.["new"]), tostring(attr.name) == "deployedBy"),
UndeployedBy = take_anyif(tostring(attr.["new"]), tostring(attr.name) == "undeployedBy"),
Creator = take_anyif(tostring(coalesce(attr.["new"], attr.["old"])), tostring(attr.name) == "creator"),
TenantName = take_anyif(tostring(attr.["new"]), tostring(attr.name) == "tenantName"),
RuntimeLocationId = take_anyif(tostring(coalesce(attr.["new"], attr.["old"])), tostring(attr.name) == "runtimeLocationId")
)
| extend Actor = case(
isnotempty(DeployedBy), DeployedBy,
isnotempty(UndeployedBy), UndeployedBy,
isnotempty(Creator), Creator,
""
)
| extend ActionCategory = iff(objectType == "Deployment", "Deploy", "Undeploy"),
normalizedAction = iff(objectType == "Deployment", "deployed", "undeployed")
| extend MessageText = strcat("Integration artifact '", SymbolicName, "' (version ", ArtifactVersion, ") was ", normalizedAction, " in tenant ", TenantName)
| extend AccountName = iff(Actor has "@", tostring(split(Actor, "@")[0]), ""),
UPNSuffix = iff(Actor has "@", tostring(split(Actor, "@")[1]), "")
| project
UpdatedOn,
Actor,
AccountName,
UPNSuffix,
MessageText,
ArtifactName = SymbolicName,
ArtifactId,
ArtifactVersion,
ActionCategory,
ObjectType = objectType,
TenantName,
RuntimeLocationId,
Tenant,
CloudApp = "SAP Cloud Integration"
entityMappings:
- entityType: Account
fieldMappings:
- columnName: AccountName
identifier: Name
- columnName: UPNSuffix
identifier: UPNSuffix
- entityType: CloudApplication
fieldMappings:
- columnName: CloudApp
identifier: Name
query: |
SAPBTPAuditLog_CL
| where Category == "audit.configuration"
| extend objectType = tostring(Message.object.type)
| where objectType in ("Deployment", "Undeployment")
| extend attributes = todynamic(Message.attributes)
| mv-apply attr = attributes on (
summarize
SymbolicName = take_anyif(tostring(coalesce(attr.["new"], attr.["old"])), tostring(attr.name) == "symbolicName"),
ArtifactId = take_anyif(tostring(coalesce(attr.["new"], attr.["old"])), tostring(attr.name) == "id"),
ArtifactVersion = take_anyif(tostring(coalesce(attr.["new"], attr.["old"])), tostring(attr.name) == "version"),
DeployedBy = take_anyif(tostring(attr.["new"]), tostring(attr.name) == "deployedBy"),
UndeployedBy = take_anyif(tostring(attr.["new"]), tostring(attr.name) == "undeployedBy"),
Creator = take_anyif(tostring(coalesce(attr.["new"], attr.["old"])), tostring(attr.name) == "creator"),
TenantName = take_anyif(tostring(attr.["new"]), tostring(attr.name) == "tenantName"),
RuntimeLocationId = take_anyif(tostring(coalesce(attr.["new"], attr.["old"])), tostring(attr.name) == "runtimeLocationId")
)
| extend Actor = case(
isnotempty(DeployedBy), DeployedBy,
isnotempty(UndeployedBy), UndeployedBy,
isnotempty(Creator), Creator,
""
)
| extend ActionCategory = iff(objectType == "Deployment", "Deploy", "Undeploy"),
normalizedAction = iff(objectType == "Deployment", "deployed", "undeployed")
| extend MessageText = strcat("Integration artifact '", SymbolicName, "' (version ", ArtifactVersion, ") was ", normalizedAction, " in tenant ", TenantName)
| extend AccountName = iff(Actor has "@", tostring(split(Actor, "@")[0]), ""),
UPNSuffix = iff(Actor has "@", tostring(split(Actor, "@")[1]), "")
| project
UpdatedOn,
Actor,
AccountName,
UPNSuffix,
MessageText,
ArtifactName = SymbolicName,
ArtifactId,
ArtifactVersion,
ActionCategory,
ObjectType = objectType,
TenantName,
RuntimeLocationId,
Tenant,
CloudApp = "SAP Cloud Integration"
eventGroupingSettings:
aggregationKind: SingleAlert
id: a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d
queryFrequency: 15m
alertDetailsOverride:
alertDisplayNameFormat: 'SAP Cloud Integration: {{MessageText}}'
alertDescriptionFormat: |
{{MessageText}} by {{Actor}}.
This could indicate:
- Legitimate integration artifact deployment or maintenance
- Unauthorized deployment of malicious integration code
- Attacker undeploying security-relevant integrations
status: Available
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SAP%20BTP/Analytic%20Rules/BTP%20-%20Cloud%20Integration%20artifact%20deployment.yaml
version: 1.1.1
severity: High
relevantTechniques:
- T1059
- T1546
name: SAP BTP - Cloud Integration artifact deployment
kind: Scheduled
tactics:
- Execution
- Persistence
requiredDataConnectors:
- dataTypes:
- SAPBTPAuditLog_CL
connectorId: SAPBTPAuditEvents
description: |
Identifies deployment and undeployment of integration artifacts in SAP Cloud Integration.
Integration flows are executable code that can process, transform, and route data between
systems.
Unauthorized artifact deployment could indicate:
- Attacker deploying malicious integration flows for data exfiltration
- Deployment of rogue code for persistent access
- Undeployment of critical integrations causing denial of service
customDetails:
ArtifactId: ArtifactId
ArtifactName: ArtifactName
TenantName: TenantName
ActionCategory: ActionCategory
ArtifactVersion: ArtifactVersion
RuntimeLocationId: RuntimeLocationId
triggerOperator: gt
triggerThreshold: 0
queryPeriod: 15m
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d')]",
"properties": {
"alertDetailsOverride": {
"alertDescriptionFormat": "{{MessageText}} by {{Actor}}.\n\nThis could indicate:\n- Legitimate integration artifact deployment or maintenance\n- Unauthorized deployment of malicious integration code\n- Attacker undeploying security-relevant integrations\n",
"alertDisplayNameFormat": "SAP Cloud Integration: {{MessageText}}"
},
"alertRuleTemplateName": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"customDetails": {
"ActionCategory": "ActionCategory",
"ArtifactId": "ArtifactId",
"ArtifactName": "ArtifactName",
"ArtifactVersion": "ArtifactVersion",
"RuntimeLocationId": "RuntimeLocationId",
"TenantName": "TenantName"
},
"description": "Identifies deployment and undeployment of integration artifacts in SAP Cloud Integration.\nIntegration flows are executable code that can process, transform, and route data between\nsystems.\n\nUnauthorized artifact deployment could indicate:\n- Attacker deploying malicious integration flows for data exfiltration\n- Deployment of rogue code for persistent access\n- Undeployment of critical integrations causing denial of service\n",
"displayName": "SAP BTP - Cloud Integration artifact deployment",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "AccountName",
"identifier": "Name"
},
{
"columnName": "UPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "CloudApplication",
"fieldMappings": [
{
"columnName": "CloudApp",
"identifier": "Name"
}
]
}
],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SAP%20BTP/Analytic%20Rules/BTP%20-%20Cloud%20Integration%20artifact%20deployment.yaml",
"query": "SAPBTPAuditLog_CL\n| where Category == \"audit.configuration\"\n| extend objectType = tostring(Message.object.type)\n| where objectType in (\"Deployment\", \"Undeployment\")\n| extend attributes = todynamic(Message.attributes)\n| mv-apply attr = attributes on (\n summarize\n SymbolicName = take_anyif(tostring(coalesce(attr.[\"new\"], attr.[\"old\"])), tostring(attr.name) == \"symbolicName\"),\n ArtifactId = take_anyif(tostring(coalesce(attr.[\"new\"], attr.[\"old\"])), tostring(attr.name) == \"id\"),\n ArtifactVersion = take_anyif(tostring(coalesce(attr.[\"new\"], attr.[\"old\"])), tostring(attr.name) == \"version\"),\n DeployedBy = take_anyif(tostring(attr.[\"new\"]), tostring(attr.name) == \"deployedBy\"),\n UndeployedBy = take_anyif(tostring(attr.[\"new\"]), tostring(attr.name) == \"undeployedBy\"),\n Creator = take_anyif(tostring(coalesce(attr.[\"new\"], attr.[\"old\"])), tostring(attr.name) == \"creator\"),\n TenantName = take_anyif(tostring(attr.[\"new\"]), tostring(attr.name) == \"tenantName\"),\n RuntimeLocationId = take_anyif(tostring(coalesce(attr.[\"new\"], attr.[\"old\"])), tostring(attr.name) == \"runtimeLocationId\")\n)\n| extend Actor = case(\n isnotempty(DeployedBy), DeployedBy,\n isnotempty(UndeployedBy), UndeployedBy,\n isnotempty(Creator), Creator,\n \"\"\n)\n| extend ActionCategory = iff(objectType == \"Deployment\", \"Deploy\", \"Undeploy\"),\n normalizedAction = iff(objectType == \"Deployment\", \"deployed\", \"undeployed\")\n| extend MessageText = strcat(\"Integration artifact '\", SymbolicName, \"' (version \", ArtifactVersion, \") was \", normalizedAction, \" in tenant \", TenantName)\n| extend AccountName = iff(Actor has \"@\", tostring(split(Actor, \"@\")[0]), \"\"),\n UPNSuffix = iff(Actor has \"@\", tostring(split(Actor, \"@\")[1]), \"\")\n| project\n UpdatedOn,\n Actor,\n AccountName,\n UPNSuffix,\n MessageText,\n ArtifactName = SymbolicName,\n ArtifactId,\n ArtifactVersion,\n ActionCategory,\n ObjectType = objectType,\n TenantName,\n RuntimeLocationId,\n Tenant,\n CloudApp = \"SAP Cloud Integration\"\n",
"queryFrequency": "PT15M",
"queryPeriod": "PT15M",
"severity": "High",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"Execution",
"Persistence"
],
"techniques": [
"T1059",
"T1546"
],
"templateVersion": "1.1.1",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}