From d831769d1fec1afd5d97a34c5c457d508fe8e333 Mon Sep 17 00:00:00 2001 From: Itay Mizeretz Date: Wed, 23 May 2018 18:06:30 +0300 Subject: [PATCH] Fix CR --- monkey_island/cc/services/config.py | 11 +++- monkey_island/cc/services/report.py | 61 +++++++++++++++++-- .../cc/ui/src/components/pages/ReportPage.js | 13 ++-- 3 files changed, 74 insertions(+), 11 deletions(-) diff --git a/monkey_island/cc/services/config.py b/monkey_island/cc/services/config.py index 8294e0bb3..5bddc1901 100644 --- a/monkey_island/cc/services/config.py +++ b/monkey_island/cc/services/config.py @@ -241,9 +241,14 @@ SCHEMA = { "default": [ ], "description": - "List of IP/subnet groups. Each group should consist of subnets that aren't supposed" - " to be accessible to one another. If the monkey is in one subnet it'll scan the other" - " subnets in the same group." + "You can use this feature to test for network segmentation, by proving lists of" + " IP/subnet groups that should not be accessible to each other. Each input group" + " consists of subnets that should not be accessible to each other. If the Monkey" + " is inside of one of the subnets it will attempt to connect to machines in the" + " other subnet." + " Example, by providing input 192.168.1.0/24, 192.168.2.0/24, 192.168.3.1-192.168.3.10," + " a Monkey with the IP address 192.168.2.5 will try to access machines inside" + " 192.168.1.0/24 or 192.168.3.1-192.168.3.10." } } } diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py index a4dcb7f57..ba2fc56b3 100644 --- a/monkey_island/cc/services/report.py +++ b/monkey_island/cc/services/report.py @@ -1,4 +1,5 @@ import itertools +import functools import ipaddress from enum import Enum @@ -329,11 +330,52 @@ class ReportService: return ip_address return None + @staticmethod + def get_cross_segment_issues_of_single_machine(source_subnet_range, target_subnet_range): + """ + Gets list of cross segment issues of a single machine. Meaning a machine has an interface for each of the + subnets. + :param source_subnet_range: The subnet range which shouldn't be able to access target_subnet. + :param target_subnet_range: The subnet range which shouldn't be accessible from source_subnet. + :return: + """ + cross_segment_issues = [] + + for monkey in mongo.db.monkey.find({}, {'ip_addresses': 1, 'hostname': 1}): + ip_in_src = None + ip_in_dst = None + for ip_addr in monkey['ip_addresses']: + if source_subnet_range.is_in_range(unicode(ip_addr)): + ip_in_src = ip_addr + break + + # No point searching the dst subnet if there are no IPs in src subnet. + if not ip_in_src: + continue + + for ip_addr in monkey['ip_addresses']: + if target_subnet_range.is_in_range(unicode(ip_addr)): + ip_in_dst = ip_addr + break + + if ip_in_dst: + cross_segment_issues.append( + { + 'source': ip_in_src, + 'hostname': monkey['hostname'], + 'target': ip_in_dst, + 'services': None, + 'is_self': True + }) + + return cross_segment_issues + @staticmethod def get_cross_segment_issues_per_subnet_pair(scans, source_subnet, target_subnet): """ Gets list of cross segment issues from source_subnet to target_subnet. :param scans: List of all scan telemetry entries. Must have monkey_guid, ip_addr and services. + This should be a PyMongo cursor object. :param source_subnet: The subnet which shouldn't be able to access target_subnet. :param target_subnet: The subnet which shouldn't be accessible from source_subnet. :return: @@ -345,6 +387,7 @@ class ReportService: cross_segment_issues = [] + scans.rewind() # If we iterated over scans already we need to rewind. for scan in scans: target_ip = scan['data']['machine']['ip_addr'] if target_subnet_range.is_in_range(unicode(target_ip)): @@ -359,16 +402,19 @@ class ReportService: 'source': cross_segment_ip, 'hostname': monkey['hostname'], 'target': target_ip, - 'services': scan['data']['machine']['services'] + 'services': scan['data']['machine']['services'], + 'is_self': False }) - return cross_segment_issues + return cross_segment_issues + ReportService.get_cross_segment_issues_of_single_machine( + source_subnet_range, target_subnet_range) @staticmethod def get_cross_segment_issues_per_subnet_group(scans, subnet_group): """ Gets list of cross segment issues within given subnet_group. :param scans: List of all scan telemetry entries. Must have monkey_guid, ip_addr and services. + This should be a PyMongo cursor object. :param subnet_group: List of subnets which shouldn't be accessible from each other. :return: Cross segment issues regarding the subnets in the group. """ @@ -405,8 +451,15 @@ class ReportService: @staticmethod def get_issues(): - issues = ReportService.get_exploits() + ReportService.get_tunnels() \ - + ReportService.get_island_cross_segment_issues() + ReportService.get_azure_issues() + ISSUE_GENERATORS = [ + ReportService.get_exploits, + ReportService.get_tunnels, + ReportService.get_island_cross_segment_issues, + ReportService.get_azure_issues + ] + + issues = functools.reduce(lambda acc, issue_gen: acc + issue_gen(), ISSUE_GENERATORS, []) + issues_dict = {} for issue in issues: machine = issue['machine'] diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js index d92b06f7d..278d6152f 100644 --- a/monkey_island/cc/ui/src/components/pages/ReportPage.js +++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js @@ -456,10 +456,15 @@ class ReportPageComponent extends AuthComponent {