엔터프라이즈 노출 그래프 쿼리

Microsoft 보안 노출 관리의 엔터프라이즈 노출 그래프를 사용하여 Microsoft Defender 포털의 고급 헌팅에서 엔터프라이즈 노출 위협을 사전에 헌팅합니다.

이 문서에서는 엔터프라이즈 노출 그래프에서 쿼리를 생성하기 위한 몇 가지 예제, 팁 및 힌트를 제공합니다.

보안 노출 관리는 현재 공개 미리 보기로 제공됩니다.

중요

이 게시물의 일부 정보는 상용으로 출시되기 전에 실질적으로 수정될 수 있는 사전 릴리스된 제품과 관련이 있습니다. Microsoft는 여기에서 제공되는 정보와 관련하여 명시적이거나 묵시적인 어떠한 보증도 하지 않습니다.

필수 조건

고급 헌팅 쿼리 빌드

make-graph 연산자 사용

Kusto의 make-graph 연산자는 노드 및 에지 데이터를 메모리에 로드합니다.

  • Kusto는 사용 중인 열만 로드하므로 열을 명시적으로 선택할 필요가 없습니다.
  • 그러나 열에는 NodeProperties 모든 노드 정보가 포함되므로 큽니다.
  • 대부분의 시나리오에서는 운영자에게 공급하기 전에 필요한 정보만 추출하는 것이 make-graph 유용합니다.

예제

let FilteredNodes = ExposureGraphNodes
| extend ContainsSensetiveData = NodeProperties has "containsSensitiveData"
| project Id, ContainsSensetiveData, Label, EntityIds, Categories;
Edges
| make-graph SourceNodeId --> TargetNodeId with FilteredNodes on Id
..

동적 열 및 스마트 인덱싱 사용

NodePropertiesCategories 는 동적 열입니다.

  • Kusto는 해당 열에 json과 유사한 콘텐츠가 포함되어 있으며 스마트 인덱싱을 적용합니다.
  • 그러나 모든 Kusto 연산자가 인덱스를 사용하는 것은 아닙니다. 예를 들어 , set_has_elementisemptyisnotnull 인덱스가 동적 열에 적용되고 isnotnull(Properties["containsSensitiveData"] 인덱스는 사용하지 않을 때 사용하지 않습니다.
  • 대신 항상 인덱스 사용 has() 연산자를 사용합니다.

예제

다음 쿼리에서 연산자는 has 문자열 set_has_elementdata 확인하고 요소를 확인합니다data.

연산자는 범주 prefix_data에 대해서도 true를 has() 반환하기 때문에 두 연산자를 모두 사용하는 것이 중요합니다.

Categories has('data') and set_has_element(Categories, 'data')

문자열 용어 이해에 대해 자세히 알아봅니다.

예제 노출 쿼리

다음 예제는 테넌트에서 보안 노출 데이터를 이해하는 쿼리를 작성하는 데 도움이 될 수 있습니다.

테넌트에서 모든 노드 레이블 나열

다음 쿼리는 테이블의 데이터를 ExposureGraphNodes 그룹화하고 Kusto의 summarize 연산자를 사용하여 로 NodeLabel나열합니다.

ExposureGraphNodes
| summarize by NodeLabel

테넌트에서 모든 에지 레이블 나열

다음 쿼리는 테이블의 데이터를 ExposureGraphEdges 그룹화하고 Kusto의 summarize 연산자를 사용하여 에지 레이블(EdgeLabel)으로 나열합니다.

ExposureGraphEdges
| summarize by EdgeLabel

지정된 노드 레이블의 모든 연결 나열

다음 쿼리는 테이블의 ExposureGraphEdges 데이터를 그룹화하고 원본 노드 레이블이 microsoft.compute/virtualmachines인 경우 가상 머신의 을 로 EdgeLabel요약합니다. 보안 노출 그래프의 가상 머신에 자산을 연결하는 에지를 요약합니다.

ExposureGraphEdges
| where SourceNodeLabel == "microsoft.compute/virtualmachines"
| summarize by EdgeLabel

특정 노드 레이블에 대한 모든 연결 나열

다음 쿼리는 가상 머신을 다른 보안 노출 그래프 자산에 연결하는 에지를 요약합니다. 테이블의 데이터를 ExposureGraphEdges 그룹화하고 대상 노드 레이블이 microsoft.compute/virtualmachines인 경우 Kusto의 summarize 연산자를 사용하여 대상 노드 레이블을 로 EdgeLabel나열합니다.

ExposureGraphEdges
| where TargetNodeLabel == "microsoft.compute/virtualmachines"
| summarize by EdgeLabel

특정 노드 레이블의 속성 나열

다음 쿼리는 가상 머신 노드 레이블의 속성을 나열합니다. "microsoft.compute/virtualmachines" 결과만 표시하도록 필터링된 테이블의 데이터를 ExposureGraphNodes 그룹화합니다. 연산자를 사용하면 project-keep 쿼리가 열을 유지합니다 NodeProperties . 반환된 데이터는 한 행으로 제한됩니다.

ExposureGraphNodes
| where NodeLabel == "microsoft.compute/virtualmachines"
| project-keep NodeProperties
| take 1

노출 그래프 쿼리

노출 그래프를 쿼리하려면 다음을 수행합니다.

  1. Microsoft Defender 포털에서 헌팅 -> 고급 헌팅을 선택합니다.

  2. 쿼리 영역에 쿼리를 입력합니다. 그래프 스키마, 함수 및 연산자 테이블 또는 다음 예제를 사용하여 쿼리를 빌드할 수 있습니다.

  3. 쿼리 실행을 선택합니다.

그래프 지향 쿼리 예제

이러한 그래프 지향 쿼리 예제를 사용하여 더 나은 보안 노출 쿼리를 작성할 수 있습니다. 예제에서는 위험을 발견할 수 있는 엔터티 간의 관계를 노출하는 패턴을 검색합니다. 컨텍스트를 인시던트/경고 신호와 상호 연결하는 방법을 보여 줍니다.

특정 노드 레이블에 대한 에지가 있는 모든 노드 레이블 나열

다음 쿼리는 가상 머신 노드 레이블에 대한 커넥터가 있는 들어오는 모든 노드 레이블 목록을 생성합니다. 테이블의 열 데이터를 연산자를 사용하여 테이블 TargetNodeIdSourceNodeId 열에 ExposureGraphEdgesExposureGraphNodesmake-graph 매핑하여 그래프 구조를 빌드합니다.

그런 다음 연산자를 graph-match 사용하여 대상 노드 TargetNodeNodeLabel 가 일치하는 microsoft.compute/virtualmachines그래프 패턴을 만듭니다. project 연산자는 만 유지하는 IncomingNodeLabels데 사용됩니다. 의 결과를 IncomingNodeLabels나열합니다.

ExposureGraphEdges
| make-graph SourceNodeId --> TargetNodeId with ExposureGraphNodes
on NodeId
| graph-match (SourceNode)-[edges]->(TargetNode)
       where TargetNode.NodeLabel == "microsoft.compute/virtualmachines"
       project IncomingNodeLabels = SourceNode.NodeLabel 
| summarize by IncomingNodeLabels

특정 노드 레이블을 에지하는 모든 노드 레이블 나열

다음 쿼리는 가상 머신 노드 레이블에 대한 커넥터가 있는 모든 나가는 노드 레이블 목록을 생성합니다.

  • 연산자를 사용하여 make-graph 테이블의 데이터를 테이블 TargetNodeId 의 열 ExposureGraphNodesExposureGraphEdges 매핑 SourceNodeId 하여 그래프 구조를 빌드합니다.
  • 그런 다음 연산자를 graph-match 사용하여 및 NodeLabelSourceNode 와 일치하는 그래프 패턴을 일치microsoft.compute/virtualmachines합니다.
  • project 연산자는 만 유지하는 OutgoingNodeLabels데 사용됩니다. 의 결과를 OutgoingNodeLabels나열합니다.
ExposureGraphEdges
| make-graph SourceNodeId --> TargetNodeId with ExposureGraphNodes
on NodeId
| graph-match (SourceNode)-[edges]->(TargetNode)
       where SourceNode.NodeLabel == "microsoft.compute/virtualmachines"
       project OutgoingNodeLabels = SourceNode.NodeLabel 
| summarize by OutgoingNodeLabels

RCE 취약성으로 인터넷에 노출된 VM 검색

다음 쿼리를 사용하면 인터넷에 노출된 가상 머신과 RCE(원격 코드 실행) 취약성을 검색할 수 있습니다.

  • 스키마 테이블을 사용합니다 ExposureGraphNodes .
  • vulnerableToRCE 가 모두 NodePropertiesexposedToInternet true이면 범주()가 가상 머신(Categoriesvirtual_machine)인지 확인합니다.
ExposureGraphNodes
| where isnotnull(NodeProperties.rawData.exposedToInternet)
| where isnotnull(NodeProperties.rawData.vulnerableToRCE)
| where Categories has "virtual_machine" and set_has_element(Categories, "virtual_machine")

권한 에스컬레이션 취약성이 있는 인터넷 연결 디바이스 검색

다음 쿼리는 시스템 내에서 더 높은 수준의 권한에 대한 액세스를 허용할 수 있는 권한 에스컬레이션 취약성에 노출된 인터넷 연결 디바이스를 찾습니다.

  • 스키마 테이블을 사용합니다 ExposureGraphNodes .
  • 가 인터넷 연결() 및 VulnerableToPrivilegeEscalation인 경우 NodeProperties 쿼리는 의 Categories 항목이 실제로 디바이스(device)인지 확인합니다.IsInternetFacing
ExposureGraphNodes
| where isnotnull(NodeProperties.rawData.IsInternetFacing)
| where isnotnull(NodeProperties.rawData.VulnerableToPrivilegeEscalation)
| where set_has_element(Categories, "device")

둘 이상의 중요한 디바이스에 로그인한 모든 사용자 표시

이 쿼리는 로그인한 디바이스 수와 함께 둘 이상의 중요한 디바이스에 로그인한 사용자 목록을 생성합니다.

  • 중요도 수준이 4를 초과하는 디바이스 또는 identity로 필터링된 데이터를 사용하여 ExposureGraphNodes 테이블을 만듭니다IdentitiesAndCriticalDevices.
  • 그런 다음 연산자를 사용하여 그래프 구조를 make-graph 만듭니다. 여기서 는 EdgeLabel 입니다 Can Authenticate As.
  • 연산자를 사용하여 가 graph-match 과 일치하는 인스턴스를 device 일치합니다 identity.
  • 그런 다음 연산자를 project 사용하여 ID ID 및 디바이스 ID를 유지합니다.
  • 운영자는 mv-apply 형식별로 디바이스 ID 및 ID ID를 필터링합니다. 이를 요약하고 , 및 User Id헤더가 있는 테이블에 결과를 표시합니다Number Of devices user is logged-in to.
let IdentitiesAndCriticalDevices = ExposureGraphNodes
| where
 // Critical Device
 (set_has_element(Categories, "device") and isnotnull(NodeProperties.rawData.criticalityLevel) and NodeProperties.rawData.criticalityLevel.criticalityLevel < 4)
 // or identity
 or set_has_element(Categories, "identity");
ExposureGraphEdges
| where EdgeLabel == "Can Authenticate As"
| make-graph SourceNodeId --> TargetNodeId with IdentitiesAndCriticalDevices on NodeId
| graph-match (Device)-[canConnectAs]->(Identity)
       where set_has_element(Identity.Categories, "identity") and set_has_element(Device.Categories, "device")
       project IdentityIds=Identity.EntityIds, DeviceIds=Device.EntityIds
| mv-apply DeviceIds on (
    where DeviceIds.type == "DeviceInventoryId")
| mv-apply IdentityIds on (
    where IdentityIds.type == "SecurityIdentifier")
| summarize NumberOfDevicesUserLoggedinTo=count() by tostring(IdentityIds.id)
| where NumberOfDevicesUserLoggedinTo > 1
| project ["Number Of devices user is logged-in to"]=NumberOfDevicesUserLoggedinTo, ["User Id"]=IdentityIds_id

높은 가치의 서버에 액세스할 수 있는 중요한 취약성/사용자가 있는 클라이언트 디바이스 표시

다음 쿼리는 RCE 취약성이 있는 디바이스와 해당 디바이스 ID, 중요한 취약성이 높은 디바이스 및 해당 디바이스 ID 목록을 생성합니다.

  • 4보다 낮은 중요도가 있는 RCE 취약성이 있는 디바이스(device)와 필터링 및 패턴 일치를 통해 중요한 취약성이 있는 디바이스를 표시하는 ID(identity)가 포함된 테이블을 만듭니다IdentitiesAndCriticalDevices.
  • 목록은 에지 레이블과 CanRemoteInteractiveLogonTo가 있는 연결만 표시하도록 필터링됩니다Can Authenticate As.
let IdentitiesAndCriticalDevices = ExposureGraphNodes // Reduce the number of nodes to match
| where 
 // Critical devices & devices with RCE vulnerabilities
 (set_has_element(Categories, "device") and 
    (
        // Critical devices
        (isnotnull(NodeProperties.rawData.criticalityLevel) and NodeProperties.rawData.criticalityLevel.criticalityLevel < 4)
        or 
        // Devices with RCE vulnerability
        isnotnull(NodeProperties.rawData.vulnerableToRCE)
    )
  )
 or 
 // identity
 set_has_element(Categories, "identity");
ExposureGraphEdges
| where EdgeLabel in~ ("Can Authenticate As", "CanRemoteInteractiveLogonTo") // Reduce the number of edges to match
| make-graph SourceNodeId --> TargetNodeId with IdentitiesAndCriticalDevices on NodeId
| graph-match (DeviceWithRCE)-[CanConnectAs]->(Identity)-[CanRemoteLogin]->(CriticalDevice)
       where 
             CanConnectAs.EdgeLabel =~ "Can Authenticate As" and
             CanRemoteLogin.EdgeLabel =~ "CanRemoteInteractiveLogonTo" and
             set_has_element(Identity.Categories, "identity") and 
             set_has_element(DeviceWithRCE.Categories, "device") and isnotnull(DeviceWithRCE.NodeProperties.rawData.vulnerableToRCE) and
             set_has_element(CriticalDevice.Categories, "device") and isnotnull(CriticalDevice.NodeProperties.rawData.criticalityLevel)
       project DeviceWithRCEIds=DeviceWithRCE.EntityIds, DeviceWithRCEName=DeviceWithRCE.NodeName, CriticalDeviceIds=CriticalDevice.EntityIds, CriticalDeviceName=CriticalDevice.NodeName

특정 노드 ID에서 특정 레이블이 있는 노드로의 모든 경로 제공

이 쿼리는 가상 머신 노드 레이블에 대한 연결을 초래하는 최대 3개의 자산을 전달하는 특정 IP 노드의 경로를 표시합니다.

  • ExposureGraphEdges 스키마 테이블과 make-graphgraph-match 연산자를 사용하여 ExposureGraphNodes 그래프 구조를 만듭니다.
  • 연산자를 project 사용하면 IP ID, IP 속성, 가상 머신 ID 및 가상 머신 속성 목록이 표시됩니다.
let IPsAndVMs = ExposureGraphNodes
| where (set_has_element(Categories, "ip_address") or set_has_element(Categories, "virtual_machine"));
ExposureGraphEdges
| make-graph SourceNodeId --> TargetNodeId with IPsAndVMs on NodeId
| graph-match (IP)-[anyEdge*1..3]->(VM)
       where set_has_element(IP.Categories, "ip_address") and set_has_element(VM.Categories, "virtual_machine")
       project IpIds=IP.EntityIds, IpProperties=IP.NodeProperties.rawData, VmIds=VM.EntityIds, VmProperties=VM.NodeProperties.rawData

다음 단계

공격 표면 맵을 사용하여 탐색합니다.