From 434c72f69f808bf9f50e2988644762a05667ef91 Mon Sep 17 00:00:00 2001 From: Itay Mizeretz Date: Tue, 12 Dec 2017 16:33:16 +0200 Subject: [PATCH] Implemented issues and warnings on overview --- monkey_island/cc/services/report.py | 68 ++++++++++++-- .../cc/ui/src/components/pages/ReportPage.js | 94 ++++++++++++------- 2 files changed, 119 insertions(+), 43 deletions(-) diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py index ab6c9fb13..4b3bf8573 100644 --- a/monkey_island/cc/services/report.py +++ b/monkey_island/cc/services/report.py @@ -25,6 +25,18 @@ class ReportService: 'ShellShockExploiter': 'ShellShock Exploiter', } + class ISSUES_DICT: + WEAK_PASSWORD = 0 + STOLEN_CREDS = 1 + ELASTIC = 2 + SAMBACRY = 3 + SHELLSHOCK = 4 + CONFICKER = 5 + + class WARNINGS_DICT: + CROSS_SEGMENT = 0 + TUNNEL = 1 + @staticmethod def get_first_monkey_time(): return mongo.db.telemetry.find({}, {'timestamp': 1}).sort([('$natural', 1)]).limit(1)[0]['timestamp'] @@ -139,6 +151,7 @@ class ReportService: processed_exploit['username'] = attempt['user'] if len(attempt['password']) > 0: processed_exploit['type'] = 'password' + processed_exploit['password'] = attempt['password'] else: processed_exploit['type'] = 'hash' return processed_exploit @@ -232,9 +245,9 @@ class ReportService: @staticmethod def get_monkey_subnets(monkey_guid): network_info = mongo.db.telemetry.find_one( - {'telem_type': 'system_info_collection', 'monkey_guid': monkey_guid}, - {'data.network_info.networks': 1} - ) + {'telem_type': 'system_info_collection', 'monkey_guid': monkey_guid}, + {'data.network_info.networks': 1} + ) if network_info is None: return [] @@ -315,22 +328,61 @@ class ReportService: def get_config_scan(): return ConfigService.get_config_value(['basic_network', 'general', 'local_network_scan'], True) + @staticmethod + def get_issues_overview(issues, config_users, config_passwords): + issues_byte_array = [False] * 6 + + for machine in issues: + for issue in issues[machine]: + if issue['type'] == 'elastic': + issues_byte_array[ReportService.ISSUES_DICT.ELASTIC] = True + elif issue['type'] == 'sambacry': + issues_byte_array[ReportService.ISSUES_DICT.SAMBACRY] = True + elif issue['type'] == 'shellshock': + issues_byte_array[ReportService.ISSUES_DICT.SHELLSHOCK] = True + elif issue['type'] == 'conficker': + issues_byte_array[ReportService.ISSUES_DICT.CONFICKER] = True + elif issue['type'].endswith('_password') and issue['password'] in config_passwords and \ + issue['username'] in config_users: + issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD] = True + elif issue['type'].endswith('_pth') or issue['type'].endswith('_password'): + issues_byte_array[ReportService.ISSUES_DICT.STOLEN_CREDS] = True + + return issues_byte_array + + @staticmethod + def get_warnings_overview(issues): + warnings_byte_array = [False] * 2 + + for machine in issues: + for issue in issues[machine]: + if issue['type'] == 'cross_segment': + warnings_byte_array[ReportService.WARNINGS_DICT.CROSS_SEGMENT] = True + elif issue['type'] == 'tunnel': + warnings_byte_array[ReportService.WARNINGS_DICT.TUNNEL] = True + + return warnings_byte_array + @staticmethod def get_report(): + issues = ReportService.get_issues() + config_users = ReportService.get_config_users() + config_passwords = ReportService.get_config_passwords() + return \ { 'overview': { 'manual_monkeys': ReportService.get_manual_monkeys(), - 'config_users': ReportService.get_config_users(), - 'config_passwords': ReportService.get_config_passwords(), + 'config_users': config_users, + 'config_passwords': config_passwords, 'config_exploits': ReportService.get_config_exploits(), 'config_ips': ReportService.get_config_ips(), 'config_scan': ReportService.get_config_scan(), 'monkey_start_time': ReportService.get_first_monkey_time().strftime("%d/%m/%Y %H:%M:%S"), 'monkey_duration': ReportService.get_monkey_duration(), - 'issues': [False, True, True, True, False, True], - 'warnings': [True, True] + 'issues': ReportService.get_issues_overview(issues, config_users, config_passwords), + 'warnings': ReportService.get_warnings_overview(issues) }, 'glance': { @@ -340,7 +392,7 @@ class ReportService: }, 'recommendations': { - 'issues': ReportService.get_issues() + 'issues': issues } } diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js index a058ce516..e5e1fd3af 100644 --- a/monkey_island/cc/ui/src/components/pages/ReportPage.js +++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js @@ -498,46 +498,70 @@ class ReportPageComponent extends React.Component {

Immediate Threats

- During this simulated attack the Monkey uncovered {this.state.report.overview.issues.filter(function (x) { - return x === true; - }).length} issues: - + { + this.state.report.overview.issues.filter(function (x) { + return x === true; + }).length > 0 ? +
+ During this simulated attack the Monkey uncovered + {this.state.report.overview.issues.filter(function (x) { + return x === true; + }).length} issues: + +
+ : +
+ During this simulated attack the Monkey uncovered 0 issues. +
+ }

Security Issues

- The monkey uncovered the following possible set of issues: - + { + this.state.report.overview.warnings.filter(function (x) { + return x === true; + }).length > 0 ? +
+ The monkey uncovered the following possible set of issues: +
    + {this.state.report.overview.warnings[this.Warning.CROSS_SEGMENT] ? +
  • Possible cross segment traffic. Infected machines could communicate with the + Monkey Island despite crossing segment boundaries using unused ports.
  • : null} + {this.state.report.overview.warnings[this.Warning.TUNNEL] ? +
  • Lack of Micro-segmentation, machines successfully tunneled monkey activity + using unused ports.
  • : null} +
+
+ : +
+ The monkey did not find any issues. +
+ }