From 89e0e2f888e925e60ace66ccf01f2bd434888f28 Mon Sep 17 00:00:00 2001 From: krisek Date: Thu, 24 Sep 2020 01:17:07 +0200 Subject: [PATCH] Fix #407: Correctly ingest EC2security group egress rules (#408) * fix egress import * initial security group import test cases --- cartography/intel/aws/ec2/security_groups.py | 4 +- tests/data/aws/ec2/security_groups.py | 218 ++++++++++++++++++ .../intel/aws/ec2/test_ec2_security_groups.py | 85 +++++++ 3 files changed, 305 insertions(+), 2 deletions(-) create mode 100644 tests/data/aws/ec2/security_groups.py create mode 100644 tests/integration/cartography/intel/aws/ec2/test_ec2_security_groups.py diff --git a/cartography/intel/aws/ec2/security_groups.py b/cartography/intel/aws/ec2/security_groups.py index 1ecfdd99a..72fb1a8de 100644 --- a/cartography/intel/aws/ec2/security_groups.py +++ b/cartography/intel/aws/ec2/security_groups.py @@ -57,7 +57,7 @@ def load_ec2_security_group_rule(neo4j_session, group, rule_type, aws_update_tag """ group_id = group["GroupId"] - rule_type_map = {"IpPermissions": "IpPermissionInbound", "IpPermissionEgress": "IpPermissionEgress"} + rule_type_map = {"IpPermissions": "IpPermissionInbound", "IpPermissionsEgress": "IpPermissionEgress"} if group.get(rule_type): for rule in group[rule_type]: @@ -128,7 +128,7 @@ def load_ec2_security_groupinfo(neo4j_session, data, region, current_aws_account ) load_ec2_security_group_rule(neo4j_session, group, "IpPermissions", aws_update_tag) - load_ec2_security_group_rule(neo4j_session, group, "IpPermissionEgress", aws_update_tag) + load_ec2_security_group_rule(neo4j_session, group, "IpPermissionsEgress", aws_update_tag) @timeit diff --git a/tests/data/aws/ec2/security_groups.py b/tests/data/aws/ec2/security_groups.py new file mode 100644 index 000000000..97c8c2cc2 --- /dev/null +++ b/tests/data/aws/ec2/security_groups.py @@ -0,0 +1,218 @@ +DESCRIBE_SGS = [ + { + "Description": "security group vpc2-id1", + "GroupName": "sq-vpc2-id1", + "IpPermissions": [ + { + "FromPort": 80, + "IpProtocol": "tcp", + "IpRanges": [ + { + "CidrIp": "203.0.113.0/24", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "ToPort": 80, + "UserIdGroupPairs": [], + }, + { + "FromPort": 443, + "IpProtocol": "tcp", + "IpRanges": [ + { + "CidrIp": "203.0.113.0/24", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "ToPort": 443, + "UserIdGroupPairs": [], + }, + ], + "OwnerId": "000000000000", + "GroupId": "sg-028e2522c72719996", + "IpPermissionsEgress": [ + { + "FromPort": 80, + "IpProtocol": "tcp", + "IpRanges": [ + { + "CidrIp": "0.0.0.0/0", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "ToPort": 80, + "UserIdGroupPairs": [], + }, + { + "IpProtocol": "-1", + "IpRanges": [ + { + "CidrIp": "8.8.8.8/32", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "UserIdGroupPairs": [], + }, + { + "FromPort": 443, + "IpProtocol": "tcp", + "IpRanges": [ + { + "CidrIp": "0.0.0.0/0", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "ToPort": 443, + "UserIdGroupPairs": [], + }, + ], + "VpcId": "vpc-05326141848d1c681", + }, + { + "Description": "default VPC security group", + "GroupName": "default", + "IpPermissions": [ + { + "IpProtocol": "-1", + "IpRanges": [], + "Ipv6Ranges": [], + "PrefixListIds": [], + "UserIdGroupPairs": [ + { + "GroupId": "sg-053dba35430032a0d", + "UserId": "000000000000", + }, + ], + }, + ], + "OwnerId": "000000000000", + "GroupId": "sg-053dba35430032a0d", + "IpPermissionsEgress": [ + { + "IpProtocol": "-1", + "IpRanges": [ + { + "CidrIp": "0.0.0.0/0", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "UserIdGroupPairs": [], + }, + ], + "VpcId": "vpc-025873e026b9e8ee6", + }, + { + "Description": "security group vpc1-id1", + "GroupName": "sq-vpc1-id1", + "IpPermissions": [ + { + "FromPort": 80, + "IpProtocol": "tcp", + "IpRanges": [ + { + "CidrIp": "203.0.113.0/24", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "ToPort": 80, + "UserIdGroupPairs": [], + }, + { + "FromPort": 443, + "IpProtocol": "tcp", + "IpRanges": [ + { + "CidrIp": "203.0.113.0/24", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "ToPort": 443, + "UserIdGroupPairs": [], + }, + ], + "OwnerId": "000000000000", + "GroupId": "sg-06c795c66be8937be", + "IpPermissionsEgress": [ + { + "FromPort": 80, + "IpProtocol": "tcp", + "IpRanges": [ + { + "CidrIp": "0.0.0.0/0", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "ToPort": 80, + "UserIdGroupPairs": [], + }, + { + "IpProtocol": "-1", + "IpRanges": [ + { + "CidrIp": "8.8.8.8/32", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "UserIdGroupPairs": [], + }, + { + "FromPort": 443, + "IpProtocol": "tcp", + "IpRanges": [ + { + "CidrIp": "0.0.0.0/0", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "ToPort": 443, + "UserIdGroupPairs": [], + }, + ], + "VpcId": "vpc-025873e026b9e8ee6", + }, + { + "Description": "default VPC security group", + "GroupName": "default", + "IpPermissions": [ + { + "IpProtocol": "-1", + "IpRanges": [], + "Ipv6Ranges": [], + "PrefixListIds": [], + "UserIdGroupPairs": [ + { + "GroupId": "sg-0fd4fff275d63600f", + "UserId": "000000000000", + }, + ], + }, + ], + "OwnerId": "000000000000", + "GroupId": "sg-0fd4fff275d63600f", + "IpPermissionsEgress": [ + { + "IpProtocol": "-1", + "IpRanges": [ + { + "CidrIp": "0.0.0.0/0", + }, + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "UserIdGroupPairs": [], + }, + ], + "VpcId": "vpc-05326141848d1c681", + }, +] diff --git a/tests/integration/cartography/intel/aws/ec2/test_ec2_security_groups.py b/tests/integration/cartography/intel/aws/ec2/test_ec2_security_groups.py new file mode 100644 index 000000000..01df9f47b --- /dev/null +++ b/tests/integration/cartography/intel/aws/ec2/test_ec2_security_groups.py @@ -0,0 +1,85 @@ +import cartography.intel.aws.ec2 +import tests.data.aws.ec2.security_groups + + +TEST_ACCOUNT_ID = '000000000000' +TEST_REGION = 'eu-north-1' +TEST_UPDATE_TAG = 123456789 + + +def test_load_security_groups(neo4j_session): + data = tests.data.aws.ec2.security_groups.DESCRIBE_SGS + cartography.intel.aws.ec2.security_groups.load_ec2_security_groupinfo( + neo4j_session, + data, + TEST_REGION, + TEST_ACCOUNT_ID, + TEST_UPDATE_TAG, + ) + + expected_nodes = { + "sg-0fd4fff275d63600f", + "sg-028e2522c72719996", + "sg-06c795c66be8937be", + "sg-053dba35430032a0d", + } + + nodes = neo4j_session.run( + """ + MATCH (s:EC2SecurityGroup) RETURN s.id; + """, + ) + actual_nodes = {n['s.id'] for n in nodes} + + assert actual_nodes == expected_nodes + + +def test_load_security_groups_relationships(neo4j_session): + # Create Test AWSAccount + neo4j_session.run( + """ + MERGE (aws:AWSAccount{id: {aws_account_id}}) + ON CREATE SET aws.firstseen = timestamp() + SET aws.lastupdated = {aws_update_tag} + """, + aws_account_id=TEST_ACCOUNT_ID, + aws_update_tag=TEST_UPDATE_TAG, + ) + + data = tests.data.aws.ec2.security_groups.DESCRIBE_SGS + cartography.intel.aws.ec2.security_groups.load_ec2_security_groupinfo( + neo4j_session, + data, + TEST_REGION, + TEST_ACCOUNT_ID, + TEST_UPDATE_TAG, + ) + + expected_nodes = { + ('sg-028e2522c72719996', 'sg-028e2522c72719996/IpPermissionsEgress/443443tcp'), + ('sg-028e2522c72719996', 'sg-028e2522c72719996/IpPermissionsEgress/NoneNone-1'), + ('sg-028e2522c72719996', 'sg-028e2522c72719996/IpPermissionsEgress/8080tcp'), + ('sg-028e2522c72719996', 'sg-028e2522c72719996/IpPermissions/443443tcp'), + ('sg-028e2522c72719996', 'sg-028e2522c72719996/IpPermissions/8080tcp'), + ('sg-053dba35430032a0d', 'sg-053dba35430032a0d/IpPermissionsEgress/NoneNone-1'), + ('sg-053dba35430032a0d', 'sg-053dba35430032a0d/IpPermissions/NoneNone-1'), + ('sg-06c795c66be8937be', 'sg-06c795c66be8937be/IpPermissionsEgress/443443tcp'), + ('sg-06c795c66be8937be', 'sg-06c795c66be8937be/IpPermissionsEgress/NoneNone-1'), + ('sg-06c795c66be8937be', 'sg-06c795c66be8937be/IpPermissionsEgress/8080tcp'), + ('sg-06c795c66be8937be', 'sg-06c795c66be8937be/IpPermissions/443443tcp'), + ('sg-06c795c66be8937be', 'sg-06c795c66be8937be/IpPermissions/8080tcp'), + ('sg-0fd4fff275d63600f', 'sg-0fd4fff275d63600f/IpPermissionsEgress/NoneNone-1'), + ('sg-0fd4fff275d63600f', 'sg-0fd4fff275d63600f/IpPermissions/NoneNone-1'), + } + + # Fetch relationships + result = neo4j_session.run( + """ + MATCH (s:EC2SecurityGroup)-[]-(r:IpRule) RETURN s.id,r.ruleid; + """, + ) + actual = { + (r['s.id'], r['r.ruleid']) for r in result + } + + assert actual == expected_nodes