turbot/steampipe-mod-azure-compliance

Control: 8.1 Ensure that RDP access from the Internet is evaluated and restricted

Description

Network security groups should be periodically evaluated for port misconfigurations. Where RDP is not explicitly required and narrowly configured for resources attached to a network security group, Internet-level access to Azure resources should be restricted or eliminated.

The potential security problem with using RDP over the Internet is that attackers can use various brute force techniques to gain access to Azure Virtual Machines. Once the attackers gain access, they can use a virtual machine as a launch point for compromising other machines on an Azure Virtual Network or even attack networked devices outside of Azure.

Remediation

From Azure Portal

  1. Go to Network security groups.
  2. Under Settings, click Inbound security rules.
  3. Check the box next to any inbound security rule matching:
  • Port: 3389 or range including 3389
  • Protocol: TCP or Any
  • Source: 0.0.0.0/0, Internet, or Any
  • Action: Allow
  1. Click Delete.
  2. Click Yes.

From Azure CLI

For each network security group rule requiring remediation, run the following command to delete a rule:

az network nsg rule delete --resource-group <resource-group> --nsg-name <network-security-group> --name <rule>

Default Value

By default, RDP access from internet is not enabled.

Usage

Run the control in your terminal:

powerpipe control run azure_compliance.control.cis_v400_8_1

Snapshot and share results via Turbot Pipes:

powerpipe login
powerpipe control run azure_compliance.control.cis_v400_8_1 --share

SQL

This control uses a named query:

with network_sg as (
select
distinct name sg_name
from
azure_network_security_group nsg,
jsonb_array_elements(security_rules) sg,
jsonb_array_elements_text(sg -> 'properties' -> 'destinationPortRanges' || (sg -> 'properties' -> 'destinationPortRange') :: jsonb) dport,
jsonb_array_elements_text(sg -> 'properties' -> 'sourceAddressPrefixes' || (sg -> 'properties' -> 'sourceAddressPrefix') :: jsonb) sip
where
sg -> 'properties' ->> 'access' = 'Allow'
and sg -> 'properties' ->> 'direction' = 'Inbound'
and (sg -> 'properties' ->> 'protocol' ilike 'TCP' or sg -> 'properties' ->> 'protocol' = '*')
and sip in ('*', '0.0.0.0', '0.0.0.0/0', 'Internet', 'any', '<nw>/0', '/0')
and (
dport in ('3389', '*')
or (
dport like '%-%'
and split_part(dport, '-', 1) :: integer <= 3389
and split_part(dport, '-', 2) :: integer >= 3389
)
)
)
select
sg.id resource,
case
when nsg.sg_name is null then 'ok'
else 'alarm'
end as status,
case
when nsg.sg_name is null
then sg.title || ' restricts RDP access from internet.'
else sg.title || ' allows RDP access from internet.'
end as reason
, sg.resource_group as resource_group
, sub.display_name as subscription
from
azure_network_security_group sg
left join network_sg nsg on nsg.sg_name = sg.name
join azure_subscription sub on sub.subscription_id = sg.subscription_id;

Tags