Query Details

Tifcepillar2 Data

Query

// ================================================
// TIFCE Pillar 2: Environmental Relevance
// Query 1: XDR Device + Email telemetry only
//
// Purpose:
// - Identify whether active TI IOCs are found in XDR telemetry.
//
// Supports:
// - file
// - ipv4-addr
// - ipv6-addr
// - network-traffic
// - domain-name
// - url
// - email-addr
//
// No observe / block / deny / disposition logic
// ================================================
let CanonicalIOC = (iocType:string, iocValue:string) {
    strcat(tolower(trim(" ", iocType)), ":", tolower(trim(" ", iocValue)))
};
// -----------------------------
// Active TI indicators
// -----------------------------
let ActiveIOCs =
    ThreatIntelIndicators
    | where IsActive == true
      and IsDeleted == false
      and (isnull(ValidUntil) or ValidUntil > now())
    | where isnotempty(SourceSystem)
      and isnotempty(ObservableKey)
      and isnotempty(ObservableValue)
    | extend TIFeed = tostring(SourceSystem)
    | extend IOCTypeRaw = tostring(split(ObservableKey, ":", 0))
    | extend IOCType = replace_regex(tolower(trim(" ", IOCTypeRaw)), @"[\[\]""']", "")
    | where IOCType in (
        "file",
        "ipv4-addr",
        "ipv6-addr",
        "network-traffic",
        "domain-name",
        "url",
        "email-addr"
    )
    | extend IOC = CanonicalIOC(IOCType, tostring(ObservableValue))
    | summarize by TIFeed, IOC;
// -----------------------------
// IOC matches in XDR telemetry
// -----------------------------
let TelemetryIOCs =
    union isfuzzy=true
    // Device file hashes
    (
        DeviceFileEvents
        | where isnotempty(SHA256) or isnotempty(SHA1)
        | extend IOCs = pack_array(
            iff(isnotempty(SHA256), CanonicalIOC("file", SHA256), ""),
            iff(isnotempty(SHA1), CanonicalIOC("file", SHA1), "")
        )
        | mv-expand IOC = IOCs to typeof(string)
        | where isnotempty(IOC)
        | project IOC
    ),
    // Device network IPs, IPv6, network-traffic, URLs, and domains
    (
        DeviceNetworkEvents
        | where isnotempty(RemoteIP) or isnotempty(RemoteUrl)
        | extend UrlHost = iff(isnotempty(RemoteUrl), tostring(parse_url(RemoteUrl).Host), "")
        | extend RemoteIPType = iff(RemoteIP contains ":", "ipv6-addr", "ipv4-addr")
        | extend IOCs = pack_array(
            iff(isnotempty(RemoteIP), CanonicalIOC(RemoteIPType, RemoteIP), ""),
            iff(isnotempty(RemoteIP), CanonicalIOC("network-traffic", RemoteIP), ""),
            iff(isnotempty(RemoteUrl), CanonicalIOC("url", RemoteUrl), ""),
            iff(isnotempty(UrlHost), CanonicalIOC("domain-name", UrlHost), "")
        )
        | mv-expand IOC = IOCs to typeof(string)
        | where isnotempty(IOC)
        | project IOC
    ),
    // Email URLs and domains
    (
        EmailUrlInfo
        | where isnotempty(Url) or isnotempty(UrlDomain)
        | extend IOCs = pack_array(
            iff(isnotempty(Url), CanonicalIOC("url", Url), ""),
            iff(isnotempty(UrlDomain), CanonicalIOC("domain-name", UrlDomain), "")
        )
        | mv-expand IOC = IOCs to typeof(string)
        | where isnotempty(IOC)
        | project IOC
    ),
    // Email attachment hashes
    (
        EmailAttachmentInfo
        | where isnotempty(SHA256) or isnotempty(SHA1)
        | extend IOCs = pack_array(
            iff(isnotempty(SHA256), CanonicalIOC("file", SHA256), ""),
            iff(isnotempty(SHA1), CanonicalIOC("file", SHA1), "")
        )
        | mv-expand IOC = IOCs to typeof(string)
        | where isnotempty(IOC)
        | project IOC
    ),
    // Email addresses + derived email domains
    (
        EmailEvents
        | extend SenderFromAddress = tostring(column_ifexists("SenderFromAddress", "")),
                 SenderMailFromAddress = tostring(column_ifexists("SenderMailFromAddress", "")),
                 RecipientEmailAddress = tostring(column_ifexists("RecipientEmailAddress", ""))
        | extend EmailCandidates = pack_array(SenderFromAddress, SenderMailFromAddress, RecipientEmailAddress)
        | mv-expand EmailAddress = EmailCandidates to typeof(string)
        | extend EmailAddress = tolower(trim(" ", EmailAddress))
        | where isnotempty(EmailAddress) and EmailAddress contains "@"
        | extend EmailDomain = tostring(split(EmailAddress, "@", 1))
        | extend IOCs = pack_array(
            CanonicalIOC("email-addr", EmailAddress),
            iff(isnotempty(EmailDomain), CanonicalIOC("domain-name", EmailDomain), "")
        )
        | mv-expand IOC = IOCs to typeof(string)
        | where isnotempty(IOC)
        | project IOC
    )
    | where isnotempty(IOC)
    | summarize by IOC;
// -----------------------------
// Feed-level relevance scoring
// -----------------------------
ActiveIOCs
| join kind=leftouter (
    TelemetryIOCs
    | project TelemetryIOC = IOC
) on $left.IOC == $right.TelemetryIOC
| summarize
    TotalIOCs = count(),
    FoundIOCs = countif(isnotempty(TelemetryIOC)),
    NotFoundIOCs = countif(isempty(TelemetryIOC))
    by TIFeed
| extend
    EnvironmentalRelevanceScore = FoundIOCs,
    RelevancePct = round(
        iif(TotalIOCs > 0, 100.0 * todouble(FoundIOCs) / todouble(TotalIOCs), 0.0),
        2
    ),
    NotFoundPct = round(
        iif(TotalIOCs > 0, 100.0 * todouble(NotFoundIOCs) / todouble(TotalIOCs), 0.0),
        2
    )
| order by EnvironmentalRelevanceScore desc
| project
    Feed = TIFeed,
    TotalIOCs,
    FoundIOCs,
    NotFoundIOCs,
    RelevancePct,
    NotFoundPct,
    EnvironmentalRelevanceScore;

Explanation

This query is designed to analyze security threat intelligence indicators (IOCs) and determine their presence in XDR (Extended Detection and Response) telemetry data, specifically focusing on device and email-related data. Here's a simplified breakdown of what the query does:

  1. Define a Function for IOCs: A function CanonicalIOC is defined to standardize the format of IOCs by combining their type and value into a lowercase string.

  2. Identify Active Threat Intelligence Indicators:

    • It filters the ThreatIntelIndicators table to find active IOCs that are not deleted and are still valid.
    • It ensures these IOCs have a source system, key, and value.
    • It focuses on specific types of IOCs: file, IPv4/IPv6 addresses, network traffic, domain names, URLs, and email addresses.
    • It creates a standardized IOC string for each indicator and groups them by their source feed.
  3. Match IOCs in XDR Telemetry:

    • It collects potential IOCs from various XDR telemetry sources:
      • Device File Events: Extracts file hashes (SHA256, SHA1).
      • Device Network Events: Extracts IP addresses, URLs, and domains.
      • Email URL Info: Extracts URLs and domains from emails.
      • Email Attachment Info: Extracts file hashes from email attachments.
      • Email Events: Extracts email addresses and domains from email communications.
    • It standardizes these telemetry IOCs using the same format as the threat intelligence IOCs.
  4. Calculate Relevance Scores:

    • It performs a left outer join between the active IOCs and the telemetry IOCs to find matches.
    • It calculates the total number of IOCs, how many were found in the telemetry, and how many were not found.
    • It computes an "Environmental Relevance Score" based on the number of found IOCs.
    • It calculates the percentage of IOCs found and not found.
    • It orders the results by the relevance score in descending order.
  5. Output:

    • The final output includes the feed name, total IOCs, found IOCs, not found IOCs, relevance percentage, not found percentage, and the environmental relevance score for each feed.

In summary, this query helps assess the relevance and presence of threat intelligence indicators within the organization's XDR telemetry data, providing insights into potential security threats.

Details

Michalis Michalos profile picture

Michalis Michalos

Released: June 3, 2026

Tables

ThreatIntelIndicatorsDeviceFileEventsDeviceNetworkEventsEmailUrlInfoEmailAttachmentInfoEmailEvents

Keywords

DevicesEmailNetworkDomainThreatIntelIndicators

Operators

letstrcattolowertrimThreatIntelIndicatorswhereandisnullnowisnotemptyextendtostringsplitreplace_regexinsummarizebyunionisfuzzyDeviceFileEventsiffpack_arraymv-expandprojectDeviceNetworkEventsparse_urlcontainsEmailUrlInfoEmailAttachmentInfoEmailEventscolumn_ifexistsjoinkindleftouteroncountcountifisemptyEnvironmentalRelevanceScoreroundtodoubleorderdesc

Actions