feat(CIS checks): Complete CIS checks (#1461)

Co-authored-by: sergargar <sergio@verica.io>
Co-authored-by: Nacho Rivera <59198746+n4ch04@users.noreply.github.com>
Co-authored-by: Pepe Fagoaga <pepe@verica.io>
This commit is contained in:
Sergio Garcia
2022-11-14 17:50:26 +01:00
committed by GitHub
parent 6497f7bfe8
commit 8c8763a620
57 changed files with 1817 additions and 222 deletions

View File

@@ -1,42 +0,0 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2019) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra7138="7.138"
CHECK_TITLE_extra7138="[extra7138] Ensure no Network ACLs allow ingress from 0.0.0.0/0 to any port"
CHECK_SCORED_extra7138="NOT SCORED"
CHECK_CIS_LEVEL_extra7138="LEVEL2"
CHECK_SEVERITY_extra7138="High"
CHECK_ASFF_TYPE_extra7138="Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"
CHECK_ASFF_RESOURCE_TYPE_extra7138="AwsEc2NetworkAcl"
CHECK_ALTERNATE_check7138="extra7138"
CHECK_SERVICENAME_extra7138="ec2"
CHECK_RISK_extra7138='Even having a perimeter firewall; having network acls open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.'
CHECK_REMEDIATION_extra7138='Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.'
CHECK_DOC_extra7138='https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html'
CHECK_CAF_EPIC_extra7138='Infrastructure Security'
extra7138(){
for regx in $REGIONS; do
NACL_LIST=$($AWSCLI ec2 describe-network-acls --query 'NetworkAcls[?Entries[?((!PortRange) && (CidrBlock == `0.0.0.0/0`) && (Egress == `false`) && (RuleAction == `allow`))]].{NetworkAclId:NetworkAclId}' $PROFILE_OPT --region $regx --output text 2>&1)
if [[ $(echo "$NACL_LIST" | grep -E 'AccessDenied|UnauthorizedOperation|AuthorizationError') ]]; then
textInfo "$regx: Access Denied trying to describe network acls" "$regx"
continue
fi
if [[ $NACL_LIST ]];then
for NACL in $NACL_LIST;do
textInfo "$regx: Found Network ACL: $NACL open to 0.0.0.0/0 for any port" "$regx" "$NACL"
done
else
textPass "$regx: No Network ACL found with any port open to 0.0.0.0/0" "$regx" "$NACL"
fi
done
}

View File

@@ -1,48 +0,0 @@
#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
CHECK_ID_extra729="7.29"
CHECK_TITLE_extra729="[extra729] Ensure there are no EBS Volumes unencrypted"
CHECK_SCORED_extra729="NOT_SCORED"
CHECK_CIS_LEVEL_extra729="EXTRA"
CHECK_SEVERITY_extra729="Medium"
CHECK_ASFF_RESOURCE_TYPE_extra729="AwsEc2Volume"
CHECK_ALTERNATE_check729="extra729"
CHECK_ASFF_COMPLIANCE_TYPE_extra729="ens-mp.info.3.aws.ebs.1"
CHECK_SERVICENAME_extra729="ec2"
CHECK_RISK_extra729='Data encryption at rest prevents data visibility in the event of its unauthorized access or theft.'
CHECK_REMEDIATION_extra729='Encrypt all EBS volumes and Enable Encryption by default You can configure your AWS account to enforce the encryption of the new EBS volumes and snapshot copies that you create. For example; Amazon EBS encrypts the EBS volumes created when you launch an instance and the snapshots that you copy from an unencrypted snapshot.'
CHECK_DOC_extra729='https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html'
CHECK_CAF_EPIC_extra729='Data Protection'
extra729(){
# "Ensure there are no EBS Volumes unencrypted "
for regx in $REGIONS; do
LIST_OF_EBS_NON_ENC_VOLUMES=$($AWSCLI ec2 describe-volumes $PROFILE_OPT --region $regx --query 'Volumes[?Encrypted==`false`].VolumeId' --output text 2>&1)
if [[ $(echo "$LIST_OF_EBS_NON_ENC_VOLUMES" | grep -E 'AccessDenied|UnauthorizedOperation') ]]; then
textInfo "$regx: Access Denied trying to describe volumes" "$regx"
continue
fi
if [[ $LIST_OF_EBS_NON_ENC_VOLUMES ]];then
for volume in $LIST_OF_EBS_NON_ENC_VOLUMES; do
textFail "$regx: $volume is not encrypted!" "$regx" "$volume"
done
fi
LIST_OF_EBS_ENC_VOLUMES=$($AWSCLI ec2 describe-volumes $PROFILE_OPT --region $regx --query 'Volumes[?Encrypted==`true`].VolumeId' --output text)
if [[ $LIST_OF_EBS_ENC_VOLUMES ]];then
for volume in $LIST_OF_EBS_ENC_VOLUMES; do
textPass "$regx: $volume is encrypted" "$regx" "$volume"
done
fi
done
}

View File

@@ -0,0 +1,35 @@
{
"Provider": "aws",
"CheckID": "ec2_ebs_volume_encryption",
"CheckTitle": "Ensure there are no EBS Volumes unencrypted.",
"CheckType": ["Data Protection"],
"ServiceName": "ec2",
"SubServiceName": "volume",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "medium",
"ResourceType": "AwsEc2Volume",
"Description": "Ensure there are no EBS Volumes unencrypted.",
"Risk": "Data encryption at rest prevents data visibility in the event of its unauthorized access or theft.",
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Encrypt all EBS volumes and Enable Encryption by default You can configure your AWS account to enforce the encryption of the new EBS volumes and snapshot copies that you create. For example; Amazon EBS encrypts the EBS volumes created when you launch an instance and the snapshots that you copy from an unencrypted snapshot.",
"Url": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html"
}
},
"Categories": [],
"Tags": {
"Tag1Key": "value",
"Tag2Key": "value"
},
"DependsOn": [],
"RelatedTo": [],
"Notes": "",
"Compliance": []
}

View File

@@ -0,0 +1,20 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.ec2.ec2_client import ec2_client
class ec2_ebs_volume_encryption(Check):
def execute(self):
findings = []
for volume in ec2_client.volumes:
report = Check_Report(self.metadata)
report.region = volume.region
report.resource_id = volume.id
if volume.encrypted:
report.status = "PASS"
report.status_extended = f"EBS Snapshot {volume.id} is encrypted."
else:
report.status = "FAIL"
report.status_extended = f"EBS Snapshot {volume.id} is unencrypted."
findings.append(report)
return findings

View File

@@ -0,0 +1,92 @@
from unittest import mock
from boto3 import resource
from moto import mock_ec2
AWS_REGION = "us-east-1"
class Test_ec2_ebs_volume_encryption:
@mock_ec2
def test_ec2_no_volumes(self):
from providers.aws.lib.audit_info.audit_info import current_audit_info
from providers.aws.services.ec2.ec2_service import EC2
current_audit_info.audited_partition = "aws"
with mock.patch(
"providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption.ec2_client",
new=EC2(current_audit_info),
):
# Test Check
from providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption import (
ec2_ebs_volume_encryption,
)
check = ec2_ebs_volume_encryption()
result = check.execute()
assert len(result) == 0
@mock_ec2
def test_ec2_unencrypted_volume(self):
# Create EC2 Mocked Resources
ec2 = resource("ec2", region_name=AWS_REGION)
volume = ec2.create_volume(Size=80, AvailabilityZone=f"{AWS_REGION}a")
from providers.aws.lib.audit_info.audit_info import current_audit_info
from providers.aws.services.ec2.ec2_service import EC2
current_audit_info.audited_partition = "aws"
with mock.patch(
"providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption.ec2_client",
new=EC2(current_audit_info),
):
# Test Check
from providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption import (
ec2_ebs_volume_encryption,
)
check = ec2_ebs_volume_encryption()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended == f"EBS Snapshot {volume.id} is unencrypted."
)
@mock_ec2
def test_ec2_encrypted_volume(self):
# Create EC2 Mocked Resources
ec2 = resource("ec2", region_name=AWS_REGION)
volume = ec2.create_volume(
Size=80, AvailabilityZone=f"{AWS_REGION}a", Encrypted=True
)
from providers.aws.lib.audit_info.audit_info import current_audit_info
from providers.aws.services.ec2.ec2_service import EC2
current_audit_info.audited_partition = "aws"
with mock.patch(
"providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption.ec2_client",
new=EC2(current_audit_info),
):
# Test Check
from providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption import (
ec2_ebs_volume_encryption,
)
check = ec2_ebs_volume_encryption()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended == f"EBS Snapshot {volume.id} is encrypted."
)

View File

@@ -0,0 +1,35 @@
{
"Provider": "aws",
"CheckID": "ec2_network_acls_allow_ingress_any_port",
"CheckTitle": "Ensure no Network ACLs allow ingress from 0.0.0.0/0 to any port.",
"CheckType": ["Software and Configuration Checks", "Industry and Regulatory Standards", "CIS AWS Foundations Benchmark"],
"ServiceName": "ec2",
"SubServiceName": "networkacl",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "high",
"ResourceType": "AwsEc2NetworkAcl",
"Description": "Ensure no Network ACLs allow ingress from 0.0.0.0/0 to any port.",
"Risk": "Even having a perimeter firewall, having network acls open allows any user or malware with vpc access to scan for well known and sensitive ports and gain access to instance.",
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.",
"Url": "https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html"
}
},
"Categories": [],
"Tags": {
"Tag1Key": "value",
"Tag2Key": "value"
},
"DependsOn": [],
"RelatedTo": [],
"Notes": "Infrastructure Security",
"Compliance": []
}

View File

@@ -0,0 +1,26 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.ec2.ec2_client import ec2_client
from providers.aws.services.ec2.lib.network_acls import check_network_acl
class ec2_network_acls_allow_ingress_any_port(Check):
def execute(self):
findings = []
tcp_protocol = "-1"
check_port = 0
for network_acl in ec2_client.network_acls:
report = Check_Report(self.metadata)
report.region = network_acl.region
report.resource_id = network_acl.id
# If some entry allows it, that ACL is not securely configured
if not check_network_acl(network_acl.entries, tcp_protocol, check_port):
report.status = "PASS"
report.status_extended = f"Network ACL {network_acl.id} has not every port open to the Internet."
else:
report.status = "FAIL"
report.status_extended = (
f"Network ACL {network_acl.id} has every port open to the Internet."
)
findings.append(report)
return findings

View File

@@ -0,0 +1,153 @@
from unittest import mock
from boto3 import client
from moto import mock_ec2
AWS_REGION = "us-east-1"
class Test_ec2_network_acls_allow_ingress_any_port:
@mock_ec2
def test_ec2_default_nacls(self):
from providers.aws.lib.audit_info.audit_info import current_audit_info
from providers.aws.services.ec2.ec2_service import EC2
current_audit_info.audited_partition = "aws"
with mock.patch(
"providers.aws.services.ec2.ec2_network_acls_allow_ingress_any_port.ec2_network_acls_allow_ingress_any_port.ec2_client",
new=EC2(current_audit_info),
):
# Test Check
from providers.aws.services.ec2.ec2_network_acls_allow_ingress_any_port.ec2_network_acls_allow_ingress_any_port import (
ec2_network_acls_allow_ingress_any_port,
)
check = ec2_network_acls_allow_ingress_any_port()
result = check.execute()
# One default nacl per region
assert len(result) == 23
@mock_ec2
def test_ec2_non_default_compliant_nacl(self):
from providers.aws.lib.audit_info.audit_info import current_audit_info
from providers.aws.services.ec2.ec2_service import EC2
current_audit_info.audited_partition = "aws"
with mock.patch(
"providers.aws.services.ec2.ec2_network_acls_allow_ingress_any_port.ec2_network_acls_allow_ingress_any_port.ec2_client",
new=EC2(current_audit_info),
):
# Test Check
from providers.aws.services.ec2.ec2_network_acls_allow_ingress_any_port.ec2_network_acls_allow_ingress_any_port import (
ec2_network_acls_allow_ingress_any_port,
)
check = ec2_network_acls_allow_ingress_any_port()
result = check.execute()
# One default sg per region
assert len(result) == 23
# by default nacls are public
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Network ACL {result[0].resource_id} has every port open to the Internet."
)
@mock_ec2
def test_ec2_non_compliant_nacl(self):
# Create EC2 Mocked Resources
ec2_client = client("ec2", region_name=AWS_REGION)
vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"]
nacl_id = ec2_client.create_network_acl(VpcId=vpc_id)["NetworkAcl"][
"NetworkAclId"
]
ec2_client.create_network_acl_entry(
NetworkAclId=nacl_id,
RuleNumber=100,
Protocol="-1",
RuleAction="allow",
Egress=False,
CidrBlock="0.0.0.0/0",
)
from providers.aws.lib.audit_info.audit_info import current_audit_info
from providers.aws.services.ec2.ec2_service import EC2
current_audit_info.audited_partition = "aws"
with mock.patch(
"providers.aws.services.ec2.ec2_network_acls_allow_ingress_any_port.ec2_network_acls_allow_ingress_any_port.ec2_client",
new=EC2(current_audit_info),
):
# Test Check
from providers.aws.services.ec2.ec2_network_acls_allow_ingress_any_port.ec2_network_acls_allow_ingress_any_port import (
ec2_network_acls_allow_ingress_any_port,
)
check = ec2_network_acls_allow_ingress_any_port()
result = check.execute()
# One default sg per region + default of new VPC + new NACL
assert len(result) == 25
# Search changed sg
for nacl in result:
print(nacl.status)
if nacl.resource_id == nacl_id:
assert nacl.status == "FAIL"
assert (
nacl.status_extended
== f"Network ACL {nacl_id} has every port open to the Internet."
)
@mock_ec2
def test_ec2_compliant_nacl(self):
# Create EC2 Mocked Resources
ec2_client = client("ec2", region_name=AWS_REGION)
vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"]
nacl_id = ec2_client.create_network_acl(VpcId=vpc_id)["NetworkAcl"][
"NetworkAclId"
]
ec2_client.create_network_acl_entry(
NetworkAclId=nacl_id,
RuleNumber=100,
Protocol="-1",
RuleAction="allow",
Egress=False,
CidrBlock="10.0.0.2/32",
)
from providers.aws.lib.audit_info.audit_info import current_audit_info
from providers.aws.services.ec2.ec2_service import EC2
current_audit_info.audited_partition = "aws"
with mock.patch(
"providers.aws.services.ec2.ec2_network_acls_allow_ingress_any_port.ec2_network_acls_allow_ingress_any_port.ec2_client",
new=EC2(current_audit_info),
):
# Test Check
from providers.aws.services.ec2.ec2_network_acls_allow_ingress_any_port.ec2_network_acls_allow_ingress_any_port import (
ec2_network_acls_allow_ingress_any_port,
)
check = ec2_network_acls_allow_ingress_any_port()
result = check.execute()
# One default sg per region + default of new VPC + new NACL
assert len(result) == 25
# Search changed sg
for nacl in result:
print(nacl.status)
if nacl.resource_id == nacl_id:
assert nacl.status == "PASS"
assert (
nacl.status_extended
== f"Network ACL {nacl_id} has not every port open to the Internet."
)

View File

@@ -14,9 +14,9 @@
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-22#cloudformation",
"Other": "",
"Terraform": ""
"Terraform": "https://docs.bridgecrew.io/docs/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-22#terraform"
},
"Recommendation": {
"Text": "Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.",

View File

@@ -14,9 +14,9 @@
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"NativeIaC": "https://docs.bridgecrew.io/docs/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-3389#cloudformation",
"Other": "",
"Terraform": ""
"Terraform": "https://docs.bridgecrew.io/docs/ensure-aws-nacl-does-not-allow-ingress-from-00000-to-port-3389#terraform"
},
"Recommendation": {
"Text": "Apply Zero Trust approach. Implement a process to scan and remediate unrestricted or overly permissive network acls. Recommended best practices is to narrow the definition for the minimum ports required.",

View File

@@ -7,21 +7,17 @@ class ec2_securitygroup_allow_ingress_from_internet_to_any_port(Check):
def execute(self):
findings = []
for security_group in ec2_client.security_groups:
public = False
report = Check_Report(self.metadata)
report.region = security_group.region
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not all ports open to the Internet."
report.resource_id = security_group.id
# Loop through every security group's ingress rule and check it
for ingress_rule in security_group.ingress_rules:
public = check_security_group(ingress_rule, "-1")
# Check
if public:
if check_security_group(ingress_rule, "-1"):
report.status = "FAIL"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has all ports open to the Internet."
report.resource_id = security_group.id
else:
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not all ports open to the Internet."
report.resource_id = security_group.id
findings.append(report)
break
findings.append(report)
return findings

View File

@@ -1,5 +1,4 @@
from lib.check.models import Check, Check_Report
from providers.aws.services.ec2.ec2_client import ec2_client
from providers.aws.services.ec2.lib.security_groups import check_security_group
@@ -9,21 +8,17 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21(Check)
findings = []
check_ports = [20, 21]
for security_group in ec2_client.security_groups:
public = False
report = Check_Report(self.metadata)
report.region = security_group.region
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not FTP ports 20 and 21 open to the Internet."
report.resource_id = security_group.id
# Loop through every security group's ingress rule and check it
for ingress_rule in security_group.ingress_rules:
public = check_security_group(ingress_rule, "tcp", check_ports)
# Check
if public:
if check_security_group(ingress_rule, "tcp", check_ports):
report.status = "FAIL"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has FTP ports 20 and 21 open to the Internet."
report.resource_id = security_group.id
else:
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not FTP ports 20 and 21 open to the Internet."
report.resource_id = security_group.id
findings.append(report)
break
findings.append(report)
return findings

View File

@@ -8,21 +8,17 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22(Check):
findings = []
check_ports = [22]
for security_group in ec2_client.security_groups:
public = False
report = Check_Report(self.metadata)
report.region = security_group.region
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not SSH port 22 open to the Internet."
report.resource_id = security_group.id
# Loop through every security group's ingress rule and check it
for ingress_rule in security_group.ingress_rules:
public = check_security_group(ingress_rule, "tcp", check_ports)
# Check
if public:
if check_security_group(ingress_rule, "tcp", check_ports):
report.status = "FAIL"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has the SSH port 22 open to the Internet."
report.resource_id = security_group.id
else:
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not SSH port 22 open to the Internet."
report.resource_id = security_group.id
findings.append(report)
break
findings.append(report)
return findings

View File

@@ -8,21 +8,17 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389(Check):
findings = []
check_ports = [3389]
for security_group in ec2_client.security_groups:
public = False
report = Check_Report(self.metadata)
report.region = security_group.region
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Microsoft RDP port 3389 open to the Internet."
report.resource_id = security_group.id
# Loop through every security group's ingress rule and check it
for ingress_rule in security_group.ingress_rules:
public = check_security_group(ingress_rule, "tcp", check_ports)
# Check
if public:
if check_security_group(ingress_rule, "tcp", check_ports):
report.status = "FAIL"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Microsoft RDP port 3389 open to the Internet."
report.resource_id = security_group.id
else:
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Microsoft RDP port 3389 open to the Internet."
report.resource_id = security_group.id
findings.append(report)
break
findings.append(report)
return findings

View File

@@ -8,21 +8,18 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306(Check
findings = []
check_ports = [3306]
for security_group in ec2_client.security_groups:
public = False
report = Check_Report(self.metadata)
report.region = security_group.region
report.resource_id = security_group.id
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not MySQL port 3306 open to the Internet."
# Loop through every security group's ingress rule and check it
for ingress_rule in security_group.ingress_rules:
public = check_security_group(ingress_rule, "tcp", check_ports)
# Check
if public:
if check_security_group(ingress_rule, "tcp", check_ports):
report.status = "FAIL"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has the MySQL port 3306 open to the Internet."
report.resource_id = security_group.id
else:
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not MySQL port 3306 open to the Internet."
report.resource_id = security_group.id
findings.append(report)
break
findings.append(report)
return findings

View File

@@ -8,21 +8,17 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483
findings = []
check_ports = [1521, 2483]
for security_group in ec2_client.security_groups:
public = False
report = Check_Report(self.metadata)
report.region = security_group.region
report.resource_id = security_group.id
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Oracle ports 1521 and 2483 open to the Internet."
# Loop through every security group's ingress rule and check it
for ingress_rule in security_group.ingress_rules:
public = check_security_group(ingress_rule, "tcp", check_ports)
# Check
if public:
if check_security_group(ingress_rule, "tcp", check_ports):
report.status = "FAIL"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Oracle ports 1521 and 2483 open to the Internet."
report.resource_id = security_group.id
else:
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Oracle ports 1521 and 2483 open to the Internet."
report.resource_id = security_group.id
findings.append(report)
break
findings.append(report)
return findings

View File

@@ -7,21 +7,18 @@ class ec2_securitygroup_default_restrict_traffic(Check):
def execute(self):
findings = []
for security_group in ec2_client.security_groups:
public = False
report = Check_Report(self.metadata)
report.region = security_group.region
report.resource_id = security_group.id
# Find default security group
if security_group.name == "default":
report.status = "PASS"
report.status_extended = f"Default Security Group ({security_group.id}) is not open to the Internet."
for ingress_rule in security_group.ingress_rules:
public = check_security_group(ingress_rule, "-1")
if public:
report.status = "FAIL"
report.status_extended = f"Default Security Group ({security_group.id}) is open to the Internet."
report.resource_id = security_group.id
else:
report.status = "PASS"
report.status_extended = f"Default Security Group ({security_group.id}) is not open to the Internet."
report.resource_id = security_group.id
if check_security_group(ingress_rule, "-1"):
report.status = "FAIL"
report.status_extended = f"Default Security Group ({security_group.id}) is open to the Internet."
break
findings.append(report)
return findings

View File

@@ -23,6 +23,8 @@ class EC2:
self.__get_snapshot_public__()
self.elastic_ips = []
self.__threading_call__(self.__describe_elastic_ips__)
self.volumes = []
self.__threading_call__(self.__describe_volumes__)
def __get_session__(self):
return self.session
@@ -164,7 +166,7 @@ class EC2:
)
def __describe_elastic_ips__(self, regional_client):
logger.info("EC2 - Describing Security Groups...")
logger.info("EC2 - Describing Network Interfaces...")
try:
describe_network_interfaces_paginator = regional_client.get_paginator(
"describe_network_interfaces"
@@ -186,6 +188,26 @@ class EC2:
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __describe_volumes__(self, regional_client):
logger.info("EC2 - Describing Volumes...")
try:
describe_volumes_paginator = regional_client.get_paginator(
"describe_volumes"
)
for page in describe_volumes_paginator.paginate():
for volume in page["Volumes"]:
self.volumes.append(
Volume(
volume["VolumeId"],
regional_client.region,
volume["Encrypted"],
)
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
@dataclass
class Instance:
@@ -236,6 +258,18 @@ class Snapshot:
self.public = False
@dataclass
class Volume:
id: str
region: str
encrypted: bool
def __init__(self, id, region, encrypted):
self.id = id
self.region = region
self.encrypted = encrypted
@dataclass
class SecurityGroup:
name: str