2025년 4월 3일에 STIX(구조적 위협 정보 eXpression) 표시기 및 개체 스키마 ThreatIntelIndicators ( 및 ThreatIntelObjects)를 지원하기 위해 두 개의 새 테이블을 공개적으로 미리 했습니다. 이 문서에서는 STIX 개체를 쿼리에 통합하여 위협 헌팅을 개선하는 방법과 새 위협 지표 스키마로 마이그레이션하는 방법에 대한 예제를 제공합니다.
Microsoft Sentinel 위협 인텔리전스에 대한 자세한 내용은 Microsoft Sentinel 위협 인텔리전스를 참조하세요.
중요
Microsoft Sentinel 2025년 7월 31일까지 동일한 데이터를 레거시 ThreatIntelligenceIndicator 테이블에 계속 수집하면서 모든 위협 인텔리전스를 새 ThreatIntelIndicators 테이블과 ThreatIntelObjects 테이블에 수집합니다.
2025년 7월 31일까지 새 테이블을 사용하도록 사용자 지정 쿼리, 분석 및 검색 규칙, 통합 문서 및 자동화를 업데이트해야 합니다. 이 날짜 이후에는 Microsoft Sentinel 레거시 ThreatIntelligenceIndicator 테이블에 대한 데이터 수집을 중지합니다. 새 테이블을 활용하기 위해 콘텐츠 허브의 모든 기본 위협 인텔리전스 솔루션을 업데이트하고 있습니다.
데이터 다시 게시 프로세스에 대한 중요한 업데이트를 도입했습니다.
- 이전에는 데이터를 12일 동안 Log Analytics에 분할하고 다시 게시했습니다. 이제 모든 데이터는7-10일마다 다시 게시됩니다. 와 같은지
LastUpdateMethod확인하여 및ThreatIntelObjects테이블에서 이 데이터를ThreatIntelIndicators식별할 수 있습니다LogARepublisher. - 이제 새 테이블은 고급 헌팅 시나리오에서 사용되는 전체 데이터 개체(다른 열에 이미 있는 특성 제외)를 포함하는 열을 포함하여
Data더 많은 열을 지원합니다. 이러한 열이 시나리오와 일치하지 않는 경우 Log Analytics 로 수집하기 전에 열 및 행 을 필터링하는 방법에 대해 자세히 알아보세요. - Log Analytics에 대한 수집을 최적화하기 위해 데이터가 없는 키-값 쌍은 제외됩니다. 또한 열 내의
Data일부 필드(예:description및pattern)는 1,000자를 초과하면 잘립니다. 업데이트된 스키마 및 사용량에 미치는 영향에 대한 자세한 내용은 ThreatIntelIndicators 및 ThreatIntelObjects를 참조하세요.
특정 위협 지표와 연결된 위협 행위자 식별
이 쿼리는 IP 주소와 같은 위협 지표와 위협 행위자를 상호 연결하는 방법의 예입니다.
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
특정 위협 행위자 관련 위협 인텔리전스 데이터 나열
이 쿼리는 위협 행위자의 TTP(전술, 기술 및 프로시저)에 대한 인사이트를 제공합니다(조사하려는 위협 행위자의 이름으로 대체 Sangria Tempest ).
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
기존 쿼리를 새 ThreatIntelIndicators 스키마로 마이그레이션
이 예제에서는 기존 쿼리를 레거시 ThreatIntelligenceIndicator 테이블에서 새 ThreatIntelIndicators 스키마로 마이그레이션하는 방법을 보여 줍니다. 쿼리는 연산자를 extend 사용하여 새 테이블의 ObservableKey 및 ObservableValue 열을 기반으로 레거시 열을 다시 만듭니다.
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
Log Analytics로 전송된 데이터 변환
Azure Monitor의 변환을 통해 들어오는 데이터를 Log Analytics 작업 영역에 저장하기 전에 필터링하거나 수정할 수 있습니다. DCR(데이터 수집 규칙)에서 KQL(Kusto 쿼리 언어) 문으로 구현됩니다. 작업 영역 변환을 만드는 방법 및 변환 비용에 대해 자세히 알아봅니다.
Log Analytics로 전송된 열 변환
및 ThreatIntelObjects 테이블에는 ThreatIntelIndicator 전체 원래 STIX 개체가 포함된 열이 포함 Data 됩니다. 이 열이 사용 사례와 관련이 없는 경우 다음 KQL 문을 사용하여 수집하기 전에 필터링할 수 있습니다.
source
| project-away Data
Log Analytics로 전송된 행 변환
테이블은 ThreatIntelIndicators 항상 노출되지 않은 각 표시기마다 하나 이상의 행을 받습니다. 경우에 따라 STIX 패턴을 키/값 쌍으로 구문 분석할 수 없습니다. 이 경우 지표는 여전히 Log Analytics로 전송되지만, 원시의 분석되지 않은 패턴만 포함되므로 필요한 경우 사용자가 사용자 지정 분석을 빌드할 수 있습니다. 이러한 행이 시나리오에 유용하지 않은 경우 다음 KQL 문을 사용하여 수집하기 전에 필터링할 수 있습니다.
source
| where (ObservableKey != "" and isnotempty(ObservableKey))
or (ObservableValue != "" and isnotempty(ObservableValue))
관련 콘텐츠
자세한 내용은 다음 문서를 참조하세요.
- Microsoft Sentinel 위협 인텔리전스.
- STIX/TAXII 위협 인텔리전스 피드에 Microsoft Sentinel 연결합니다.
- Microsoft Sentinel 쉽게 통합할 수 있는 TIP, TAXII 피드 및 보강을 확인합니다.
KQL에 대한 자세한 내용은 Kusto 쿼리 언어(KQL) 개요를 참조하세요.
기타 리소스: