엔터프라이즈 노출 그래프 쿼리
Microsoft 보안 노출 관리 엔터프라이즈 노출 그래프를 사용하여 Microsoft Defender 포털의 고급 헌팅에서 엔터프라이즈 노출 위협을 사전에 헌팅합니다.
이 문서에서는 엔터프라이즈 노출 그래프에서 쿼리를 생성하기 위한 몇 가지 예제, 팁 및 힌트를 제공합니다.
필수 구성 요소
- 공격 표면 관리에 대해 읽어보세요.
- 그래프 작업에 필요한 권한을 검토합니다.
고급 헌팅 쿼리 빌드
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
..
동적 열 및 스마트 인덱싱 사용
NodeProperties
및 Categories
는 동적 열입니다.
- Kusto는 해당 열에 json과 유사한 콘텐츠가 포함되어 있으며 스마트 인덱싱을 적용합니다.
- 그러나 모든 Kusto 연산자가 인덱스를 사용하는 것은 아닙니다. 예를 들어 ,
set_has_element
isempty
는isnotnull
인덱스가 동적 열에 적용되고isnotnull(Properties["containsSensitiveData"]
인덱스는 사용하지 않을 때 사용하지 않습니다. - 대신 항상 인덱스 사용
has()
연산자를 사용합니다.
예제
다음 쿼리에서 연산자는 has
문자열 set_has_element
을 data
확인하고 요소를 확인합니다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
노출 그래프 쿼리
노출 그래프를 쿼리하려면 다음을 수행합니다.
Microsoft Defender 포털에서 헌팅 -> 고급 헌팅을 선택합니다.
쿼리 영역에 쿼리를 입력합니다. 그래프 스키마, 함수 및 연산자 테이블 또는 다음 예제를 사용하여 쿼리를 빌드할 수 있습니다.
쿼리 실행을 선택합니다.
그래프 지향 쿼리 예제
이러한 그래프 지향 쿼리 예제를 사용하여 더 나은 보안 노출 쿼리를 작성할 수 있습니다. 예제에서는 위험을 발견할 수 있는 엔터티 간의 관계를 노출하는 패턴을 검색합니다. 컨텍스트를 인시던트/경고 신호와 상호 연결하는 방법을 보여 줍니다.
특정 노드 레이블에 대한 에지가 있는 모든 노드 레이블 나열
다음 쿼리는 가상 머신 노드 레이블에 대한 커넥터가 있는 들어오는 모든 노드 레이블 목록을 생성합니다. 테이블의 열 데이터를 연산자를 사용하여 테이블 TargetNodeId
의 SourceNodeId
열에 ExposureGraphEdges
ExposureGraphNodes
make-graph
매핑하여 그래프 구조를 빌드합니다.
그런 다음 연산자를 graph-match
사용하여 대상 노드 TargetNode
와 NodeLabel
가 일치하는 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
의 열ExposureGraphNodes
에ExposureGraphEdges
매핑SourceNodeId
하여 그래프 구조를 빌드합니다. - 그런 다음 연산자를
graph-match
사용하여 및NodeLabel
가SourceNode
와 일치하는 그래프 패턴을 일치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
가 모두NodeProperties
exposedToInternet
true이면 범주()가 가상 머신(Categories
virtual_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-graph
및graph-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
다음 단계
공격 표면 맵을 사용하여 탐색합니다.