Back
Id3ebd25b1-6f54-49f9-b5a5-0246357ce4ca
RulenameGSA - TI IP Entity
DescriptionThis query identifies IP indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in GSA NetworkAccessTraffic.
SeverityMedium
TacticsCommandAndControl
TechniquesT1071
Required data connectorsAzureActiveDirectory
KindScheduled
Query frequency1h
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global%20Secure%20Access/Analytic%20Rules/GSA%20-%20TI%20IP%20Entity.yaml
Arm template3ebd25b1-6f54-49f9-b5a5-0246357ce4ca.json
Deploy To Azure
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let NetworkAccessTraffic_ =
    NetworkAccessTraffic
    | where TimeGenerated >= ago(dt_lookBack)
    | where TrafficType == "internet"
    | project-rename GSANetworkAccessTraffic_TimeGenerated = TimeGenerated;
let IPList = NetworkAccessTraffic_ | summarize by DestinationIp;
ThreatIntelIndicators
| project-rename TI_ipEntity = ObservableValue
| extend IndicatorType = replace(@'\[|\]|"""', "", tostring(split(ObservableKey, ":", 0)))
| where IndicatorType in ("ipv4-addr", "network-traffic")
| extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)
| where TimeGenerated >= ago(ioc_lookBack)
| where TI_ipEntity in (IPList)
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, TI_ipEntity
| where IsActive and (ValidUntil > now() or isempty(ValidUntil))
| extend Description = tostring(parse_json(Data).description)
| where Description !contains_cs "State: inactive;" and Description !contains_cs "State: falsepos;"
| join kind=innerunique (NetworkAccessTraffic_) on $left.TI_ipEntity == $right.DestinationIp
| extend GSAThreatType = ThreatType
| summarize GSANetworkAccessTraffic_TimeGenerated = arg_max(GSANetworkAccessTraffic_TimeGenerated, *) by Id, DestinationIp
| project-reorder *,
    Tags,
    Confidence,
    TrafficLightProtocolLevel,
    Type,
    TI_ipEntity,
    UserPrincipalName,
    UserId,
    DeviceId,
    InitiatingProcessName,
    GSAThreatType,
    DestinationFqdn,
    DestinationUrl,
    DestinationPort,
    SourceIp,
    SourcePort,
    HttpUserAgent
queryPeriod: 14d
status: Available
kind: Scheduled
description: |
  This query identifies IP indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in GSA NetworkAccessTraffic.
queryFrequency: 1h
id: 3ebd25b1-6f54-49f9-b5a5-0246357ce4ca
entityMappings:
- fieldMappings:
  - columnName: UserPrincipalName
    identifier: Name
  entityType: Account
- fieldMappings:
  - columnName: InitiatingProcessName
    identifier: CommandLine
  entityType: Process
- fieldMappings:
  - columnName: SourceIp
    identifier: Address
  entityType: IP
- fieldMappings:
  - columnName: DeviceId
    identifier: AzureID
  entityType: Host
relevantTechniques:
- T1071
triggerThreshold: 0
tactics:
- CommandAndControl
requiredDataConnectors:
- connectorId: AzureActiveDirectory
  dataTypes:
  - NetworkAccessTrafficLogs
query: |
  let dt_lookBack = 1h;
  let ioc_lookBack = 14d;
  let NetworkAccessTraffic_ =
      NetworkAccessTraffic
      | where TimeGenerated >= ago(dt_lookBack)
      | where TrafficType == "internet"
      | project-rename GSANetworkAccessTraffic_TimeGenerated = TimeGenerated;
  let IPList = NetworkAccessTraffic_ | summarize by DestinationIp;
  ThreatIntelIndicators
  | project-rename TI_ipEntity = ObservableValue
  | extend IndicatorType = replace(@'\[|\]|"""', "", tostring(split(ObservableKey, ":", 0)))
  | where IndicatorType in ("ipv4-addr", "network-traffic")
  | extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)
  | where TimeGenerated >= ago(ioc_lookBack)
  | where TI_ipEntity in (IPList)
  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, TI_ipEntity
  | where IsActive and (ValidUntil > now() or isempty(ValidUntil))
  | extend Description = tostring(parse_json(Data).description)
  | where Description !contains_cs "State: inactive;" and Description !contains_cs "State: falsepos;"
  | join kind=innerunique (NetworkAccessTraffic_) on $left.TI_ipEntity == $right.DestinationIp
  | extend GSAThreatType = ThreatType
  | summarize GSANetworkAccessTraffic_TimeGenerated = arg_max(GSANetworkAccessTraffic_TimeGenerated, *) by Id, DestinationIp
  | project-reorder *,
      Tags,
      Confidence,
      TrafficLightProtocolLevel,
      Type,
      TI_ipEntity,
      UserPrincipalName,
      UserId,
      DeviceId,
      InitiatingProcessName,
      GSAThreatType,
      DestinationFqdn,
      DestinationUrl,
      DestinationPort,
      SourceIp,
      SourcePort,
      HttpUserAgent
severity: Medium
triggerOperator: gt
name: GSA - TI IP Entity
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global%20Secure%20Access/Analytic%20Rules/GSA%20-%20TI%20IP%20Entity.yaml
{
  "$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/3ebd25b1-6f54-49f9-b5a5-0246357ce4ca')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/3ebd25b1-6f54-49f9-b5a5-0246357ce4ca')]",
      "properties": {
        "alertRuleTemplateName": "3ebd25b1-6f54-49f9-b5a5-0246357ce4ca",
        "customDetails": null,
        "description": "This query identifies IP indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in GSA NetworkAccessTraffic.\n",
        "displayName": "GSA - TI IP Entity",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "UserPrincipalName",
                "identifier": "Name"
              }
            ]
          },
          {
            "entityType": "Process",
            "fieldMappings": [
              {
                "columnName": "InitiatingProcessName",
                "identifier": "CommandLine"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "SourceIp",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "Host",
            "fieldMappings": [
              {
                "columnName": "DeviceId",
                "identifier": "AzureID"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global%20Secure%20Access/Analytic%20Rules/GSA%20-%20TI%20IP%20Entity.yaml",
        "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet NetworkAccessTraffic_ =\n    NetworkAccessTraffic\n    | where TimeGenerated >= ago(dt_lookBack)\n    | where TrafficType == \"internet\"\n    | project-rename GSANetworkAccessTraffic_TimeGenerated = TimeGenerated;\nlet IPList = NetworkAccessTraffic_ | summarize by DestinationIp;\nThreatIntelIndicators\n| project-rename TI_ipEntity = ObservableValue\n| extend IndicatorType = replace(@'\\[|\\]|\"\"\"', \"\", tostring(split(ObservableKey, \":\", 0)))\n| where IndicatorType in (\"ipv4-addr\", \"network-traffic\")\n| extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)\n| where TimeGenerated >= ago(ioc_lookBack)\n| where TI_ipEntity in (IPList)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, TI_ipEntity\n| where IsActive and (ValidUntil > now() or isempty(ValidUntil))\n| extend Description = tostring(parse_json(Data).description)\n| where Description !contains_cs \"State: inactive;\" and Description !contains_cs \"State: falsepos;\"\n| join kind=innerunique (NetworkAccessTraffic_) on $left.TI_ipEntity == $right.DestinationIp\n| extend GSAThreatType = ThreatType\n| summarize GSANetworkAccessTraffic_TimeGenerated = arg_max(GSANetworkAccessTraffic_TimeGenerated, *) by Id, DestinationIp\n| project-reorder *,\n    Tags,\n    Confidence,\n    TrafficLightProtocolLevel,\n    Type,\n    TI_ipEntity,\n    UserPrincipalName,\n    UserId,\n    DeviceId,\n    InitiatingProcessName,\n    GSAThreatType,\n    DestinationFqdn,\n    DestinationUrl,\n    DestinationPort,\n    SourceIp,\n    SourcePort,\n    HttpUserAgent\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl"
        ],
        "techniques": [
          "T1071"
        ],
        "templateVersion": "1.0.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}