Query Details
// Use here: https://portal.azure.com/#view/HubsExtension/ArgQueryBlade
SecurityResources
| where type =~ "microsoft.security/assessments/subassessments" and id has "providers/Microsoft.ContainerRegistry/registries/"
| extend assessedResourceType = tostring(properties["additionalData"]["assessedResourceType"])
| where assessedResourceType == "AzureContainerRegistryVulnerability"
| extend
//source = tostring(properties["resourceDetails"]["source"]), // == "Azure"
timeGenerated = todatetime(properties["timeGenerated"]),
status = tostring(properties["status"]["code"]),
statusCause = tostring(properties["status"]["cause"]),
statusDescription = tostring(properties["status"]["description"]),
assessmentId = tostring(properties["id"]),
assessmentDisplayName = tostring(properties["displayName"]),
assessmentSeverity = tostring(properties["status"]["severity"]),
assessmentDescription = tostring(properties["description"]),
//assessmentCvssv3 = tostring(properties["additionalData"]["cvssV30Score"]), // == cvssv3
assessmentRemediation = tostring(properties["remediation"]),
cveId = tostring(properties["additionalData"]["vulnerabilityDetails"]["cveId"]),
vulnerabilitySeverity = tostring(properties["additionalData"]["vulnerabilityDetails"]["severity"]),
cvssv2 = tostring(properties["additionalData"]["vulnerabilityDetails"]["cvss"]["2.0"]["base"]),
cvssv2Vector = tostring(properties["additionalData"]["vulnerabilityDetails"]["cvss"]["2.0"]["cvssVectorString"]),
cvssv3 = tostring(properties["additionalData"]["vulnerabilityDetails"]["cvss"]["3.0"]["base"]),
cvssv3Vector = tostring(properties["additionalData"]["vulnerabilityDetails"]["cvss"]["3.0"]["cvssVectorString"]),
hasPublicExploit = toboolean(properties["additionalData"]["vulnerabilityDetails"]["exploitabilityAssessment"]["exploitStepsPublished"]),
isExploitVerified = toboolean(properties["additionalData"]["vulnerabilityDetails"]["exploitabilityAssessment"]["exploitStepsVerified"]),
isExploitInKit = toboolean(properties["additionalData"]["vulnerabilityDetails"]["exploitabilityAssessment"]["isInExploitKit"]),
exploitTypes = strcat_array(properties["additionalData"]["vulnerabilityDetails"]["exploitabilityAssessment"]["types"], ", "),
cpePart = tostring(properties["additionalData"]["vulnerabilityDetails"]["cpe"]["part"]),
//artifactType = tostring(properties["additionalData"]["artifactDetails"]["artifactType"]), // == "ContainerImage"
mediaType = tostring(properties["additionalData"]["artifactDetails"]["mediaType"]),
registryHost = tostring(properties["additionalData"]["artifactDetails"]["registryHost"]),
repositoryName = tostring(properties["additionalData"]["artifactDetails"]["repositoryName"]),
imageDigest = tostring(properties["additionalData"]["artifactDetails"]["digest"]),
imageTimePushed = todatetime(properties["additionalData"]["artifactDetails"]["lastPushedToRegistryUTC"]),
imageOsPlatform = tostring(properties["additionalData"]["softwareDetails"]["osDetails"]["osPlatform"]),
imageOsVersion = tostring(properties["additionalData"]["softwareDetails"]["osDetails"]["osVersion"]),
softwareCategory = tostring(properties["additionalData"]["softwareDetails"]["category"]),
softwareLanguage = tostring(properties["additionalData"]["softwareDetails"]["language"]),
softwareVendor = tostring(properties["additionalData"]["softwareDetails"]["vendor"]),
softwareName = tostring(properties["additionalData"]["softwareDetails"]["packageName"]),
softwareVersion = tostring(properties["additionalData"]["softwareDetails"]["version"]),
//softwareFixStatus = tostring(properties["additionalData"]["softwareDetails"]["fixStatus"]), // == "FixAvailable"
softwareFixVersion = tostring(properties["additionalData"]["softwareDetails"]["fixedVersion"]),
softwareEvidence = tostring(properties["additionalData"]["softwareDetails"]["evidence"][0]),
resourceId = tostring(properties["resourceDetails"]["id"])
| extend hasExploit = hasPublicExploit or isExploitVerified or isExploitInKit or isnotempty(exploitTypes)
| project resourceId, tenantId, subscriptionId, location, resourceGroup, assessedResourceType, timeGenerated, status, statusCause, statusDescription, assessmentId, assessmentDisplayName, assessmentSeverity, assessmentDescription, assessmentRemediation, cveId, vulnerabilitySeverity, cvssv2, cvssv2Vector, cvssv3, cvssv3Vector, hasExploit, hasPublicExploit, isExploitVerified, isExploitInKit, exploitTypes, cpePart, mediaType, registryHost, repositoryName, imageDigest, imageTimePushed, imageOsPlatform, imageOsVersion, softwareCategory, softwareLanguage, softwareVendor, softwareName, softwareVersion, softwareFixVersion, softwareEvidence
| summarize
SoftwareVersions = make_list(pack(
"AssessmentRemediation", assessmentRemediation,
"SoftwareVersion", softwareVersion,
"SoftwareFixVersion", softwareFixVersion
)),
arg_max(timeGenerated, location, resourceGroup, assessedResourceType, status, statusCause, statusDescription, assessmentDisplayName, assessmentSeverity, assessmentDescription, cveId, vulnerabilitySeverity, cvssv2, cvssv2Vector, cvssv3, cvssv3Vector, hasExploit, hasPublicExploit, isExploitVerified, isExploitInKit, exploitTypes, cpePart, mediaType, repositoryName, imageDigest, imageTimePushed, imageOsPlatform, imageOsVersion, softwareCategory, softwareLanguage, softwareVendor, softwareEvidence)
by tenantId, subscriptionId, registryHost, resourceId, assessmentId, softwareName
| summarize
VulnerableSoftware = make_list(pack(
"SoftwareName", softwareName,
"SoftwareVersions", SoftwareVersions,
"SoftwareVendor", softwareVendor,
"SoftwareCategory", softwareCategory,
"SoftwareLanguage", softwareLanguage,
"SoftwareEvidence", softwareEvidence
)),
arg_max(timeGenerated, location, resourceGroup, assessedResourceType, status, statusCause, statusDescription, assessmentDisplayName, assessmentSeverity, assessmentDescription, cveId, vulnerabilitySeverity, cvssv2, cvssv2Vector, cvssv3, cvssv3Vector, hasExploit, hasPublicExploit, isExploitVerified, isExploitInKit, exploitTypes, cpePart, mediaType, repositoryName, imageDigest, imageTimePushed, imageOsPlatform, imageOsVersion)
by tenantId, subscriptionId, registryHost, resourceId, assessmentId
| summarize
Vulnerabilities = make_list(pack(
"CVE", cveId,
"Severity", vulnerabilitySeverity,
"assessmentDescription", assessmentDescription,
"CVSSv2", cvssv2,
"CVSSv3", cvssv3,
"HasExploit", hasExploit,
"VulnerableSoftware", VulnerableSoftware
)),
ImageOsPlatform = make_set(imageOsPlatform),
ImageOsVersion = make_set(imageOsVersion),
HasExploitableVulnerability = binary_all_or(tolong(hasExploit)),
arg_max(timeGenerated, location, resourceGroup, assessedResourceType, status, statusCause, statusDescription, mediaType, repositoryName, imageDigest, imageTimePushed, imageOsPlatform, imageOsVersion)
by tenantId, subscriptionId, registryHost, resourceId
| extend Vulnerabilities = iff(status == "Unhealthy", Vulnerabilities, dynamic(null))
| join kind=leftouter (
ResourceContainers
| where type == "microsoft.resources/subscriptions"
| project subscriptionId, subscriptionName = name
) on subscriptionId
| project
resourceId,
tenantId,
subscriptionId,
subscriptionName,
location,
resourceGroup,
assessedResourceType,
status,
statusCause,
statusDescription,
mediaType,
registryHost,
repositoryName,
imageDigest,
imageTimePushed,
ImageOsPlatform,
ImageOsVersion,
HasExploitableVulnerability//,
//Vulnerabilities
The query retrieves information about vulnerabilities in Azure Container Registries. It includes details such as the assessment status, severity, description, and remediation steps for each vulnerability. It also provides information about the software versions, vendors, and categories affected by the vulnerabilities. The query summarizes the data by grouping it based on the tenant, subscription, registry, and assessment. It also determines if there are any exploitable vulnerabilities and identifies the operating system platforms and versions associated with the vulnerable images. The final result includes information about the resource, subscription, location, and other relevant details.

Jose Sebastián Canós
Released: October 4, 2023
Tables
Keywords
Operators