diff --git a/hammer/library/aws/security_groups.py b/hammer/library/aws/security_groups.py index 814d88aa..5a126522 100755 --- a/hammer/library/aws/security_groups.py +++ b/hammer/library/aws/security_groups.py @@ -342,6 +342,44 @@ def restrict(self, status=None): processed += 1 return processed + @staticmethod + def build_open_ports_table(account, sg_id): + args = {'DryRun': False} + if sg_id: + args['GroupIds'] = [sg_id] + try: + secgroups = account.client("ec2").describe_security_groups(**args)["SecurityGroups"] + except ClientError as err: + if err.response['Error']['Code'] in ["AccessDenied", "UnauthorizedOperation"]: + logging.error(f"Access denied in {account} " + f"(ec2:{err.operation_name})") + elif err.response['Error']['Code'] == "InvalidGroup.NotFound": + logging.error(err.response['Error']['Message']) + return False + else: + logging.exception(f"Failed to describe security groups in {account}") + return False + + port_details = "||From Port||To Port||Protocol||CIDR||\n" + + for security_group in secgroups: + permissions_source = security_group["IpPermissions"] + for ingress in permissions_source: + protocol = ingress["IpProtocol"] + if protocol == "-1" or protocol not in ["tcp", "udp", "icmp", "icmpv6", "58"]: + from_port = None + to_port = None + else: + from_port = ingress.get("FromPort", 0) + to_port = ingress.get("ToPort", 65535) + ip_ranges = [ip_range["CidrIp"] for ip_range in ingress["IpRanges"]] + ip_ranges += [ip_range["CidrIpv6"] for ip_range in ingress.get("Ipv6Ranges", [])] + + for ip_range in ip_ranges: + port_details += f"|{from_port}|{to_port}|{protocol}|{ip_range}|" + port_details += "\n" + return port_details + class SecurityGroup(object): """ diff --git a/hammer/reporting-remediation/remediation/clean_security_groups.py b/hammer/reporting-remediation/remediation/clean_security_groups.py index 91d0c7ad..f50df950 100755 --- a/hammer/reporting-remediation/remediation/clean_security_groups.py +++ b/hammer/reporting-remediation/remediation/clean_security_groups.py @@ -5,12 +5,12 @@ import logging import argparse - +from botocore.exceptions import ClientError from library.logger import set_logging, add_cw_logging from library.config import Config from library.jiraoperations import JiraReporting from library.slack_utility import SlackNotification -from library.aws.security_groups import SecurityGroupsChecker, RestrictionStatus +from library.aws.security_groups import SecurityGroupsChecker, RestrictionStatus, SecurityGroupPermission from library.aws.utility import Account from library.ddb_issues import Operations as IssueOperations from library.ddb_issues import IssueStatus, SecurityGroupIssue @@ -114,7 +114,10 @@ def clean_security_groups(self, batch=False): f"[{backup_path}|https://s3.console.aws.amazon.com/s3/object/{backup_bucket}/{backup_path}]. " f"Security group '{group_name} / {group_id}' `{RestrictionStatus.OpenCompletely.value}` issue " f"in '{account_name} / {account_id}' account, '{group_region}' region " - f"was remediated by hammer") + f"was remediated by hammer.") + + comment += "\n\n After remediation, Security Group has access to following ports: \n" + comment += SecurityGroupPermission.build_open_ports_table(account, group_id) if comment is not None: jira.remediate_issue(