mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-11 15:25:10 +00:00
105 lines
3.3 KiB
Python
105 lines
3.3 KiB
Python
import ipaddress
|
|
from typing import Any
|
|
|
|
|
|
################## Security Groups
|
|
def check_security_group(ingress_rule: Any, protocol: str, ports: list = []) -> bool:
|
|
"""
|
|
Check if the security group ingress rule has public access to the check_ports using the protocol
|
|
|
|
@param ingress_rule: AWS Security Group IpPermissions Ingress Rule
|
|
{
|
|
'FromPort': 123,
|
|
'IpProtocol': 'string',
|
|
'IpRanges': [
|
|
{
|
|
'CidrIp': 'string',
|
|
'Description': 'string'
|
|
},
|
|
],
|
|
'Ipv6Ranges': [
|
|
{
|
|
'CidrIpv6': 'string',
|
|
'Description': 'string'
|
|
},
|
|
],
|
|
'ToPort': 123,
|
|
}
|
|
|
|
@param procotol: Protocol to check.
|
|
|
|
|
|
@param ports: List of ports to check. (Default: [])
|
|
"""
|
|
|
|
# Check for all traffic ingress rules regardless of the protocol
|
|
if ingress_rule["IpProtocol"] == "-1":
|
|
for ip_ingress_rule in ingress_rule["IpRanges"]:
|
|
if _is_cidr_public(ip_ingress_rule["CidrIp"]):
|
|
return True
|
|
for ip_ingress_rule in ingress_rule["Ipv6Ranges"]:
|
|
if _is_cidr_public(ip_ingress_rule["CidrIp"]):
|
|
return True
|
|
|
|
# Check for specific ports in ingress rules
|
|
if "FromPort" in ingress_rule:
|
|
# If there is a port range
|
|
if ingress_rule["FromPort"] != ingress_rule["ToPort"]:
|
|
# Calculate port range, adding 1
|
|
diff = (ingress_rule["ToPort"] - ingress_rule["FromPort"]) + 1
|
|
ingress_port_range = []
|
|
for x in range(diff):
|
|
ingress_port_range.append(int(ingress_rule["FromPort"]) + x)
|
|
# If FromPort and ToPort are the same
|
|
else:
|
|
ingress_port_range = []
|
|
ingress_port_range.append(int(ingress_rule["FromPort"]))
|
|
|
|
# Test Security Group
|
|
# IPv4
|
|
for ip_ingress_rule in ingress_rule["IpRanges"]:
|
|
if _is_cidr_public(ip_ingress_rule["CidrIp"]):
|
|
# If there are input ports to check
|
|
if ports:
|
|
for port in ports:
|
|
if (
|
|
port in ingress_port_range
|
|
and ingress_rule["IpProtocol"] == protocol
|
|
):
|
|
return True
|
|
else:
|
|
return True
|
|
|
|
# IPv6
|
|
for ip_ingress_rule in ingress_rule["Ipv6Ranges"]:
|
|
if _is_cidr_public(ip_ingress_rule["CidrIp"]):
|
|
# If there are input ports to check
|
|
if ports:
|
|
for port in ports:
|
|
if (
|
|
port in ingress_port_range
|
|
and ingress_rule["IpProtocol"] == protocol
|
|
):
|
|
return True
|
|
else:
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def _is_cidr_public(cidr: str) -> bool:
|
|
"""
|
|
Check if an input CIDR is public
|
|
|
|
@param cidr: CIDR 10.22.33.44/8
|
|
"""
|
|
public_IPv4 = "0.0.0.0/0"
|
|
public_IPv6 = "::/0"
|
|
# Workaround until this issue is fixed
|
|
# PR https://github.com/python/cpython/pull/97733
|
|
# Issue https://github.com/python/cpython/issues/82836
|
|
if cidr in (public_IPv4, public_IPv6):
|
|
return True
|
|
|
|
return ipaddress.ip_network(cidr).is_global
|