Microsoft Defender 脆弱性の管理に切り替える

Microsoft Defender for Cloud は、すべての脆弱性評価ソリューションを統合して、Microsoft Defender 脆弱性の管理の脆弱性スキャナーを利用しています。

Microsoft Defender 脆弱性の管理は、コンテナーのリリースやランタイムのシナリオなど、多くのクラウド ネイティブのユース ケースに統合されています。

Qualys を利用した Defender for Cloud Containers の脆弱性評価は、現在廃止されています。 Microsoft Defender 脆弱性の管理を使った Azure の脆弱性評価にまだ移行していない場合は、このページの手順に従って移行してください。

手順 1: スキャンが有効になっていることを確認する

Microsoft Defender 脆弱性の管理を利用したコンテナー脆弱性評価スキャンは、Defender for Containers、Defender for Container Registries (非推奨)、Defender Cloud Security Posture Management に対して既定で有効になっています。 これを無効にした組織は、いずれかのプランで [エージェントレス コンテナーの脆弱性評価] のトグルを再度有効にする必要があります。 これは、有効になっている前述のプランすべてに自動的に反映されます。

設定で

Microsoft Defender 脆弱性の管理スキャンを有効にする方法の詳細については、「Microsoft Defender 脆弱性の管理を利用して脆弱性評価を有効にする」を参照してください。

手順 2: (省略可能) REST API と Azure Resource Graph クエリを更新する

Azure Resource Graph (ARG) REST API、Subassessment REST API、または ARG クエリを介して、Qualys によるコンテナー脆弱性評価の結果にプログラムでアクセスしていた場合は、Microsoft Defender 脆弱性の管理で利用できる新しいコンテナー脆弱性評価に用意されている新しいスキーマや REST API に合わせて、既存のクエリを更新する必要があります。

次のセクションでは、Qualys を利用したオファリングの既存のクエリを、Microsoft Defender 脆弱性の管理を利用したオファリングを使う同等のクエリに変換するか方法を理解するのに役立つ例をいくつか紹介します。

ARG クエリのサンプル

報告に使われる Azure Resource Graph クエリがある場合は、前述した Microsoft Defender 脆弱性の管理の assessmentKeys を反映するように更新する必要があります。 Microsoft Defender 脆弱性の管理クエリへの移行に役立つ例を次に示します。

異常なコンテナー イメージを表示する

Qualys
securityresources
    | where type == "microsoft.security/assessments/subassessments"
    | extend assessmentKey = extract(".*assessments/(.+?)/.*",1,  id)
    | where assessmentKey == "dbd0cb49-b563-45e7-9724-889e799fa648"
    | project 
        Resource = tolower(extract(@'(?i)(.*?)/providers/Microsoft.Security/([^/]+)', 1, id)), 
        ResourceType = tolower(split(id,"/").[6]), 
        subscriptionId, 
        severity = properties.status.severity, 
        status = properties.status.code, 
        VulnId = properties.id, 
        description = properties.displayName, 
        patchable = properties.additionalData.patchable, 
        cve = properties.additionalData.cve, 
        Repo = properties.additionalData.repositoryName, 
        imageDigest = properties.additionalData.imageDigest
    | where status == 'Unhealthy' 
Microsoft Defender 脆弱性の管理
securityresources
    | where type == "microsoft.security/assessments/subassessments"
    | extend assessmentKey = extract(".*assessments/(.+?)/.*",1,  id)
    | where assessmentKey == "c0b7cfc6-3172-465a-b378-53c7ff2cc0d5"
    | project 
        Resource = tolower(extract(@'(?i)(.*?)/providers/Microsoft.Security/([^/]+)', 1, id)), 
        ResourceType = tolower(split(id,"/").[6]), 
        subscriptionId, 
        severity = properties.additionalData.vulnerabilityDetails.severity, 
        status = properties.status.code, 
        VulnId = properties.id, 
        description = properties.description, 
        fixStatus = properties.additionalData.softwareDetails.fixStatus, 
        Repo = properties.additionalData.artifactDetails.repositoryName, 
        imageUri = properties.resourceDetails.id
    | where status == 'Unhealthy' 

正常なコンテナー イメージを表示する

Qualys
securityresources
    | where type == "microsoft.security/assessments/subassessments"
    | extend assessmentKey = extract(".*assessments/(.+?)/.*",1,  id)
    | where assessmentKey == "dbd0cb49-b563-45e7-9724-889e799fa648"
    | project 
        Resource = tolower(extract(@'(?i)(.*?)/providers/Microsoft.Security/([^/]+)', 1, id)), 
        ResourceType = tolower(split(id,"/").[6]), 
        subscriptionId, 
        status = properties.status.code, 
        Repo = properties.additionalData.repositoryName, 
        imageDigest = properties.additionalData.imageDigest
    | where status == 'Healthy'
Microsoft Defender 脆弱性の管理
securityresources
    | where type == "microsoft.security/assessments/subassessments"
    | extend assessmentKey = extract(".*assessments/(.+?)/.*",1,  id)
    | where assessmentKey == "c0b7cfc6-3172-465a-b378-53c7ff2cc0d5"
    | project 
        Resource = tolower(extract(@'(?i)(.*?)/providers/Microsoft.Security/([^/]+)', 1, id)), 
        ResourceType = tolower(split(id,"/").[6]), 
        subscriptionId, 
        status = properties.status.code,
        Repo = properties.additionalData.artifactDetails.repositoryName, 
        imageUri = properties.resourceDetails.id
    | where status == 'Healthy' 

脆弱なイメージを重大度別にカウントする

Qualys
securityresources
    | where type == "microsoft.security/assessments/subassessments"
    | extend assessmentKey = extract(".*assessments/(.+?)/.*",1,  id)
    | extend status = tostring(parse_json(properties).status.code)
    | extend severity = tostring(parse_json(properties).status.severity)
    | extend vulId=tostring((properties).id)
    | extend Resource = tolower(extract(@'(?i)(.*?)/providers/Microsoft.Security/([^/]+)', 1, id))
    | where assessmentKey == "dbd0cb49-b563-45e7-9724-889e799fa648"
    | where status == 'Unhealthy' 
    | distinct 
        vulId, 
        severity
    | summarize count=count() by tostring(severity)
Microsoft Defender 脆弱性の管理
securityresources
    | where type == "microsoft.security/assessments/subassessments"
    | extend assessmentKey = extract(".*assessments/(.+?)/.*",1,  id)
    | extend severity = tostring(properties.additionalData.vulnerabilityDetails.severity)
    | extend status = tostring(parse_json(properties).status.code)
    | extend vulId=tostring((properties).id)
    | extend Resource = tolower(extract(@'(?i)(.*?)/providers/Microsoft.Security/([^/]+)', 1, id))
    | where assessmentKey == "c0b7cfc6-3172-465a-b378-53c7ff2cc0d5"
    | where status == 'Unhealthy' 
    | distinct 
        vulId, 
        severity
    | summarize count=count() by tostring(severity)

AKS クラスター上で実行されている脆弱なイメージのポッド、コンテナー、名前空間を表示する

Qualys
securityresources 
| where type =~ "microsoft.security/assessments/subassessments"
| extend assessmentKey = extract(@"(?i)providers/Microsoft.Security/assessments/([^/]*)", 1, id),
         subAssessmentId = tostring(properties.id),
         parentResourceId = extract("(.+)/providers/Microsoft.Security", 1, id)
| extend resourceId = extract(@'(?i)(.*?)@([^/]+)', 1,tostring(properties.resourceDetails.id))
| extend severity = tostring(parse_json(properties).status.severity)
| extend VulnId = tostring(parse_json(properties).id)
| extend status = tostring(parse_json(properties).status.code)
| where assessmentKey == "41503391-efa5-47ee-9282-4eff6131462c"
| extend resourceId = tostring(properties.resourceDetails.id),
         parsedJson = parse_json(tostring(properties.additionalData))
| extend containerData = parse_json(tostring(parsedJson.data.Containers))
| mv-expand containerDetails = containerData to typeof(dynamic)
| extend ContainerName = tostring(containerDetails.Name),
         ContainerPod = tostring(containerDetails.Pod.Name),
         Namespace = tostring(containerDetails.Pod.Namespace),
         ControllerType = tostring(containerDetails.Pod.ControllerType),
         ControllerName = tostring(containerDetails.Pod.ControllerName)
| where status == 'Unhealthy'
|project Image=resourceId, VulnId,severity, Namespace, ContainerName, ContainerPod,ControllerName,ControllerType

Microsoft Defender 脆弱性の管理
securityresources 
| where type =~ "microsoft.security/assessments/subassessments"
| extend assessmentKey=extract(@"(?i)providers/Microsoft.Security/assessments/([^/]*)", 1, id)
| where assessmentKey == "c0b7cfc6-3172-465a-b378-53c7ff2cc0d5" 
| extend azureClusterId = tostring(properties.additionalData.clusterDetails.clusterResourceId)
| extend cve =tostring(properties.id)
| extend status = properties.status.code
| extend severity=tostring(parse_json(properties).additionalData.vulnerabilityDetails.severity)
| where status == "Unhealthy"
| extend azureImageId = tostring(properties.resourceDetails.id)
| extend severity = tolower(properties.additionalData.vulnerabilityDetails.severity)
| extend kubernetesContext = properties.additionalData.kubernetesContext
| mv-expand workload = kubernetesContext.workloads
| mv-expand OwnedResource = workload.ownedResources
| mv-expand OwnedContainer = OwnedResource.containers                    
| mv-expand Container = workload.containers                    
| extend isController = isnotempty(workload.ownedResources)
| extend namespace =  tostring(workload.namespace)
| extend podName = iff(isController, tostring(OwnedResource.name), workload.name)
| extend containerName = iff(isController, tostring(OwnedContainer.name), Container.name)
| extend controllerName =  iff(isController, tostring(workload.name),"") 
| extend controllerType =  iff(isController, tostring(workload.kind),"")                       
| extend imageName = extract("(.+)@sha256:", 1, azureImageId) 
| project imageName, cve, severity, clusterId = azureClusterId, containerName, podName, controllerName, controllerType, namespace

手順 3: (省略可能) コンテナー セキュリティ レポート

Microsoft Defender for Cloud には、Container Security ブックなど、Azure ブックで既定値のまま使用できるレポートが用意されています。

Container Security ブックのスクリーンショット。

このブックには、レジストリとランタイムの両方からのコンテナーの脆弱性スキャン結果が含まれています。

コンテナー脆弱性スキャンの結果を含むブックのスクリーンショット。

このブックには、Microsoft Defender 脆弱性の管理スキャンの結果が表示され、Azure Registry コンテナー イメージ内で検出された脆弱性の包括的な概要が提供されます。 コンテナーのセキュリティ ブックには、コンテナーの脆弱性評価について次の利点があります。

  • すべての脆弱性の概要: Azure コンテナー レジストリ全体で検出され、AKS クラスター上で実行されているすべての脆弱性を表示します。

  • 悪用可能な脆弱性ダッシュボード: 既知の悪用による脆弱性を強調表示する専用セクション。セキュリティ チームはこれを使って悪用のリスクが高い脆弱性に焦点を当てることができます。 これは、Microsoft Defender 脆弱性の管理を使ったコンテナー脆弱性評価スキャンでのみ使用できます。

    悪用可能な脆弱性ダッシュボードのスクリーンショット。

  • その他の ARG クエリ: このブックを使うと、Qualys と Microsoft Defender 脆弱性の管理の間で ARG データのクエリを実行する方法の例をさらに確認できます。 ブックの編集方法の詳細については、Microsoft Defender for Cloud のブック ギャラリーを参照してください。

次のステップ