Query Details
// Use here: https://portal.azure.com/#view/HubsExtension/ArgQueryBlade
SecurityResources
| where type =~ "microsoft.security/assessments/subassessments" and id has "providers/Microsoft.Compute/virtualMachines"
| extend assessedResourceType = tostring(properties["additionalData"]["assessedResourceType"])
| where assessedResourceType == "ServerVulnerabilityTvm" // thus source == "Microsoft Defender vulnerability management"
| extend
source = tostring(properties["additionalData"]["source"]), // scanner
timeGenerated = todatetime(properties["timeGenerated"]),
status = tostring(properties["status"]["code"]),
category = tostring(properties["category"]),
assessmentDisplayName = tostring(properties["displayName"]),
assessmentDescription = tostring(properties["description"]),
assessmentCvssv3 = tostring(properties["additionalData"]["cvssV30Score"]),
assessmentSeverity = tostring(properties["status"]["severity"]),
softwareVendor = tostring(properties["additionalData"]["softwareVendor"]),
softwareName = tostring(properties["additionalData"]["softwareName"]),
softwareVersion = tostring(properties["additionalData"]["softwareVersion"]),
recommendedVendor = tostring(properties["additionalData"]["recommendedVendor"]),
recommendedProgram = tostring(properties["additionalData"]["recommendedProgram"]),
recommendedVersion = tostring(properties["additionalData"]["recommendedVersion"]),
resourceId = tostring(properties["resourceDetails"]["id"]),
assessmentId = tostring(properties["id"]),
cve = properties["additionalData"]["cve"]
| mv-expand cve = iff(array_length(cve) == 0, dynamic([""]), cve)
| extend
cve,
description = tostring(cve["description"]),
severity = tostring(cve["severity"]),
cvss = tostring(cve["cvssScore"]),
cvssVersion = toint(cve["cvssVersion"]),
hasPublicExploit = toboolean(cve["hasPublicExploit"]),
isExploitVerified = toboolean(cve["isExploitVerified"]),
isExploitInKit = toboolean(cve["isExploitInKit"]),
exploitabilityLevel = tostring(cve["exploitabilityLevel"]),
exploitTypes = strcat_array(cve["exploitTypes"], ", "),
isZeroDay = toboolean(cve["isZeroDay"])
| extend
cve = tostring(cve["title"]),
cvssv2 = iff(cvssVersion == 2, cvss, ""),
cvssv3 = iff(cvssVersion == 3, cvss, ""),
hasExploit = exploitabilityLevel != "NoExploit"
| sort by isExploitInKit desc, isExploitVerified desc, hasPublicExploit desc
| project timeGenerated, resourceId, tenantId, subscriptionId, location, resourceGroup, assessedResourceType, source, status, category, assessmentDisplayName, assessmentDescription, assessmentCvssv3, assessmentSeverity, softwareVendor, softwareName, softwareVersion, recommendedVendor, recommendedProgram, recommendedVersion, assessmentId, cve, description, severity, cvssv2, cvssv3, hasPublicExploit, isExploitVerified, isExploitInKit, exploitabilityLevel, exploitTypes, isZeroDay, hasExploit
| summarize
Scanners = make_set(source),
Vulnerabilities = make_list(pack(
"CVE", cve,
"Description", description,
"Severity", severity,
"CVSSv2", cvssv2,
"CVSSv3", cvssv3,
"HasExploit", hasExploit,
// "HasPublicExploit", hasPublicExploit,
// "IsExploitVerified", isExploitVerified,
// "IsExploitInKit", isExploitInKit,
// "ExploitTypes", exploitTypes,
// "IsZeroDay", isZeroDay
"AssessmentDisplayName", assessmentDisplayName,
"AssessmentId", assessmentId
)),
HasExploitableVulnerability = binary_all_or(tolong(hasExploit)),
arg_max(timeGenerated, subscriptionId, location, resourceGroup, assessedResourceType, assessmentDisplayName, assessmentDescription, assessmentSeverity, assessmentCvssv3)
by category, status, tenantId, resourceId, assessmentId
| summarize
Scanners = make_set(Scanners),
Vulnerabilities = make_list(Vulnerabilities),
AssessmentsDisplayNames = strcat_array(make_list(assessmentDisplayName), ", "),
AssessmentsCVSSv3 = max(toreal(assessmentCvssv3)),
HasExploitableVulnerability = binary_all_or(tolong(HasExploitableVulnerability)),
arg_max(timeGenerated, subscriptionId, location, resourceGroup, assessedResourceType)
by category, status, tenantId, resourceId
| join kind=leftouter (
ResourceContainers
| where type == "microsoft.resources/subscriptions"
| project subscriptionId, subscriptionName = name
) on subscriptionId
| sort by tenantId asc, subscriptionName asc, status asc, resourceId asc
| project
resourceId,
tenantId,
subscriptionId,
subscriptionName,
location,
resourceGroup,
assessedResourceType,
Scanners,
status,
category,
AssessmentsDisplayNames,
AssessmentsCVSSv3,
HasExploitableVulnerability,
Vulnerabilities
This query retrieves security assessment information for virtual machines in Azure. It filters the results to only include assessments related to server vulnerabilities. The query then expands the information about each vulnerability, including its description, severity, and CVSS scores. It also includes information about the software affected by the vulnerability and any recommended actions. The results are sorted based on the presence of exploits and other factors. Finally, the query summarizes the data by category, status, tenant, and resource, and joins it with subscription information. The final result includes details about the resource, tenant, subscription, location, and assessment information.

Jose Sebastián Canós
Released: September 5, 2023
Tables
Keywords
Operators