Back
Ida1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d
RulenameSAP BTP - Cloud Integration artifact deployment
DescriptionIdentifies 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
SeverityHigh
TacticsExecution
Persistence
TechniquesT1059
T1546
Required data connectorsSAPBTPAuditEvents
KindScheduled
Query frequency15m
Query period15m
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SAP%20BTP/Analytic%20Rules/BTP%20-%20Cloud%20Integration%20artifact%20deployment.yaml
Version1.1.1
Arm templatea1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d.json
Deploy To Azure
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"
name: SAP BTP - Cloud Integration artifact deployment
triggerOperator: gt
kind: Scheduled
queryFrequency: 15m
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
id: a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d
triggerThreshold: 0
queryPeriod: 15m
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"
version: 1.1.1
customDetails:
  ArtifactId: ArtifactId
  TenantName: TenantName
  ArtifactVersion: ArtifactVersion
  ArtifactName: ArtifactName
  ActionCategory: ActionCategory
  RuntimeLocationId: RuntimeLocationId
status: Available
eventGroupingSettings:
  aggregationKind: SingleAlert
severity: High
requiredDataConnectors:
- connectorId: SAPBTPAuditEvents
  dataTypes:
  - SAPBTPAuditLog_CL
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SAP%20BTP/Analytic%20Rules/BTP%20-%20Cloud%20Integration%20artifact%20deployment.yaml
alertDetailsOverride:
  alertDescriptionFormat: |
    {{MessageText}} by {{Actor}}.

    This could indicate:
    - Legitimate integration artifact deployment or maintenance
    - Unauthorized deployment of malicious integration code
    - Attacker undeploying security-relevant integrations
  alertDisplayNameFormat: 'SAP Cloud Integration: {{MessageText}}'
relevantTechniques:
- T1059
- T1546
tactics:
- Execution
- Persistence
entityMappings:
- fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: UPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: Name
    columnName: CloudApp
  entityType: CloudApplication
{
  "$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"
    }
  ]
}