Microsoft 보안 노출 관리 엔터프라이즈 노출 그래프를 사용하여 Microsoft Defender 포털의 고급 헌팅에서 엔드포인트, 클라우드 환경 및 하이브리드 인프라에서 엔터프라이즈 노출 위협을 사전에 헌팅합니다. Defender 포털에서 클라우드용 Defender의 통합을 통해 노출 그래프에는 이제 Azure, AWS 및 GCP 환경의 클라우드 노드 유형 및 엔터티가 포함됩니다.
이 문서에서는 엔터프라이즈 노출 그래프에서 쿼리를 생성하기 위한 몇 가지 예제, 팁 및 힌트를 제공합니다.
필수 구성 요소
- 공격 표면 관리에 대해 읽어보세요.
- 그래프 작업에 필요한 권한을 검토합니다.
고급 헌팅 쿼리 빌드
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_elementisempty는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요약합니다. 보안 노출 그래프의 가상 머신에 자산을 연결하는 에지를 요약합니다. Defender 포털에서 클라우드용 Defender가 통합되면 이제 여러 환경의 클라우드 리소스가 포함됩니다.
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 . 반환된 데이터는 한 행으로 제한됩니다. Defender 포털에서 클라우드용 Defender가 통합된 NodeProperties에는 이제 추가 클라우드별 특성 및 관계가 포함됩니다.
ExposureGraphNodes
| where NodeLabel == "microsoft.compute/virtualmachines"
| project-keep NodeProperties
| take 1
예: 여러 환경에서 클라우드 리소스 쿼리
다음 쿼리는 이제 Defender 포털에서 클라우드용 Defender 통합을 사용하여 사용할 수 있는 다양한 환경의 클라우드 리소스를 쿼리하는 방법을 보여 줍니다.
ExposureGraphNodes
| where NodeLabel contains "microsoft.compute" or NodeLabel contains "aws." or NodeLabel contains "gcp."
| summarize count() by NodeLabel
| order by count_ desc
노출 그래프 쿼리
노출 그래프를 쿼리하려면 다음을 수행합니다.
Microsoft Defender 포털에서 헌팅 -> 고급 헌팅을 선택합니다.
쿼리 영역에 쿼리를 입력합니다. 그래프 스키마, 함수 및 연산자 테이블 또는 다음 예제를 사용하여 쿼리를 빌드할 수 있습니다.
쿼리 실행을 선택합니다.
그래프 지향 쿼리 예제
이러한 그래프 지향 쿼리 예제를 사용하여 더 나은 보안 노출 쿼리를 작성할 수 있습니다. 예제에서는 위험을 발견할 수 있는 엔터티 간의 관계를 노출하는 패턴을 검색합니다. 컨텍스트를 인시던트/경고 신호와 상호 연결하는 방법을 보여 줍니다.
특정 노드 레이블에 대한 에지가 있는 모든 노드 레이블 나열
다음 쿼리는 가상 머신 노드 레이블에 대한 커넥터가 있는 들어오는 모든 노드 레이블 목록을 생성합니다. 테이블의 열 데이터를 연산자를 사용하여 테이블 TargetNodeId 의 SourceNodeId 열에 ExposureGraphEdgesExposureGraphNodesmake-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가 모두NodePropertiesexposedToInternettrue이면 범주()가 가상 머신(Categoriesvirtual_machine)인지 확인합니다. - Defender 포털에서 클라우드용 Defender가 통합되면 이제 Azure, AWS 및 GCP 환경의 VM이 포함됩니다.
ExposureGraphNodes
| where isnotnull(NodeProperties.rawData.exposedToInternet)
| where isnotnull(NodeProperties.rawData.vulnerableToRCE)
| where Categories has "virtual_machine" and set_has_element(Categories, "virtual_machine")
예: 클라우드와 온-프레미스 자산 간의 하이브리드 공격 경로 찾기
다음 쿼리는 Defender 포털에서 클라우드용 Defender의 통합을 통해 잠재적인 하이브리드 공격 경로를 식별하는 방법을 보여 줍니다.
let CloudAssets = ExposureGraphNodes
| where Categories has "virtual_machine" and (NodeLabel contains "microsoft.compute" or NodeLabel contains "aws." or NodeLabel contains "gcp.");
let OnPremAssets = ExposureGraphNodes
| where Categories has "device" and not(NodeLabel contains "microsoft.compute" or NodeLabel contains "aws." or NodeLabel contains "gcp.");
ExposureGraphEdges
| make-graph SourceNodeId --> TargetNodeId with ExposureGraphNodes on NodeId
| graph-match (CloudVM)-[edge1]->(Identity)-[edge2]->(OnPremDevice)
where set_has_element(CloudVM.Categories, "virtual_machine") and
(CloudVM.NodeLabel contains "microsoft.compute" or CloudVM.NodeLabel contains "aws." or CloudVM.NodeLabel contains "gcp.") and
set_has_element(Identity.Categories, "identity") and
set_has_element(OnPremDevice.Categories, "device") and
not(OnPremDevice.NodeLabel contains "microsoft.compute" or OnPremDevice.NodeLabel contains "aws." or OnPremDevice.NodeLabel contains "gcp.")
project CloudVMName=CloudVM.NodeName, IdentityName=Identity.NodeName, OnPremDeviceName=OnPremDevice.NodeName
권한 에스컬레이션 취약성이 있는 인터넷 연결 디바이스 검색
다음 쿼리는 시스템 내에서 더 높은 수준의 권한에 대한 액세스를 허용할 수 있는 권한 에스컬레이션 취약성에 노출된 인터넷 연결 디바이스를 찾습니다.
- 스키마 테이블을 사용합니다
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
다음 단계
공격 표면 맵을 사용하여 탐색합니다.