Partager via


Utiliser des objets et des indicateurs STIX pour améliorer le renseignement sur les menaces et la chasse aux menaces dans Microsoft Sentinel (préversion)

Le 3 avril 2025, nous avons affiché un aperçu public de deux nouvelles tables pour prendre en charge les schémas d’indicateur et d’objet STIX (Structured Threat Information eXpression) : ThreatIntelIndicators et ThreatIntelObjects. Cet article fournit des exemples d’incorporation d’objets STIX dans des requêtes pour améliorer la chasse aux menaces et comment migrer vers le nouveau schéma d’indicateur de menace.

Pour plus d’informations sur les informations sur les menaces dans Microsoft Sentinel, consultez Informations sur les menaces dans Microsoft Sentinel.

Important

Microsoft Sentinel ingérera toutes les informations sur les menaces dans les nouvelles tables ThreatIntelIndicators et ThreatIntelObjects, tout en continuant à ingérer les mêmes données dans la table héritée ThreatIntelligenceIndicator jusqu'au 31 juillet 2025. Veillez à mettre à jour vos requêtes, règles d’analyse et de détection personnalisées, classeurs et automatisation pour utiliser les nouvelles tables d’après le 31 juillet 2025. Après cette date, Microsoft Sentinel cesse d’ingérer des données dans la table héritée ThreatIntelligenceIndicator . Nous mettons à jour toutes les solutions de veille des menaces prêtes à l’emploi dans le hub de contenu afin de tirer parti des nouvelles tables. Nous avons introduit des mises à jour importantes des processus de republier des données.

  1. Auparavant, les données ont été divisées et republiées dans Log Analytics sur une période de 12 jours. À présent, toutes les données sont republiées toutes les 7 à 10 jours. Vous pouvez identifier ces données dans les tables ThreatIntelIndicators et ThreatIntelObjects en vérifiant si LastUpdateMethod est égal à LogARepublisher.
  2. Les nouvelles tables prennent désormais en charge d’autres colonnes, y compris la colonne Data, qui contient l’objet de données complet (à l’exception des attributs qui existent déjà dans d’autres colonnes) utilisés dans les scénarios de chasse avancés. Si ces colonnes ne s’alignent pas sur votre scénario, apprenez-en davantage sur le filtrage des colonnes et des lignes avant l’ingestion vers Log Analytics.
  3. Pour optimiser l’ingestion dans Log Analytics, les paires clé-valeur sans données sont exclues. En outre, certains champs de la Data colonne , tels que description et pattern— sont tronqués s’ils dépassent 1 000 caractères. Pour plus d’informations sur le schéma mis à jour et sur la façon dont il peut affecter votre utilisation, consultez ThreatIntelIndicators et ThreatIntelObjects.

Identifier les acteurs de menace associés à des indicateurs de menace spécifiques

Cette requête est un exemple de mise en corrélation des indicateurs de menace, tels que les adresses IP, avec les acteurs des menaces :

 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

Cette requête fournit des insights sur les tactiques, techniques et procédures (TTPS) de l’acteur de menace (remplacez Sangria Tempest par le nom de l’acteur de menace que vous souhaitez examiner) :

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

Migrer des requêtes existantes vers le nouveau schéma ThreatIntelIndicators

Cet exemple montre comment migrer des requêtes existantes de la table héritée ThreatIntelligenceIndicator vers le nouveau ThreatIntelIndicators schéma. La requête utilise l'opérateur extend pour recréer les colonnes héritées en s'appuyant sur les colonnes ObservableKey et ObservableValue de la nouvelle table.

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

Supprimer les données envoyées à Log Analytics

Les transformations dans Azure Monitor vous permettent de filtrer ou de modifier des données entrantes avant qu’elles ne soient stockées dans un espace de travail Log Analytics. Ils sont implémentés en tant qu’instruction KQL (Kusto Query Language) dans une règle de collecte de données (DCR). Découvrez comment créer des transformations d’espace de travail et le coût des transformations.

Supprimer des colonnes envoyées à Log Analytics

Les tables ThreatIntelIndicator et ThreatIntelObjects incluent une colonne Data qui contient l’objet STIX entier d’origine. Si cette colonne n’est pas pertinente pour votre cas d’usage, vous pouvez la filtrer avant l’ingestion à l’aide de l’instruction KQL suivante :

source
| project-away Data

Transformer les lignes envoyées à Log Analytics

La ThreatIntelIndicators table reçoit toujours au moins une ligne pour chaque indicateur non expiré. Dans certains cas, le modèle STIX ne peut pas être analysé en paires clé/valeur. Lorsque cela se produit, l’indicateur est toujours envoyé à Log Analytics, mais seul le modèle brut et non pris en charge est inclus, ce qui permet aux utilisateurs de créer des analyses personnalisées si nécessaire. Si ces lignes ne sont pas utiles pour votre scénario, vous pouvez les filtrer avant l’ingestion à l’aide de l’instruction KQL suivante :

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

Pour plus d’informations, consultez les articles suivants :

Pour découvrir plus d’informations sur KQL, consultez Vue d’ensemble du langage de requête Kusto (KQL).

Autres ressources :