duo-labs / cloudmapper

CloudMapper helps you analyze your Amazon Web Services (AWS) environments.
BSD 3-Clause "New" or "Revised" License
5.98k stars 805 forks source link

Lateral flows missing across VPC peers due to sg_to_instance_mapping #207

Closed jaycgen closed 4 years ago

jaycgen commented 6 years ago

Recognise a potential overlap with https://github.com/duo-labs/cloudmapper/issues/72

Summary

In an environment with 2 or more VPCS (affects single account, single region), cross-vpc lateral movement flows that are permitted by Security Group rules are not represented as edges by prepare.py. The VPCs are correctly identified as peers by collect.py.

Steps to reproduce

• Create 2x VPCs within an AWS account (using same region in this example) • Create 2x private subnet with associated routing, 1x within each VPC • Create 2x security groups, 1x within each VPC

Root cause?

as part of the _getconnections function within prepare.py the loop for target in sg_to_instance_mapping.get(sg["GroupId"], {}): appears to try and find a match on security group, however the subsequent for source in sg_to_instance_mapping.get(ingress_sg, {}): finds no known instances within the dictionary

To the best of my knowledge the following code is looking too narrowly:

    # Get mapping of security group names to nodes that have that security group
    sg_to_instance_mapping = {}
    for instance in vpc.leaves:
        for sg in instance.security_groups():
            sg_to_instance_mapping.setdefault(sg, {})[instance] = True

Solution?

If we expand the instance mapping to vpc peers, then we find the other matches, and display them in the graph

    # Get mapping of security group names to nodes that have that security group
    sg_to_instance_mapping = {}
    for instance in vpc.leaves:
        for sg in instance.security_groups():
            sg_to_instance_mapping.setdefault(sg, {})[instance] = True
    # Get mapping from VPC peers as well
    for peer in vpc.peers:
        for instance in peer.leaves:
            for sg in instance.security_groups():
                sg_to_instance_mapping.setdefault(sg, {})[instance] = True

I don't believe we'll get any unwanted collisions or extra edges, but not tested exhaustively

0xdabbad00 commented 4 years ago

I'm closing this issue as the network diagram functionality of CloudMapper is no longer being maintained. Other features of CloudMapper, such as the audit functionality, is still maintained. If someone is interested in maintaining the network diagram functionality they can look at the issues tagged unmaintained_functionality for all the issues related to this that have been closed as they will unfortunately not be worked on by me.