Skip to main content

Restrict RDP Access from the Internet

Overview

This check verifies that your EC2 security groups do not allow inbound Remote Desktop Protocol (RDP) traffic on TCP port 3389 from the entire internet (0.0.0.0/0 or ::/0). RDP provides full graphical access to Windows systems, making unrestricted exposure a high-severity security risk.

Risk

Exposing RDP to the internet is one of the most common attack vectors for ransomware and system compromise:

  • Brute force attacks: Attackers continuously attempt common usernames and passwords to gain access
  • Credential stuffing: Stolen credentials from other breaches are tested against your systems
  • Remote code execution: Known vulnerabilities in RDP (like BlueKeep) can be exploited without authentication
  • Ransomware deployment: Once attackers gain access, they can encrypt your data and demand ransom
  • Data exfiltration: Attackers with RDP access can steal sensitive data directly from your systems

Remediation Steps

Prerequisites

You need:

  • AWS Console access with permissions to modify security groups
  • Knowledge of which IP addresses (if any) legitimately need RDP access
Required IAM permissions

Your IAM user or role needs these permissions:

  • ec2:DescribeSecurityGroups
  • ec2:DescribeSecurityGroupRules
  • ec2:RevokeSecurityGroupIngress
  • ec2:AuthorizeSecurityGroupIngress (if adding restricted rules)

AWS Console Method

  1. Open the EC2 Console

  2. Find the security group

    • In the left sidebar, click Security Groups (under Network & Security)
    • Locate the security group flagged by Prowler
    • Click on the security group ID to open its details
  3. Review the inbound rules

    • Click the Inbound rules tab
    • Look for rules with:
      • Port range: 3389 (or a range including 3389)
      • Source: 0.0.0.0/0 or ::/0
  4. Remove the dangerous rule

    • Click Edit inbound rules
    • Find the rule allowing RDP from 0.0.0.0/0 or ::/0
    • Click Delete (the X button) next to that rule
    • Click Save rules
  5. Add a restricted rule (if RDP access is still needed)

    • Click Edit inbound rules again
    • Click Add rule
    • Set:
      • Type: RDP
      • Source: Your specific IP address or CIDR range (e.g., 203.0.113.10/32 for a single IP)
    • Click Save rules

Better alternatives to direct RDP access:

  • Use AWS Systems Manager Session Manager for remote access (no open ports needed)
  • Connect through a VPN to your VPC
  • Use a hardened bastion host with MFA
AWS CLI (optional)

Find security groups with open RDP

aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=3389" \
"Name=ip-permission.to-port,Values=3389" \
"Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].[GroupId,GroupName]' \
--output table

Remove the open RDP rule (IPv4)

aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 3389 \
--cidr 0.0.0.0/0

Replace <SECURITY_GROUP_ID> with your actual security group ID (e.g., sg-0123456789abcdef0).

Remove the open RDP rule (IPv6)

If the rule also allows IPv6 access:

aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--ip-permissions IpProtocol=tcp,FromPort=3389,ToPort=3389,Ipv6Ranges=[{CidrIpv6=::/0}]

Add a restricted RDP rule

To allow RDP only from a specific IP:

aws ec2 authorize-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 3389 \
--cidr 203.0.113.10/32

Replace 203.0.113.10/32 with your actual IP address.

CloudFormation (optional)

When defining security groups in CloudFormation, ensure RDP rules only allow access from specific IPs:

AWSTemplateFormatVersion: '2010-09-09'
Description: Security group with restricted RDP access

Parameters:
AllowedRDPCidr:
Type: String
Description: CIDR block allowed to access RDP (e.g., your office IP)
AllowedPattern: ^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$
ConstraintDescription: Must be a valid CIDR block (e.g., 203.0.113.10/32)

VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC where the security group will be created

Resources:
RestrictedRDPSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group with restricted RDP access
VpcId: !Ref VpcId
SecurityGroupIngress:
# RDP access restricted to specific CIDR
- IpProtocol: tcp
FromPort: 3389
ToPort: 3389
CidrIp: !Ref AllowedRDPCidr
Description: RDP access from authorized network only
Tags:
- Key: Name
Value: restricted-rdp-sg

Outputs:
SecurityGroupId:
Description: ID of the security group with restricted RDP
Value: !Ref RestrictedRDPSecurityGroup

Important: Never use 0.0.0.0/0 or ::/0 as the CidrIp or CidrIpv6 for RDP rules.

Terraform (optional)
variable "allowed_rdp_cidr" {
description = "CIDR block allowed to access RDP"
type = string
# Example: "203.0.113.10/32" for a single IP
}

variable "vpc_id" {
description = "VPC ID where the security group will be created"
type = string
}

resource "aws_security_group" "restricted_rdp" {
name = "restricted-rdp-sg"
description = "Security group with restricted RDP access"
vpc_id = var.vpc_id

# RDP access restricted to specific CIDR
ingress {
description = "RDP access from authorized network only"
from_port = 3389
to_port = 3389
protocol = "tcp"
cidr_blocks = [var.allowed_rdp_cidr]
}

# Allow all outbound traffic
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

tags = {
Name = "restricted-rdp-sg"
}
}

output "security_group_id" {
description = "ID of the security group with restricted RDP"
value = aws_security_group.restricted_rdp.id
}

Anti-pattern to avoid:

# DO NOT DO THIS - exposes RDP to the entire internet
ingress {
from_port = 3389
to_port = 3389
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # DANGEROUS!
}

Verification

After removing the dangerous rule, verify the change:

  1. In the AWS Console:

    • Go to EC2 > Security Groups
    • Select the security group you modified
    • Click the Inbound rules tab
    • Confirm there is no rule allowing port 3389 from 0.0.0.0/0 or ::/0
  2. Re-run Prowler:

    • Run the specific check again to confirm remediation
CLI verification commands

Check if any security groups still have open RDP:

aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=3389" \
"Name=ip-permission.to-port,Values=3389" \
"Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].[GroupId,GroupName]' \
--output table

If the output is empty, no security groups have open RDP access.

View the rules for a specific security group:

aws ec2 describe-security-group-rules \
--region us-east-1 \
--filters "Name=group-id,Values=<SECURITY_GROUP_ID>" \
--query 'SecurityGroupRules[?FromPort==`3389`]' \
--output table

Additional Resources

Notes

  • Audit all security groups: This check may flag one security group, but others may have similar issues. Review all security groups in your account.
  • Check for port ranges: Some rules use port ranges (e.g., 0-65535) that include port 3389. These are equally dangerous and should be restricted.
  • IPv6 considerations: Remember to check for and remove both IPv4 (0.0.0.0/0) and IPv6 (::/0) unrestricted rules.
  • Associated resources: Before modifying a security group, check which EC2 instances, RDS databases, or other resources use it. Changes take effect immediately.
  • Alternative access methods: Consider replacing direct RDP access with AWS Systems Manager Session Manager, which requires no open inbound ports and provides audit logging.
  • Network ACLs: Security groups are not the only network control. Ensure your Network ACLs also restrict RDP access appropriately.
  • Defense in depth: Even with restricted security groups, enable Windows Firewall, use strong passwords, enable NLA (Network Level Authentication), and keep systems patched.