AWS Security Group Administrative Ingress


Description

This policy validates that AWS Security Groups don't allow unrestricted inbound traffic on port 3389 or 22, ports commonly used for the remote access protocols RDP and SSH respectively.

Query · python

RESTRICTED_PORTS = [22, 3389]


# Returns true if at least one of the ports in check_ports are between from_port and to_port
# Returns true if from_port or to_port is None as that indicates an unrestricted range of ports
def port_checker(check_ports, from_port, to_port):
    if from_port is None and to_port is None:
        return True

    for port in check_ports:
        if from_port <= port <= to_port:
            return True
    return False


def policy(resource):
    if resource["IpPermissions"] is None:
        return True

    for permission in resource["IpPermissions"]:
        src_open = False
        for ip_range in permission["IpRanges"] or []:
            if ip_range["CidrIp"] == "0.0.0.0/0":
                src_open = True
                break
        for ipv6_range in permission["Ipv6Ranges"] or []:
            if src_open or ipv6_range["CidrIpv6"] == "::/0":
                src_open = True
                break
        if src_open and port_checker(
            RESTRICTED_PORTS, permission["FromPort"], permission["ToPort"]
        ):
            return False
    return True

Analyst notes

https://docs.runpanther.io/alert-runbooks/built-in-policies/aws-securitygroup-restricts-ingress-on-administrative-ports

Raw source AWS Security Group Administrative Ingress · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: policy
Filename: aws_security_group_administrative_ingress.py
PolicyID: "AWS.SecurityGroup.AdministrativeIngress"
DisplayName: "AWS Security Group Administrative Ingress"
Enabled: true
ResourceTypes:
  - AWS.EC2.SecurityGroup
Tags:
  - AWS
  - Security Control
  - Initial Access:Exploit Public-Facing Application
Reports:
  CIS:
    - 4.1
    - 4.2
  MITRE ATT&CK:
    - TA0001:T1190
Severity: High
Description: >
  This policy validates that AWS Security Groups don't allow unrestricted inbound traffic on
  port 3389 or 22, ports commonly used for the remote access protocols RDP and SSH respectively.
Runbook: >
  https://docs.runpanther.io/alert-runbooks/built-in-policies/aws-securitygroup-restricts-ingress-on-administrative-ports
Reference: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html
Tests:
  - Name: Inbound IP Permission On All IPs On Acceptable Ports
    ExpectedResult: true
    Resource:
      {
        "Description": "default VPC security group",
        "GroupId": "sg-abc123",
        "GroupName": "default",
        "IpPermissions":
          [
            {
              "FromPort": 30,
              "IpProtocol": "-1",
              "IpRanges": [{ "CidrIp": "0.0.0.0/0", "Description": null }],
              "Ipv6Ranges": null,
              "PrefixListIds": null,
              "ToPort": 45,
              "UserIdGroupPairs":
                [
                  {
                    "Description": null,
                    "GroupId": "sg-abc123",
                    "GroupName": null,
                    "PeeringStatus": null,
                    "UserId": "1122334455",
                    "VpcId": null,
                    "VpcPeeringConnectionId": null,
                  },
                ],
            },
          ],
        "IpPermissionsEgress":
          [
            {
              "FromPort": null,
              "IpProtocol": "-1",
              "IpRanges": [{ "CidrIp": "0.0.0.0/0", "Description": null }],
              "Ipv6Ranges": null,
              "PrefixListIds": null,
              "ToPort": null,
              "UserIdGroupPairs": null,
            },
          ],
        "OwnerId": "112233445566",
        "Tags": null,
        "VpcId": "vpc-123454321",
      }
  - Name: Inbound IP Permissions On All IPs On Restricted Ports
    ExpectedResult: false
    Resource:
      {
        "Description": "default VPC security group",
        "GroupId": "sg-abc123",
        "GroupName": "default",
        "IpPermissions":
          [
            {
              "FromPort": 22,
              "IpProtocol": "-1",
              "IpRanges": [{ "CidrIp": "0.0.0.0/0", "Description": null }],
              "Ipv6Ranges": null,
              "PrefixListIds": null,
              "ToPort": 22,
              "UserIdGroupPairs":
                [
                  {
                    "Description": null,
                    "GroupId": "sg-abc123",
                    "GroupName": null,
                    "PeeringStatus": null,
                    "UserId": "1122334455",
                    "VpcId": null,
                    "VpcPeeringConnectionId": null,
                  },
                ],
            },
          ],
        "IpPermissionsEgress":
          [
            {
              "FromPort": null,
              "IpProtocol": "-1",
              "IpRanges": [{ "CidrIp": "0.0.0.0/0", "Description": null }],
              "Ipv6Ranges": null,
              "PrefixListIds": null,
              "ToPort": null,
              "UserIdGroupPairs": null,
            },
          ],
        "OwnerId": "112233445566",
        "Tags": null,
        "VpcId": "vpc-123454321",
      }
  - Name: Inbound IP Permission On All IPv6 On Restricted Ports
    ExpectedResult: false
    Resource:
      {
        "Description": "default VPC security group",
        "GroupId": "sg-abc123",
        "GroupName": "default",
        "IpPermissions":
          [
            {
              "FromPort": 22,
              "IpProtocol": "-1",
              "IpRanges": null,
              "Ipv6Ranges": [{ "CidrIpv6": "::/0", "Description": null }],
              "PrefixListIds": null,
              "ToPort": 22,
              "UserIdGroupPairs":
                [
                  {
                    "Description": null,
                    "GroupId": "sg-abc123",
                    "GroupName": null,
                    "PeeringStatus": null,
                    "UserId": "1122334455",
                    "VpcId": null,
                    "VpcPeeringConnectionId": null,
                  },
                ],
            },
          ],
        "IpPermissionsEgress":
          [
            {
              "FromPort": null,
              "IpProtocol": "-1",
              "IpRanges": [{ "CidrIp": "0.0.0.0/0", "Description": null }],
              "Ipv6Ranges": null,
              "PrefixListIds": null,
              "ToPort": null,
              "UserIdGroupPairs": null,
            },
          ],
        "OwnerId": "112233445566",
        "Tags": null,
        "VpcId": "vpc-123454321",
      }
  - Name: Inbound IP Permission On Specific IP On Restricted Port
    ExpectedResult: true
    Resource:
      {
        "Description": "default VPC security group",
        "GroupId": "sg-abc123",
        "GroupName": "default",
        "IpPermissions":
          [
            {
              "FromPort": 22,
              "IpProtocol": "-1",
              "IpRanges": [{ "CidrIp": "1.1.1.1/32", "Description": null }],
              "Ipv6Ranges": null,
              "PrefixListIds": null,
              "ToPort": 22,
              "UserIdGroupPairs":
                [
                  {
                    "Description": null,
                    "GroupId": "sg-abc123",
                    "GroupName": null,
                    "PeeringStatus": null,
                    "UserId": "1122334455",
                    "VpcId": null,
                    "VpcPeeringConnectionId": null,
                  },
                ],
            },
          ],
        "IpPermissionsEgress":
          [
            {
              "FromPort": null,
              "IpProtocol": "-1",
              "IpRanges": [{ "CidrIp": "0.0.0.0/0", "Description": null }],
              "Ipv6Ranges": null,
              "PrefixListIds": null,
              "ToPort": null,
              "UserIdGroupPairs": null,
            },
          ],
        "OwnerId": "112233445566",
        "Tags": null,
        "VpcId": "vpc-123454321",
      }
  - Name: No Inbound IP Permissions
    ExpectedResult: true
    Resource:
      {
        "Description": "default VPC security group",
        "GroupId": "sg-abc123",
        "GroupName": "default",
        "IpPermissions":
          [
            {
              "FromPort": null,
              "IpProtocol": "-1",
              "IpRanges": null,
              "Ipv6Ranges": null,
              "PrefixListIds": null,
              "ToPort": null,
              "UserIdGroupPairs":
                [
                  {
                    "Description": null,
                    "GroupId": "sg-abc123",
                    "GroupName": null,
                    "PeeringStatus": null,
                    "UserId": "1122334455",
                    "VpcId": null,
                    "VpcPeeringConnectionId": null,
                  },
                ],
            },
          ],
        "IpPermissionsEgress":
          [
            {
              "FromPort": null,
              "IpProtocol": "-1",
              "IpRanges": [{ "CidrIp": "0.0.0.0/0", "Description": null }],
              "Ipv6Ranges": null,
              "PrefixListIds": null,
              "ToPort": null,
              "UserIdGroupPairs": null,
            },
          ],
        "OwnerId": "112233445566",
        "Tags": null,
        "VpcId": "vpc-123454321",
      }


# ------ paired body: aws_security_group_administrative_ingress.py ------

RESTRICTED_PORTS = [22, 3389]


# Returns true if at least one of the ports in check_ports are between from_port and to_port
# Returns true if from_port or to_port is None as that indicates an unrestricted range of ports
def port_checker(check_ports, from_port, to_port):
    if from_port is None and to_port is None:
        return True

    for port in check_ports:
        if from_port <= port <= to_port:
            return True
    return False


def policy(resource):
    if resource["IpPermissions"] is None:
        return True

    for permission in resource["IpPermissions"]:
        src_open = False
        for ip_range in permission["IpRanges"] or []:
            if ip_range["CidrIp"] == "0.0.0.0/0":
                src_open = True
                break
        for ipv6_range in permission["Ipv6Ranges"] or []:
            if src_open or ipv6_range["CidrIpv6"] == "::/0":
                src_open = True
                break
        if src_open and port_checker(
            RESTRICTED_PORTS, permission["FromPort"], permission["ToPort"]
        ):
            return False
    return True

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.