From 772880f95227eb404b52a0f0226913564242e746 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 5 Sep 2019 15:03:30 +0300 Subject: [PATCH] Added resources explicitly for testing, improved analyzer, added config parser class --- .../analyzers/communication_analyzer.py | 20 ++++++++++++------- .../blackbox/island_config_parser.py | 16 +++++++++++++++ envs/monkey_zoo/blackbox/test_blackbox.py | 18 ++++++++--------- monkey/monkey_island/cc/app.py | 2 ++ .../cc/resources/test/__init__.py | 0 .../cc/resources/test/monkey_test.py | 14 +++++++++++++ 6 files changed, 53 insertions(+), 17 deletions(-) create mode 100644 envs/monkey_zoo/blackbox/island_config_parser.py create mode 100644 monkey/monkey_island/cc/resources/test/__init__.py create mode 100644 monkey/monkey_island/cc/resources/test/monkey_test.py diff --git a/envs/monkey_zoo/blackbox/analyzers/communication_analyzer.py b/envs/monkey_zoo/blackbox/analyzers/communication_analyzer.py index 3afb528f7..e4638233f 100644 --- a/envs/monkey_zoo/blackbox/analyzers/communication_analyzer.py +++ b/envs/monkey_zoo/blackbox/analyzers/communication_analyzer.py @@ -1,16 +1,22 @@ +import json + class CommunicationAnalyzer(object): - def __init__(self, island_client, machines): + def __init__(self, island_client, machine_ips): self.island_client = island_client - self.machines = machines + self.machine_ips = machine_ips def analyze_test_results(self): - for machine in self.machines: - if self.did_monkey_communicate_back(machine): - print("Monkey from {} communicated back".format(machine)) + for machine_ip in self.machine_ips: + if not self.did_monkey_communicate_back(machine_ip): + return False + print("Monkey from {} communicated back".format(machine_ip)) + return True - def did_monkey_communicate_back(self, monkey_ip): - request = self.island_client.send_get_request("api/telemetry", {'telem_category': 'state'}) + def did_monkey_communicate_back(self, machine_ip): + query = json.dumps({'ip_addresses': {'$elemMatch': {'$eq': machine_ip}}}) + response = self.island_client.send_get_request("api/test/monkey", {'find_query': query}) + return len(json.loads(response.content)['results']) > 0 diff --git a/envs/monkey_zoo/blackbox/island_config_parser.py b/envs/monkey_zoo/blackbox/island_config_parser.py new file mode 100644 index 000000000..63c98cb75 --- /dev/null +++ b/envs/monkey_zoo/blackbox/island_config_parser.py @@ -0,0 +1,16 @@ +import json +import os + + +class IslandConfigParser(object): + + def __init__(self, config_filename): + self.config_raw = open(IslandConfigParser.get_conf_file_path(config_filename), 'r').read() + self.config_json = json.loads(self.config_raw) + + def get_ips_of_targets(self): + return self.config_json['basic_network']['general']['subnet_scan_list'] + + @staticmethod + def get_conf_file_path(conf_file_name): + return os.path.join(os.path.dirname(os.path.abspath(__file__)), "island_configs", conf_file_name) diff --git a/envs/monkey_zoo/blackbox/test_blackbox.py b/envs/monkey_zoo/blackbox/test_blackbox.py index 708cbca24..5ef7e16f5 100644 --- a/envs/monkey_zoo/blackbox/test_blackbox.py +++ b/envs/monkey_zoo/blackbox/test_blackbox.py @@ -1,16 +1,15 @@ -import os import unittest import pytest from envs.monkey_zoo.blackbox.monkey_island_client import MonkeyIslandClient from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import CommunicationAnalyzer +from envs.monkey_zoo.blackbox.island_config_parser import IslandConfigParser -def generic_blackbox_test_case(client, config_file_path, analyzers): - with open(config_file_path, "r") as config_file: - client.import_config(config_file.read()) - client.run_monkey_local() +def generic_blackbox_test_case(client, raw_config, analyzers): + client.import_config(raw_config) + # client.run_monkey_local() for analyzer in analyzers: assert analyzer.analyze_test_results() @@ -33,11 +32,10 @@ class TestMonkeyBlackbox(unittest.TestCase): assert client.get_api_status() is not None def test_ssh_exec(self): + conf_file_name = 'SSH.conf' client = MonkeyIslandClient(self.island) - conf_file_name = "SSH.conf" - generic_blackbox_test_case(client, get_conf_file_path(conf_file_name), - [CommunicationAnalyzer(client, ["10.2.2.41", "10.2.2.42"])]) + config_parser = IslandConfigParser(conf_file_name) + analyzer = CommunicationAnalyzer(client, config_parser.get_ips_of_targets()) + generic_blackbox_test_case(client, config_parser.config_raw, [analyzer]) -def get_conf_file_path(conf_file_name): - return os.path.join(os.path.dirname(os.path.abspath(__file__)), "island_configs", conf_file_name) diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py index 2e04ef0be..7d27995ab 100644 --- a/monkey/monkey_island/cc/app.py +++ b/monkey/monkey_island/cc/app.py @@ -35,6 +35,7 @@ from monkey_island.cc.services.remote_run_aws import RemoteRunAwsService from monkey_island.cc.resources.pba_file_upload import FileUpload from monkey_island.cc.resources.attack.attack_config import AttackConfiguration from monkey_island.cc.resources.attack.attack_report import AttackReport +from monkey_island.cc.resources.test.monkey_test import MonkeyTest __author__ = 'Barak' @@ -134,6 +135,7 @@ def init_api_resources(api): api.add_resource(AttackConfiguration, '/api/attack') api.add_resource(AttackReport, '/api/attack/report') api.add_resource(VersionUpdate, '/api/version-update', '/api/version-update/') + api.add_resource(MonkeyTest, '/api/test/monkey') def init_app(mongo_url): diff --git a/monkey/monkey_island/cc/resources/test/__init__.py b/monkey/monkey_island/cc/resources/test/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/monkey/monkey_island/cc/resources/test/monkey_test.py b/monkey/monkey_island/cc/resources/test/monkey_test.py new file mode 100644 index 000000000..365f30dc9 --- /dev/null +++ b/monkey/monkey_island/cc/resources/test/monkey_test.py @@ -0,0 +1,14 @@ +import json + +import flask_restful +from flask import request + +from monkey_island.cc.auth import jwt_required +from monkey_island.cc.database import mongo + + +class MonkeyTest(flask_restful.Resource): + @jwt_required() + def get(self, **kw): + find_query = json.loads(request.args.get('find_query')) + return {'results': list(mongo.db.monkey.find(find_query))}