Usare gli oggetti e gli indicatori STIX per migliorare l'intelligence sulle minacce e la ricerca delle minacce in Microsoft Sentinel (anteprima)

Il 3 aprile 2025 sono disponibili in anteprima pubblicamente due nuove tabelle per supportare gli schemi di indicatori e oggetti STIX (Structured Threat Information eXpression): ThreatIntelIndicators e ThreatIntelObjects. Questo articolo fornisce esempi di come incorporare oggetti STIX nelle query per migliorare la ricerca delle minacce e come eseguire la migrazione al nuovo schema dell'indicatore di minaccia.

Per altre informazioni sull'intelligence sulle minacce in Microsoft Sentinel, vedere Intelligence sulle minacce in Microsoft Sentinel.

Importante

Microsoft Sentinel inserirà tutte le informazioni sulle minacce nelle tabelle e nuove ThreatIntelIndicatorsThreatIntelObjects, continuando a inserire gli stessi dati nella tabella legacy ThreatIntelligenceIndicator fino al 31 luglio 2025. Assicurarsi di aggiornare query personalizzate, regole di analisi e rilevamento, cartelle di lavoro e automazione per usare le nuove tabelle entro il 31 luglio 2025. Dopo questa data, Microsoft Sentinel smetterà di inserire i dati nella tabella legacyThreatIntelligenceIndicator. Stiamo aggiornando tutte le soluzioni di intelligence sulle minacce predefinite nell'hub contenuti per sfruttare le nuove tabelle. Sono stati introdotti aggiornamenti importanti per i processi di ripubblicazione dei dati.

  1. In precedenza, i dati erano divisi e ripubblicati in Log Analytics in un periodo di 12 giorni. A questo momento, tutti i dati vengono ripubblicati ogni 7-10 giorni. È possibile identificare questi dati nelle ThreatIntelIndicators tabelle e ThreatIntelObjects controllando se LastUpdateMethod è uguale a LogARepublisher.
  2. Le nuove tabelle supportano ora più colonne, inclusa la Data colonna , che contiene l'oggetto dati completo (ad eccezione degli attributi già esistenti in altre colonne) usato in scenari di ricerca avanzati. Se queste colonne non sono allineate allo scenario, altre informazioni sul filtro di colonne e righe prima dell'inserimento in Log Analytics.If these columns don't align with your scenario, learn more about filtering out columns and rows before ingestion to Log Analytics.
  3. Per ottimizzare l'inserimento in Log Analytics, vengono escluse coppie chiave-valore senza dati. Inoltre, alcuni campi all'interno della Data colonna, ad description esempio e pattern, vengono troncati se superano i 1.000 caratteri. Per altre informazioni sullo schema aggiornato e su come può influire sull'utilizzo, vedere ThreatIntelIndicators e ThreatIntelObjects.

Identificare gli attori delle minacce associati a indicatori di minaccia specifici

Questa query è un esempio di come correlare gli indicatori di minaccia, ad esempio gli indirizzi IP, con gli attori delle minacce:

 let IndicatorsWithThatIP = (ThreatIntelIndicators
| extend tlId = tostring(Data.id)
| summarize arg_max(TimeGenerated,*) by Id
|  where IsDeleted == false);
let ThreatActors = (ThreatIntelObjects
| where StixType == 'threat-actor'
| extend tlId = tostring(Data.id)
| extend ThreatActorName = Data.name
| extend ThreatActorSource = base64_decode_tostring(tostring(split(Id, '---')[0]))
| summarize arg_max(TimeGenerated,*) by Id
|  where IsDeleted == false);
let AllRelationships = (ThreatIntelObjects
| where StixType == 'relationship'
| extend tlSourceRef = tostring(Data.source_ref)
| extend tlTargetRef = tostring(Data.target_ref)
| extend tlId = tostring(Data.id)
| summarize arg_max(TimeGenerated,*) by Id
|  where IsDeleted == false);
let IndicatorAsSource = (IndicatorsWithThatIP
| join AllRelationships on $left.tlId == $right.tlSourceRef
| join ThreatActors on $left.tlTargetRef == $right.tlId);
let IndicatorAsTarget = (IndicatorsWithThatIP
| join AllRelationships on $left.tlId == $right.tlTargetRef
| join ThreatActors on $left.tlSourceRef == $right.tlId);
IndicatorAsSource
| union IndicatorAsTarget
| project ObservableValue, ThreatActorName

Questa query fornisce informazioni dettagliate sulle tattiche, le tecniche e le procedure (TTP) dell'attore di minacce (sostituire Sangria Tempest con il nome dell'attore di minaccia che si vuole analizzare):

let THREAT_ACTOR_NAME = 'Sangria Tempest';
let ThreatIntelObjectsPlus = (ThreatIntelObjects
| union (ThreatIntelIndicators
| extend StixType = 'indicator')
| extend tlId = tostring(Data.id)
| extend PlusStixTypes = StixType
| extend importantfield = case(StixType == "indicator", Data.pattern,
                            StixType == "attack-pattern", Data.name,
                            "Unkown")
| extend feedSource = base64_decode_tostring(tostring(split(Id, '---')[0]))
| summarize arg_max(TimeGenerated,*) by Id
|  where IsDeleted == false);
let ThreatActorsWithThatName = (ThreatIntelObjects
| where StixType == 'threat-actor'
| where Data.name == THREAT_ACTOR_NAME
| extend tlId = tostring(Data.id)
| extend ActorName = tostring(Data.name)
| summarize arg_max(TimeGenerated,*) by Id
|  where IsDeleted == false);
let AllRelationships = (ThreatIntelObjects
| where StixType == 'relationship'
| extend tlSourceRef = tostring(Data.source_ref)
| extend tlTargetRef = tostring(Data.target_ref)
| extend tlId = tostring(Data.id)
| summarize arg_max(TimeGenerated,*) by Id
|  where IsDeleted == false);
let SourceRelationships = (ThreatActorsWithThatName
| join AllRelationships on $left.tlId == $right.tlSourceRef
| join ThreatIntelObjectsPlus on $left.tlTargetRef == $right.tlId);
let TargetRelationships = (ThreatActorsWithThatName
| join AllRelationships on $left.tlId == $right.tlTargetRef
| join ThreatIntelObjectsPlus on $left.tlSourceRef == $right.tlId);
SourceRelationships
| union TargetRelationships
| project ActorName, PlusStixTypes, ObservableValue, importantfield, Tags, feedSource

Eseguire la migrazione di query esistenti al nuovo schema ThreatIntelIndicators

Questo esempio illustra come eseguire la migrazione delle query esistenti dalla tabella legacy ThreatIntelligenceIndicator al nuovo ThreatIntelIndicators schema. La query usa l'operatore extend per ricreare le colonne legacy in base alle ObservableKey colonne e ObservableValue nella nuova tabella.

ThreatIntelIndicators
| extend NetworkIP = iff(ObservableKey == 'ipv4-addr:value', ObservableValue, ''),
        NetworkSourceIP = iff(ObservableKey == 'network-traffic:src_ref.value', ObservableValue, ''),
        NetworkDestinationIP = iff(ObservableKey == 'network-traffic:dst_ref.value', ObservableValue, ''),
        DomainName = iff(ObservableKey == 'domain-name:value', ObservableValue, ''),
        EmailAddress = iff(ObservableKey == 'email-addr:value', ObservableValue, ''),
        FileHashType = case(ObservableKey has 'MD5', 'MD5',
                                ObservableKey has 'SHA-1', 'SHA-1',
                                ObservableKey has 'SHA-256', 'SHA-256',
                                ''),
        FileHashValue = iff(ObservableKey has 'file:hashes', ObservableValue, ''),
        Url = iff(ObservableKey == 'url:value', ObservableValue, ''),
        x509Certificate = iff(ObservableKey has 'x509-certificate:hashes.', ObservableValue, ''),
        x509Issuer = iff(ObservableKey has 'x509-certificate:issuer', ObservableValue, ''),
        x509CertificateNumber = iff(ObservableKey == 'x509-certificate:serial_number', ObservableValue, ''),        
        Description = tostring(Data.description),
        CreatedByRef = Data.created_by_ref,
        Extensions = Data.extensions,
        ExternalReferences = Data.references,
        GranularMarkings = Data.granular_markings,
        IndicatorId = tostring(Data.id),
        ThreatType = tostring(Data.indicator_types[0]),
        KillChainPhases = Data.kill_chain_phases,
        Labels = Data.labels,
        Lang = Data.lang,
        Name = Data.name,
        ObjectMarkingRefs = Data.object_marking_refs,
        PatternType = Data.pattern_type,
        PatternVersion = Data.pattern_version,
        Revoked = Data.revoked,
        SpecVersion = Data.spec_version
| project-reorder TimeGenerated, WorkspaceId, AzureTenantId, ThreatType, ObservableKey, ObservableValue, Confidence, Name, Description, LastUpdateMethod, SourceSystem, Created, Modified, ValidFrom, ValidUntil, IsDeleted, Tags, AdditionalFields, CreatedByRef, Extensions, ExternalReferences, GranularMarkings, IndicatorId, KillChainPhases, Labels, Lang, ObjectMarkingRefs, Pattern, PatternType, PatternVersion, Revoked, SpecVersion, NetworkIP, NetworkDestinationIP, NetworkSourceIP, DomainName, EmailAddress, FileHashType, FileHashValue, Url, x509Certificate, x509Issuer, x509CertificateNumber, Data

Trasformare i dati inviati a Log Analytics

Le trasformazioni in monitoraggio Azure consentono di filtrare o modificare i dati in ingresso prima di essere archiviati in un'area di lavoro Log Analytics. Vengono implementati come istruzione Linguaggio di query Kusto (KQL) in una regola di raccolta dati (DCR). Altre informazioni su come creare trasformazioni dell'area di lavoro e sui costi per le trasformazioni.

Trasformare le colonne inviate a Log Analytics

Le ThreatIntelIndicator tabelle e ThreatIntelObjects includono una Data colonna che contiene l'oggetto STIX originale completo. Se questa colonna non è rilevante per il caso d'uso, è possibile filtrarla prima dell'inserimento usando l'istruzione KQL seguente:

source
| project-away Data

Trasformare le righe inviate a Log Analytics

La ThreatIntelIndicators tabella riceve sempre almeno una riga per ogni indicatore non scaduto. In alcuni casi, il modello STIX non può essere analizzato in coppie chiave/valore. In questo caso, l'indicatore viene comunque inviato a Log Analytics, ma è incluso solo il modello non analizzato, che consente agli utenti di compilare analisi personalizzate, se necessario. Se queste righe non sono utili per lo scenario, è possibile filtrarle prima dell'inserimento usando l'istruzione KQL seguente:

source
| where (ObservableKey != "" and isnotempty(ObservableKey)) 
    or (ObservableValue != "" and isnotempty(ObservableValue))

Per altre informazioni, vedere gli articoli seguenti:

Per altre informazioni su KQL, vedere panoramica di Linguaggio di query Kusto (KQL).

Altre risorse: