Microsoft Entra Suite Tech Accelerator
Aug 14 2024, 07:00 AM - 09:30 AM (PDT)
Microsoft Tech Community
Guidance for handling “regreSSHion” (CVE-2024-6387) using Microsoft Security capabilities
Published Jul 08 2024 02:09 PM 7,249 Views
Microsoft

Investigating and assessing vulnerabilities within the software inventory is crucial, especially in light of high-severity vulnerabilities like the recent OpenSSH regreSSHion vulnerability. Such security risks are becoming increasingly common, often exploiting software dependencies and third-party services. The notoriety of incidents like the TeamViewer breach and the XZ Utils backdoor underscores the urgency for comprehensive vulnerability management and strategies to minimize the attack surface. In this blog post, we delve into the methodology for probing such incidents. We will demonstrate how organizations can harness the capabilities of Attack Path analysis together with Microsoft Defender suite of products to pinpoint and neutralize threats arising from such events. Our examination will center on: mapping vulnerabilities, evaluating affected assets, gauging potential impact via blast radius analysis, and implementing efficacious mitigations. 

 

Mapping Vulnerabilities and Impacted Assets 

The first step in managing an incident is to map affected software within your organization’s assets. Defender Vulnerability Management solution provides a comprehensive vulnerability assessment across all your devices.

 

Example: Mapping the regreSSHion vulnerability 

To map the presence of the regreSSHion vulnerability (CVE-2024-6387) in your environment, you can use the following KQL query in Advanced Hunting in Microsoft Defender portal:

 

 

 

 

DeviceTvmSoftwareVulnerabilities  

| where CveId == "CVE-2024-6387" 

| summarize by DeviceName, DeviceId; 

 

 

 

This query searches for devices with software vulnerabilities related to the specified CVE. 

 

Understanding Potential Impact: Attack Path Analysis 

Understanding the blast radius of impacted devices is critical for assessing the potential impact on your organization. Microsoft Security offers attack path analysis to visualize possible lateral movement steps an adversary might take. 

 

Leveraging Microsoft Defender for Cloud 

Defender for Cloud (MDC) discovers all cloud resources affected by the vulnerability which are also exposed to the internet through SSH ports. MDC highlights them in the ‘attack path analysis’ tool: 

BrjannBrekkan_0-1720466935153.png

 

Using attack path analysis, you can easily find all your exposed machines that are also potentially accessible for attackers. Use the following attack path title to filter the view only for exposed machines:  

  • Internet exposed Azure VM with OpenSSH regreSSHion vulnerability (CVE-2024-6387) 
  • Internet exposed AKS pod is running a container with OpenSSH regreSSHion vulnerability (CVE-2024-6387) 
  • Internet exposed EKS pod is running a container with OpenSSH regreSSHion vulnerability (CVE-2024-6387) 

Note: These attack path updates are rolling out and should be available for all customers shortly.

 

Using Cloud Security Explorer 

You can use the Cloud Security Explorer feature within Defender for Cloud to perform queries related to your posture across Azure, AWS, GCP, and code repositories. This allows you to investigate the specific CVE, identify affected machines, and understand the associated risks. 

We have created specific queries for this CVE that help you to easily get an initial assessment of the threat this vulnerability creates for your organization, with choices for customization: 

 

BrjannBrekkan_1-1720467020223.png

 

BrjannBrekkan_2-1720467020225.png

 

Advanced Hunting: Analyzing Attack Paths Across the Organization with Microsoft Security Exposure Management

To analyze the blast radius (i.e. the potential impact of a compromised device) of the regreSSHion vulnerability across different environments and assets, you can use the powerful `graph-match` KQL command under Advanced Hunting to identify other critical assets that might be at risk. 

The following query (wrapped in the BlastRadiusAttackPathMapping function for easier repeated usage) maps and returns possible attack paths an adversary can take.  
The function receives as an input: 

  • sourceTypes: filter for type of device that can be considered as entry points (e.g. virtual machine, endpoint device) 
  • sourceProperties: filter for properties the above devices must have (e.g. high severity vulnerabilities) 
  • sourceCveIDs: filter for specific vulnerabilities (CVE IDs) the above devices must have 
  • targetTypes: filter for type of device that are considered as the target of the path (e.g. storage account, privileged user, virtual machine, endpoint device) 
  • targetProperties: filter for properties the target devices must have (e.g. critical assets) 
  • maxPathLength: maximum hops for each attack path 
  • resultCountLimit: maximum amount of attack paths calculated 

 

 

 

 

let BlastRadiusAttackPathMapping = (sourceTypes:dynamic, sourceProperties:dynamic, sourceCveIDs:dynamic 

    , targetTypes:dynamic, targetProperties:dynamic 

    , maxPathLength:long = 6, resultCountLimit:long = 10000)  

{ 

let edgeTypes               = pack_array('has permissions to', 'contains', 'can authenticate as', 'can authenticate to', 'can remote interactive logon to' 

                                , 'can interactive logon to', 'can logon over the network to', 'contains', 'has role on', 'member of'); 

let sourceNodePropertiesFormatted = strcat('(', strcat_array(sourceProperties, '|'), ')'); 

let targetNodePropertiesFormatted = strcat('(', strcat_array(targetProperties, '|'), ')'); 

let nodes = ( 

    ExposureGraphNodes 

    | project NodeId, NodeName, NodeLabel 

        , SourcePropertiesExtracted = iff(sourceProperties != "[\"\"]", extract_all(sourceNodePropertiesFormatted, tostring(NodeProperties)), pack_array('')) 

        , TargetPropertiesExtracted = iff(targetProperties != "[\"\"]", extract_all(targetNodePropertiesFormatted, tostring(NodeProperties)), pack_array('')) 

       , criticalityLevel = toint(NodeProperties.rawData.criticalityLevel.criticalityLevel) 

    | mv-apply SourcePropertiesExtracted, TargetPropertiesExtracted on ( 

        summarize SourcePropertiesExtracted = make_set_if(SourcePropertiesExtracted, isnotempty(SourcePropertiesExtracted)) 

                , TargetPropertiesExtracted = make_set_if(TargetPropertiesExtracted, isnotempty(TargetPropertiesExtracted)) 

    ) 

    | extend CountSourceProperties = coalesce(array_length(SourcePropertiesExtracted), 0) 

            , CountTargetProperties = coalesce(array_length(TargetPropertiesExtracted), 0) 

    | extend SourceRelevancyByLabel = iff(NodeLabel in (sourceTypes) or sourceTypes == "[\"\"]", 1, 0) 

            , TargetRelevancyByLabel = iff(NodeLabel in (targetTypes) or targetTypes == "[\"\"]", 1, 0) 

            , SourceRelevancyByProperties = iff(CountSourceProperties > 0 or sourceProperties == "[\"\"]", 1, 0) 

            , TargetRelevancyByProperties = iff(CountTargetProperties > 0 or targetProperties == "[\"\"]", 1, 0) 

    | extend SourceRelevancy = iff(SourceRelevancyByLabel == 1 and SourceRelevancyByProperties == 1, 1, 0) 

            , TargetRelevancy = iff(TargetRelevancyByLabel == 1 and TargetRelevancyByProperties == 1, 1, 0) 

); 

let edges = ( 

    ExposureGraphEdges 

    | where EdgeLabel in (edgeTypes) 

    | project EdgeId, EdgeLabel, SourceNodeId, SourceNodeName, SourceNodeLabel, TargetNodeId, TargetNodeName, TargetNodeLabel 

); 

let vulnerableDevices = ( 

ExposureGraphEdges 

    | where iif(sourceCveIDs == "[\"\"]", true, (SourceNodeName in (sourceCveIDs)) and (EdgeLabel == "affecting")) // filter for CVEs only if listed, otherwise return all nodes 

    | project NodeId=TargetNodeId 

    | distinct NodeId 

); 

let paths = ( 

    edges 

    // Build the graph from all the nodes and edges and enrich it with node data (properties) 

    | make-graph SourceNodeId --> TargetNodeId with nodes on NodeId 

    // Look for existing paths between source nodes and target nodes with up to predefined number of hops 

    | graph-match cycles=none (s)-[e*1..maxPathLength]->(t) 

        // Filter only by paths with relevant sources and targets - filtered by node types and properties 

        where (s.SourceRelevancy == 1 and t.TargetRelevancy == 1) and s.NodeId in (vulnerableDevices) 

        project   SourceName                = s.NodeName 

                , SourceType                = s.NodeLabel 

                , SourceId                  = s.NodeId 

                , SourceProperties          = s.SourcePropertiesExtracted 

                , CountSourceProperties     = s.CountSourceProperties 

                , SourceRelevancy           = s.SourceRelevancy 

                , TargetName                = t.NodeName 

                , TargetType                = t.NodeLabel 

                , TargetId                  = t.NodeId 

                , TargetProperties          = t.TargetPropertiesExtracted 

                , CountTargetProperties     = t.CountTargetProperties 

                , TargetRelevancy           = t.TargetRelevancy 

                , EdgeLabels                = e.EdgeLabel 

                , EdgeIds                   = e.EdgeId 

                , EdgeAllTargetIds          = e.TargetNodeId 

                , EdgeAllTargetNames        = e.TargetNodeId 

                , EdgeAllTargetTypes        = e.TargetNodeLabel 

    | extend  PathLength                    = array_length(EdgeIds) + 1 

            , PathId                        = hash_md5(strcat(SourceId, strcat(EdgeIds), TargetId)) 

); 

let relevantPaths = ( 

    paths 

    | extend NodesInPath = array_concat(pack_array(SourceId), EdgeAllTargetIds), NodeLabelsInPath = array_concat(pack_array(SourceType), EdgeAllTargetTypes) 

    | extend NodesInPathList = NodesInPath 

    // Wrap the path into meaningful format (can be tweaked as needed) 

    | mv-expand with_itemindex = SortIndex EdgeIds to typeof(string), EdgeLabels to typeof(string) 

        , NodesInPath to typeof(string), NodeLabelsInPath to typeof(string) 

    | sort by PathId, SortIndex asc 

    | extend step = strcat( 

          iff(isnotempty(NodesInPath), strcat('(', NodeLabelsInPath, ' ', SourceName, ':', NodesInPath, ')'), '') 

        , iff(CountSourceProperties > 0 and NodesInPath == SourceId, SourceProperties, '') 

        , iff(CountTargetProperties > 0 and NodesInPath == TargetId, TargetProperties, '') 

        , iff(isnotempty(EdgeLabels), strcat('-', EdgeLabels, '->'), '')) 

    | summarize Path = make_list(step), take_any(*) by PathId 

    // Project relevant fields 

    | project SourceName, SourceType, SourceId, SourceProperties, CountSourceProperties, SourceRelevancy 

            , TargetName, TargetType, TargetId, TargetProperties, CountTargetProperties, TargetRelevancy 

            , PathId, PathLength, Path 

    | top resultCountLimit by PathLength asc 

); 

relevantPaths 

}; 

// Calling the function starts here  

let sourceTypes         = pack_array('microsoft.compute/virtualmachines', 'compute.instances', 'ec2.instance', 'device', 'container-image', 'microsoft.hybridcompute/machines'); 

let sourceProperties    = pack_array('hasHighOrCritical'); // filter for assets with severe vulnerabilities 

let sourceCveIDs        = pack_array('CVE-2024-6387'); // filter for entry points with regSSHion CVE 

let targetTypes         = pack_array('');  

let targetProperties    = pack_array('criticalityLevel'); // filter for paths that ends with critical assets 

BlastRadiusAttackPathMapping(sourceTypes, sourceProperties, sourceCveIDs, targetTypes, targetProperties) 

| project-reorder SourceType, SourceName, TargetType, TargetName, Path 

| project-keep SourceType, SourceName, TargetType, TargetName, Path 

 

 

 

 

 

For our purposes we are filtering for “compute” devices (such as servers, VMs, endpoints) with high severity vulnerabilities, specifically the regSSHion CVE ID that can be utilized by adversaries to serve as an entry point for an attack. 
We’re also looking to map paths only to devices that have a critical role in the environment (such as a Domain Controller, user with privileged role, etc.) 

 

An example for such query results: 

 

BrjannBrekkan_4-1720467952523.png

 

The function can be easily reused, the only part that should be modified is the parameters and the function calling, right below
Line 177 
// Calling the function starts here:“

 

Recommendations for Mitigation and Best Practices 

Mitigating risks associated with vulnerabilities requires a combination of proactive measures and real-time defenses. Here are some recommendations: 

  • Apply Patches and Updates: Regularly update and patch all software to address known vulnerabilities. Use Defender Vulnerability Management to monitor and enforce patch compliance. 
  • Application Blocking: Once CVE is assigned, utilize Defender Vulnerability Management's application blocking capability to prevent the execution of vulnerable or malicious software. This feature is available in premium plans only (learn more). 
  • Remediate vulnerabilities: Use Defender for Cloud ‘remediate vulnerabilities’ recommendations to remediate affected VMs and containers across your multi-cloud environment. (learn more) 
  • Exposure Management: Keep monitoring your environment using attack path analysis to block possible attack routes, using either the visualization tool under Exposure Management in Security.microsoft.com portal or the ‘graph-match’ KQL command (learn more). 
  • Secure Management ports Use Defender for Cloud ‘Secure management ports’ recommendation to ensure the SSH ports on your machines are closed, or at least protected with just-in-time access control (learn more). 
  • Network Segmentation: Implement network segmentation to limit the spread of an attack and protect critical assets. 
  • Advanced Hunting: Continuously monitor your environment using advanced hunting queries to detect unusual activities and potential exploitation attempts 

 

Conclusion 

By following these guidelines and utilizing end-to-end integrated Microsoft Security products, organizations can better prepare for, prevent and respond to attacks, ensuring a more secure and resilient environment. 

While the above process provides a comprehensive approach to protecting your organization, continual monitoring, updating, and adapting to new threats are essential for maintaining robust security. 

2 Comments
Version history
Last update:
‎Jul 08 2024 02:11 PM
Updated by: