Detect NSG inbound rule updated to allow All

Network Security Group (NSG) is one of the most common features in Azure to help strengthen your network defense. It allows you to filter network traffic to and from Azure resources. Having NSG in place doesn’t always mean your network is secure. A misconfiguration such as having an inbound rule to allow All would be like an open door to adversaries.

In this article, I would like to share a detection and monitoring use case to help detect if someone created or updated an NSG inbound rule to allow everything.

Use Case

An adversary can do as many things as he can to weaken your network defense. He may try to update an inbound rule to allow traffic from anywhere. It means he could send a request from an untrusted network to a virtual machine. The more your network is open, the higher risk.

Outbound rule can also be updated to allow a compromised virtual machine to communicate back to a malicious Command and Control host.

Azure Monitor Alert

Azure Activity log is very important. It records administrative activities. 

Specific to NSG activity, when you create or update a security rule, you make a request to trigger Microsoft.Network/networkSecurityGroups/securityRules/write 

We can use Azure Monitor alert to trigger an alert based on this operation. The solution for this is quite simple. You have Azure Activity log configured to be sent to a single Log Analytics workspace. You then create a Log Analytics query-based alert to detect when a security rule is created or updated.

Below is the query you need:

AzureActivity 
| where OperationNameValue =~ "Microsoft.Network/networkSecurityGroups/securityRules/write"
| where ActivityStatusValue == "Accept"
| extend SourceAddressPrefix_ = tostring(parse_json(tostring(parse_json(tostring(Properties_d.responseBody)).properties)).sourceAddressPrefix),
         SourceAddressPrefixes_ = tostring(parse_json(tostring(parse_json(tostring(Properties_d.requestbody)).properties)).sourceAddressPrefixes),
         Access = tostring(parse_json(tostring(parse_json(tostring(parse_json(Properties).responseBody)).properties)).access),
         Direction = tostring(parse_json(tostring(parse_json(tostring(Properties_d.responseBody)).properties)).direction),
         NsgName = split(_ResourceId, '/')[8],
         NsgRule = split(_ResourceId, '/')[10] 
| where SourceAddressPrefix_ == '*' or SourceAddressPrefixes_ == '' or SourceAddressPrefixes_ == '0.0.0.0/0' 
| where Access == "Allow"
| where Direction == "Inbound"
| project TimeGenerated, 
          NsgName, 
          NsgRule, 
          ResourceGroup, 
          SourceAddressPrefix_, 
          SourceAddressPrefixes_,
          Caller,
          CallerIpAddress,
          _ResourceId

Use this ARM template to deploy an Azure Monitor alert rule to trigger an alert when someone creates or updates an inbound rule in NSG to allow 0.0.0.0 or All (*).

Microsoft Sentinel Alert Rule

You may not like to use Azure Monitor Alert because you would like to centralize all security monitoring and detection alert and leave Azure Monitor alert for infrastructure operation monitoring.

Use this ARM template to deploy a Microsoft Sentinel analytics rule.

Azure Sentinel Analytics Rule ARM Template

Outbound monitoring

Outbound monitoring rule should be in a separate rule because the rule is based on destination address instead of source address. Below is the sample query:

AzureActivity 
| where OperationNameValue =~ "Microsoft.Network/networkSecurityGroups/securityRules/write"
| where ActivityStatusValue == "Accept"
| extend DestinationAddressPrefix_ = tostring(parse_json(tostring(parse_json(tostring(Properties_d.responseBody)).properties)).destinationAddressPrefix),
         DestinationAddressPrefixes_ = tostring(parse_json(tostring(parse_json(tostring(Properties_d.requestbody)).properties)).destinationAddressPrefixes),
         Access = tostring(parse_json(tostring(parse_json(tostring(parse_json(Properties).responseBody)).properties)).access),
         Direction = tostring(parse_json(tostring(parse_json(tostring(Properties_d.responseBody)).properties)).direction),
         NsgName = split(_ResourceId, '/')[8],
         NsgRule = split(_ResourceId, '/')[10] 
| where DestinationAddressPrefix_ == '*' or DestinationAddressPrefixes_ == '' or DestinationAddressPrefixes_ == '0.0.0.0/0' 
| where Access == "Allow"
| where Direction == "Outbound"
| project TimeGenerated, 
          NsgName, 
          NsgRule, 
          ResourceGroup, 
          DestinationAddressPrefix_, 
          DestinationAddressPrefixes_,
          Caller,
          CallerIpAddress,
          _ResourceId

All sample ARM templates to deploy Azure Monitor alert and Microsoft Sentinel analytics rules in this article is here.

If you have any feedback, please feel free to leave a comment in the Comment box or create an issue in GitHub.

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

Leave a Reply

Your email address will not be published.