Query Details
let query_period = 120d;
SecurityNestedRecommendation
| where TimeGenerated > ago(query_period) and ParentRecommendationId == "c0b7cfc6-3172-465a-b378-53c7ff2cc0d5"
| summarize hint.strategy=shuffle
StartSubAssessmentTimeGeneration = min(SubAssessmentTimeGeneration),
EndSubAssessmentTimeGeneration = arg_max(SubAssessmentTimeGeneration, *)
by Id
| extend Scanner = "MDVM - Microsoft Defender Vulnerability Management" // "c0b7cfc6-3172-465a-b378-53c7ff2cc0d5" "MDVM" "AzureContainerRegistryVulnerability"
// "dbd0cb49-b563-45e7-9724-889e799fa648" "Qualys"|"Trivy" "ContainerRegistryVulnerability"
| join hint.remote=local kind=leftouter (
arg("").ResourceContainers
| where type == "microsoft.resources/subscriptions"
| project RecommendationSubscriptionId = subscriptionId, RecommendationSubscriptionName = name
) on RecommendationSubscriptionId
| project
//TimeGenerated,
LastPushedToRegistry = todatetime(AdditionalData["ArtifactDetails"]["LastPushedToRegistryUTC"]),
StartSubAssessmentTimeGeneration,
EndSubAssessmentTimeGeneration,
Assessment_Age = bin(EndSubAssessmentTimeGeneration - StartSubAssessmentTimeGeneration, 1d)/1d,
//IsSnapshot,
//ResourceProviderType,
Scanner,
//ParentRecommendationId,
//NestedRecommendationId,
RecommendationState,
Cause,
RecommendationSeverity,
RecommendationSubscriptionId = coalesce(RecommendationSubscriptionName, RecommendationSubscriptionId),
ResourceGroup,
AssessedResourceId,
RecommendationName,
VulnerabilityId,
//Category, // Qualys
Description,
//Impact, // Qualys
RemediationDescription,
//ResourceDetails,
//Id,
//AdditionalData,
//AdditionalDataKeys = array_sort_asc(bag_keys(AdditionalData)),
CveId = AdditionalData["VulnerabilityDetails"]["CveId"],
Vulnerability_Severity = AdditionalData["VulnerabilityDetails"]["Severity"],
Vulnerability_PublishedDate = todatetime(AdditionalData["VulnerabilityDetails"]["PublishedDate"]),
Vulnerability_Age = bin(now() - todatetime(AdditionalData["VulnerabilityDetails"]["PublishedDate"]), 1d)/1d,
Vulnerability_Cvss = case(
isnotempty(AdditionalData["VulnerabilityDetails"]["Cvss"]["3.0"]), strcat(AdditionalData["VulnerabilityDetails"]["Cvss"]["3.0"]["Base"], " - ", AdditionalData["VulnerabilityDetails"]["Cvss"]["3.0"]["CvssVectorString"]),
isnotempty(AdditionalData["VulnerabilityDetails"]["Cvss"]["2.0"]), strcat(AdditionalData["VulnerabilityDetails"]["Cvss"]["2.0"]["Base"], " - ", AdditionalData["VulnerabilityDetails"]["Cvss"]["2.0"]["CvssVectorString"]),
""),
Exploit_IsInExploitKit = tobool(AdditionalData["VulnerabilityDetails"]["ExploitabilityAssessment"]["IsInExploitKit"]),
Exploit_IsPubliclyDisclosed = tobool(AdditionalData["VulnerabilityDetails"]["ExploitabilityAssessment"]["ExploitStepsPublished"]),
Exploit_IsVerified = tobool(AdditionalData["VulnerabilityDetails"]["ExploitabilityAssessment"]["ExploitStepsVerified"]),
Exploit_Types = AdditionalData["VulnerabilityDetails"]["ExploitabilityAssessment"]["Types"],
Exploit_Uris = AdditionalData["VulnerabilityDetails"]["ExploitabilityAssessment"]["ExploitUris"],
SoftwareName = AdditionalData["SoftwareDetails"]["PackageName"],
SoftwareCurrentVersion = AdditionalData["SoftwareDetails"]["Version"],
SoftwareFixedVersion = AdditionalData["SoftwareDetails"]["FixedVersion"],
//AssessedResourceType = AdditionalData["AssessedResourceType"],
//ArtifactType = AdditionalData["ArtifactDetails"]["ArtifactType"], // == "ContainerImage"
RegistryHost = AdditionalData["ArtifactDetails"]["RegistryHost"],
RepositoryName = AdditionalData["ArtifactDetails"]["RepositoryName"],
ImageDigest = AdditionalData["ArtifactDetails"]["Digest"],
ImageTags = array_sort_asc(AdditionalData["ArtifactDetails"]["Tags"]),
MediaType = AdditionalData["ArtifactDetails"]["MediaType"]
The query retrieves data from the SecurityNestedRecommendation table and filters it based on a specific time period and recommendation ID. It then summarizes the data by grouping it by ID and calculates the minimum and maximum values for a specific field. It also extends the data by adding a Scanner field and joins it with another table based on a specific condition. Finally, it projects a subset of the fields from the joined tables and performs some calculations and transformations on the data.

Jose Sebastián Canós
Released: January 3, 2024
Tables
Keywords
Operators