Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

TI map URL entity to Web Session Events ASIM Web Session schema

Back
Id3b4a8c72-5a2e-4f1e-b61a-9d8b2a6d7a21
RulenameTI map URL entity to Web Session Events (ASIM Web Session schema)
DescriptionThis rule identifies Web Sessions where the full requested URL matches a known

malicious URL from Threat Intelligence sources. The rule uses the Advanced Security

Information Model (ASIM) and supports any web session source compliant with ASIM.
SeverityMedium
TacticsCommandAndControl
InitialAccess
TechniquesT1071
Required data connectorsMicrosoftDefenderThreatIntelligence
SquidProxy
ThreatIntelligence
ThreatIntelligenceTaxii
Zscaler
KindScheduled
Query frequency1h
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence (NEW)/Analytic Rules/URLEntity_imWebSession.yaml
Version1.0.0
Arm template3b4a8c72-5a2e-4f1e-b61a-9d8b2a6d7a21.json
Deploy To Azure
let HAS_ANY_MAX = 10000;
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
// Extract URL-based Threat Intelligence indicators
let URL_TI =
  ThreatIntelIndicators
  | extend IndicatorType = replace(@"\[|\]|\""", "", tostring(split(ObservableKey, ":", 0)))
  | where IndicatorType == "url"
  | extend MaliciousUrl = tolower(ObservableValue)
  | extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)
  | extend IndicatorId = tostring(split(Id, "--")[2])
  | where TimeGenerated >= ago(ioc_lookBack)
  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, MaliciousUrl
  | where IsActive and (ValidUntil > now() or isempty(ValidUntil));
// Build a dynamic list of malicious URLs
let URL_TI_list =
  toscalar(
      URL_TI
      | summarize NIoCs = dcount(MaliciousUrl),
                  Urls = make_set(MaliciousUrl)
      | project Urls = iff(NIoCs > HAS_ANY_MAX, dynamic([]), Urls)
    );
// Match against ASIM Web Session events
URL_TI
| join kind=innerunique (
    _Im_WebSession(starttime=ago(dt_lookBack), url_has_any = URL_TI_list)
    | extend RequestedUrl = tolower(Url)
    | where isnotempty(RequestedUrl)
    | extend Event_TimeGenerated = TimeGenerated
  ) on $left.MaliciousUrl == $right.RequestedUrl
| where Event_TimeGenerated < ValidUntil
| summarize Event_TimeGenerated = arg_max(Event_TimeGenerated, *) by IndicatorId, RequestedUrl
| extend ParsedData = parse_json(Data)
| extend Description = tostring(ParsedData.description)
| extend ActivityGroupNames = extract(@"ActivityGroup:(\S+)", 1, tostring(ParsedData.labels))
| extend ThreatType = tostring(ParsedData.indicator_types[0])
| project
    Event_TimeGenerated,
    SrcIpAddr,
    RequestedUrl,
    IndicatorId,
    ThreatType,
    Confidence,
    ValidUntil,
    Description,
    ActivityGroupNames
severity: Medium
triggerOperator: gt
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence (NEW)/Analytic Rules/URLEntity_imWebSession.yaml
id: 3b4a8c72-5a2e-4f1e-b61a-9d8b2a6d7a21
customDetails:
  ThreatType: ThreatType
  IoCDescription: Description
  ActivityGroupNames: ActivityGroupNames
  IndicatorId: IndicatorId
  IoCExpirationTime: ValidUntil
  IoCConfidenceScore: Confidence
  EventTime: Event_TimeGenerated
entityMappings:
- fieldMappings:
  - identifier: Address
    columnName: SrcIpAddr
  entityType: IP
- fieldMappings:
  - identifier: Url
    columnName: RequestedUrl
  entityType: URL
kind: Scheduled
tactics:
- CommandAndControl
- InitialAccess
queryFrequency: 1h
requiredDataConnectors:
- connectorId: SquidProxy
  dataTypes:
  - SquidProxy_CL
- connectorId: Zscaler
  dataTypes:
  - CommonSecurityLog
- connectorId: ThreatIntelligence
  dataTypes:
  - ThreatIntelIndicators
- connectorId: ThreatIntelligenceTaxii
  dataTypes:
  - ThreatIntelIndicators
- connectorId: MicrosoftDefenderThreatIntelligence
  dataTypes:
  - ThreatIntelIndicators
relevantTechniques:
- T1071
version: 1.0.0
description: |
  This rule identifies Web Sessions where the full requested URL matches a known
  malicious URL from Threat Intelligence sources. The rule uses the Advanced Security
  Information Model (ASIM) and supports any web session source compliant with ASIM.  
alertDetailsOverride:
  alertDisplayNameFormat: A web request from {{SrcIpAddr}} to malicious URL matched an IoC
  alertDescriptionFormat: A client with address {{SrcIpAddr}} requested the URL {{RequestedUrl}}, which is a known malicious URL associated with {{ThreatType}}. Review threat intelligence blade for further context.
triggerThreshold: 0
query: |
  let HAS_ANY_MAX = 10000;
  let dt_lookBack = 1h;
  let ioc_lookBack = 14d;
  // Extract URL-based Threat Intelligence indicators
  let URL_TI =
    ThreatIntelIndicators
    | extend IndicatorType = replace(@"\[|\]|\""", "", tostring(split(ObservableKey, ":", 0)))
    | where IndicatorType == "url"
    | extend MaliciousUrl = tolower(ObservableValue)
    | extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)
    | extend IndicatorId = tostring(split(Id, "--")[2])
    | where TimeGenerated >= ago(ioc_lookBack)
    | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, MaliciousUrl
    | where IsActive and (ValidUntil > now() or isempty(ValidUntil));
  // Build a dynamic list of malicious URLs
  let URL_TI_list =
    toscalar(
        URL_TI
        | summarize NIoCs = dcount(MaliciousUrl),
                    Urls = make_set(MaliciousUrl)
        | project Urls = iff(NIoCs > HAS_ANY_MAX, dynamic([]), Urls)
      );
  // Match against ASIM Web Session events
  URL_TI
  | join kind=innerunique (
      _Im_WebSession(starttime=ago(dt_lookBack), url_has_any = URL_TI_list)
      | extend RequestedUrl = tolower(Url)
      | where isnotempty(RequestedUrl)
      | extend Event_TimeGenerated = TimeGenerated
    ) on $left.MaliciousUrl == $right.RequestedUrl
  | where Event_TimeGenerated < ValidUntil
  | summarize Event_TimeGenerated = arg_max(Event_TimeGenerated, *) by IndicatorId, RequestedUrl
  | extend ParsedData = parse_json(Data)
  | extend Description = tostring(ParsedData.description)
  | extend ActivityGroupNames = extract(@"ActivityGroup:(\S+)", 1, tostring(ParsedData.labels))
  | extend ThreatType = tostring(ParsedData.indicator_types[0])
  | project
      Event_TimeGenerated,
      SrcIpAddr,
      RequestedUrl,
      IndicatorId,
      ThreatType,
      Confidence,
      ValidUntil,
      Description,
      ActivityGroupNames  
queryPeriod: 14d
name: TI map URL entity to Web Session Events (ASIM Web Session schema)