Query Details

Security Nested Recommendation Running Container Image MDVM Vulnerability Assessments

Query

let query_period = 120d;
SecurityNestedRecommendation
| where TimeGenerated > ago(query_period) and ParentRecommendationId == "c609cf0f-71ab-41e9-a3c6-9a1f7fe1b8d5"
| summarize hint.strategy=shuffle
    StartSubAssessmentTimeGeneration = min(SubAssessmentTimeGeneration),
    EndSubAssessmentTimeGeneration = arg_max(SubAssessmentTimeGeneration, *)
    by Id
| extend Scanner = "MDVM - Microsoft Defender Vulnerability Management" // AzureRuntimeImageVulnerability
//"41503391-efa5-47ee-9282-4eff6131462c" "Qualys" // GeneralVulnerability
| join hint.remote=local kind=leftouter (
    arg("").ResourceContainers
    | where type == "microsoft.resources/subscriptions"
    | project RecommendationSubscriptionId = subscriptionId, RecommendationSubscriptionName = name
    ) on RecommendationSubscriptionId
| project
    //TimeGenerated,
    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"]["IsPubliclyDisclosed"]),
    Exploit_IsVerified = tobool(AdditionalData["VulnerabilityDetails"]["ExploitabilityAssessment"]["IsVerified"]),
    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"]),
    ClusterResourceId = AdditionalData["ClusterDetails"]["ClusterResourceId"],
    KubernetesContext = AdditionalData["KubernetesContext"]

Explanation

The query retrieves data from the SecurityNestedRecommendation table and filters it based on a specific time period and ParentRecommendationId. It then summarizes the data by grouping it by Id and calculates the minimum and maximum values of the SubAssessmentTimeGeneration field. The query also joins the data with the ResourceContainers table and projects specific columns from both tables. Finally, it projects various columns from the joined data, performs calculations on some columns, and renames some columns for better readability.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: December 29, 2023

Tables

SecurityNestedRecommendationarg("")

Keywords

Keywords:SecurityNestedRecommendation,TimeGenerated,StartSubAssessmentTimeGeneration,EndSubAssessmentTimeGeneration,Assessment_Age,Scanner,RecommendationState,Cause,RecommendationSeverity,RecommendationSubscriptionId,ResourceGroup,AssessedResourceId,RecommendationName,VulnerabilityId,Description,RemediationDescription,CveId,Vulnerability_Severity,Vulnerability_PublishedDate,Vulnerability_Age,Vulnerability_Cvss,Exploit_IsInExploitKit,Exploit_IsPubliclyDisclosed,Exploit_IsVerified,SoftwareName,SoftwareCurrentVersion,SoftwareFixedVersion,RegistryHost,RepositoryName,ImageDigest,ImageTags,ClusterResourceId,KubernetesContext

Operators

whereand==summarizehint.strategyminarg_maxbyextendjoinhint.remote=localkind=leftouterarg("")wheretypeprojectonprojectbin/isnotemptystrcatcasetobooltodatetimenow""coalescearray_sort_ascbag_keys

Actions