Query vulnerable VMs against Log4Shell vulnerability in Azure

I was asked from people if Microsoft Defender for Cloud had any information related to the CVE-2021-44228 (Log4Shell) vulnerability which is currently the hottest vulnerability right now.

In this article, I would like to share a Resource Graph Query to find virtual machines that are vulnerable against Log4Shell vulnerability.

Currently there are several vulnerability solutions that are supported to send data to Microsoft Defender for Cloud. Some common ones include Qualys (built-in vulnerability assessment) and Rapid 7. Log Analytics Agent would also report missing security patches on virtual machines.

securityresources
| where type == "microsoft.security/assessments/subassessments"
// Parse main assessment
| extend data = properties.additionalData,
         displayName = properties.displayName,
         resourceId  = properties.resourceDetails.id,
         timeGenerated = properties.timeGenerated,
         severity = properties.status.severity,
         statusCode = properties.status.code
| extend assessedResourceType = tostring(data.assessedResourceType),
         source = data.source
| mv-expand cves = data['cve']
| extend cve_number = cves['title'],
         cve_link_ref = cves['link']
| extend resourceName = split(resourceId,'/')[8],
         resourceGroup = split(resourceId,'/')[4],
         subscriptionId = split(resourceId,'/')[2]
| where assessedResourceType  == "ServerVulnerability"
| where cve_number == "CVE-2021-44228"
| project resourceName,
          resourceGroup, 
          subscriptionId, 
          displayName, 
          cve_number, 
          cve_link_ref, 
          data, 
          properties

This query works with VMs that have built-in vulnerability assessment solution aka Qualys installed. However you can modify the query to add another source such as Rapid 7 or data from UpdateManagement solution.

By the way, you can check from Microsoft Defender for Cloud under recommendation named “Machines should have vulnerability findings resolved“.

AzSec is working on a complete query to cover other sources. Right now if you have built-in VA you can test on your environment.

Use the following query to search data from Rapid 7, Qualys or UpdateManagement

securityresources
| where type == "microsoft.security/assessments/subassessments"
// Parse main assessment
| extend data = properties.additionalData,
         displayName = properties.displayName,
         resourceId  = properties.resourceDetails.id,
         timeGenerated = properties.timeGenerated,
         severity = properties.status.severity,
         statusCode = properties.status.code
| extend assessedResourceType = tostring(data.assessedResourceType),
         source = data.source
| mv-expand cves = data['cve']
| extend cveNumber = cves['title'],
         cveRef = cves['link']
| extend resourceName = split(resourceId,'/')[8],
         resourceGroup = split(resourceId,'/')[4],
         subscriptionId = split(resourceId,'/')[2]
// Filter for Qualys (built-in ASC Vulnerability Assessment) and Rapid 7 
| where assessedResourceType  == "ServerVulnerability"
| project resourceId,
          displayName, 
          cveNumber, 
          cveRef, 
          data, 
          properties
| union (
    securityresources
    | where type == "microsoft.security/assessments/subassessments"
    // Parse main assessment for Update Management 
    | extend data = properties.additionalData,
            displayName = properties.displayName,
            resourceId  = properties.resourceDetails.id,
            timeGenerated = properties.timeGenerated,
            severity = properties.status.severity,
            statusCode = properties.status.code
    // Parse assessment data
    | extend assessedResourceType = tostring(data.assessedResourceType),
             packageRepository = data.PackageRepository,
             cveNumber = data.data.CVENumbers,
             product = data.data.Product,
             OsType = data.data.OsType,
             cveRef = data.data.BulletinUrl
    // Filter for UpdateManagement
    | where assessedResourceType == "GeneralVulnerability"
    | extend resourceName = split(resourceId,'/')[8],
             resourceGroup = split(resourceId,'/')[4],
             subscriptionId = split(resourceId,'/')[2]
    | project resourceId,
          displayName, 
          cveNumber, 
          cveRef, 
          data, 
          properties
)
// Search for CVEs
| where cveNumber in ("CVE-2021-44228", "CVE-2021-45046")
| extend resourceName = split(resourceId,'/')[8],
             resourceGroup = split(resourceId,'/')[4],
             subscriptionId = split(resourceId,'/')[2]
| summarize cveLists = make_list(cveNumber) by tostring(resourceId)
| extend resourceName = split(resourceId,'/')[8],
         resourceGroup = split(resourceId,'/')[4],
         subscriptionId = tostring(split(resourceId,'/')[2])
| join kind=leftouter(
    resourcecontainers 
    | where type=='microsoft.resources/subscriptions' 
    | project subscriptionName=name, subscriptionId
) on subscriptionId

If you are working on Azure environment, I’d highly recommend you to check this article from Microsoft MSRC

This entry was posted in Security Automation and tagged , . Bookmark the permalink.

Leave a Reply

Your email address will not be published.