in cartography/intel/aws/ec2.py [0:0]
def load_ec2_security_group_rule(session, group, rule_type, aws_update_tag):
ingest_rule = """
MERGE (rule:#RULE_TYPE#{ruleid: {RuleId}})
ON CREATE SET rule :IpRule, rule.firstseen = timestamp(), rule.fromport = {FromPort}, rule.toport = {ToPort},
rule.protocol = {Protocol}
SET rule.lastupdated = {aws_update_tag}
WITH rule
MATCH (group:EC2SecurityGroup{groupid: {GroupId}})
MERGE (group)<-[r:MEMBER_OF_EC2_SECURITY_GROUP]-(rule)
ON CREATE SET r.firstseen = timestamp()
SET r.lastupdated = {aws_update_tag};
"""
ingest_rule_group_pair = """
MERGE (group:EC2SecurityGroup{id: {GroupId}})
ON CREATE SET group.firstseen = timestamp(), group.groupid = {GroupId}
SET group.lastupdated = {aws_update_tag}
WITH group
MATCH (inbound:IpRule{ruleid: {RuleId}})
MERGE (inbound)-[r:MEMBER_OF_EC2_SECURITY_GROUP]->(group)
ON CREATE SET r.firstseen = timestamp()
SET r.lastupdated = {aws_update_tag}
"""
ingest_range = """
MERGE (range:IpRange{id: {RangeId}})
ON CREATE SET range.firstseen = timestamp(), range.range = {RangeId}
SET range.lastupdated = {aws_update_tag}
WITH range
MATCH (rule:IpRule{ruleid: {RuleId}})
MERGE (rule)<-[r:MEMBER_OF_IP_RULE]-(range)
ON CREATE SET r.firstseen = timestamp()
SET r.lastupdated = {aws_update_tag}
"""
group_id = group["GroupId"]
rule_type_map = {"IpPermissions": "IpPermissionInbound", "IpPermissionEgress": "IpPermissionEgress"}
if group.get(rule_type):
for rule in group[rule_type]:
protocol = rule.get("IpProtocol", "all")
from_port = rule.get("FromPort", "")
to_port = rule.get("ToPort", "")
ruleid = "{0}/{1}/{2}{3}{4}".format(group_id, rule_type, from_port, to_port, protocol)
# NOTE Cypher query syntax is incompatible with Python string formatting, so we have to do this awkward
# NOTE manual formatting instead.
session.run(
ingest_rule.replace("#RULE_TYPE#", rule_type_map[rule_type]),
RuleId=ruleid,
FromPort=from_port,
ToPort=to_port,
Protocol=protocol,
GroupId=group_id,
aws_update_tag=aws_update_tag
)
session.run(
ingest_rule_group_pair,
GroupId=group_id,
RuleId=ruleid,
aws_update_tag=aws_update_tag
)
for ip_range in rule["IpRanges"]:
range_id = ip_range["CidrIp"]
session.run(
ingest_range,
RangeId=range_id,
RuleId=ruleid,
aws_update_tag=aws_update_tag
)