Example #1
0
 def reset_db():
     remove_PBA_files()
     # We can't drop system collections.
     [mongo.db[x].drop() for x in mongo.db.collection_names() if not x.startswith('system.')]
     ConfigService.init_config()
     logger.info('DB was reset')
     return jsonify(status='OK')
Example #2
0
def add_system_info_ssh_keys_to_config(ssh_info):
    for user in ssh_info:
        ConfigService.creds_add_username(user["name"])
        # Public key is useless without private key
        if user["public_key"] and user["private_key"]:
            ConfigService.ssh_add_keys(user["public_key"], user["private_key"],
                                       user["name"], user["ip"])
Example #3
0
def add_system_info_ssh_keys_to_config(ssh_info):
    for user in ssh_info:
        ConfigService.creds_add_username(user['name'])
        # Public key is useless without private key
        if user['public_key'] and user['private_key']:
            ConfigService.ssh_add_keys(user['public_key'], user['private_key'],
                                       user['name'], user['ip'])
Example #4
0
 def post(self):
     config_json = json.loads(request.data)
     if 'reset' in config_json:
         ConfigService.reset_config()
     else:
         if not ConfigService.update_config(config_json, should_encrypt=True):
             abort(400)
     return self.get()
Example #5
0
def init_app(mongo_url):
    app = Flask(__name__)

    api = flask_restful.Api(app)
    api.representations = {'application/json': output_json}

    app.config['MONGO_URI'] = mongo_url

    app.config['SECRET_KEY'] = str(uuid.getnode())
    app.config['JWT_AUTH_URL_RULE'] = '/api/auth'
    app.config['JWT_EXPIRATION_DELTA'] = env.get_auth_expiration_time()

    init_jwt(app)
    mongo.init_app(app)

    with app.app_context():
        database.init()
        ConfigService.init_config()

    # If running on AWS, this will initialize the instance data, which is used "later" in the execution of the island.
    RemoteRunAwsService.init()

    app.add_url_rule('/', 'serve_home', serve_home)
    app.add_url_rule('/<path:static_path>', 'serve_static_file',
                     serve_static_file)

    api.add_resource(Root, '/api')
    api.add_resource(Monkey, '/api/monkey', '/api/monkey/',
                     '/api/monkey/<string:guid>')
    api.add_resource(LocalRun, '/api/local-monkey', '/api/local-monkey/')
    api.add_resource(ClientRun, '/api/client-monkey', '/api/client-monkey/')
    api.add_resource(Telemetry, '/api/telemetry', '/api/telemetry/',
                     '/api/telemetry/<string:monkey_guid>')
    api.add_resource(MonkeyConfiguration, '/api/configuration',
                     '/api/configuration/')
    api.add_resource(IslandConfiguration, '/api/configuration/island',
                     '/api/configuration/island/')
    api.add_resource(MonkeyDownload, '/api/monkey/download',
                     '/api/monkey/download/',
                     '/api/monkey/download/<string:path>')
    api.add_resource(NetMap, '/api/netmap', '/api/netmap/')
    api.add_resource(Edge, '/api/netmap/edge', '/api/netmap/edge/')
    api.add_resource(Node, '/api/netmap/node', '/api/netmap/node/')
    api.add_resource(Report, '/api/report', '/api/report/')
    api.add_resource(TelemetryFeed, '/api/telemetry-feed',
                     '/api/telemetry-feed/')
    api.add_resource(Log, '/api/log', '/api/log/')
    api.add_resource(IslandLog, '/api/log/island/download',
                     '/api/log/island/download/')
    api.add_resource(PBAFileDownload, '/api/pba/download/<string:path>')
    api.add_resource(
        FileUpload, '/api/fileUpload/<string:file_type>',
        '/api/fileUpload/<string:file_type>?load=<string:filename>',
        '/api/fileUpload/<string:file_type>?restore=<string:filename>')
    api.add_resource(RemoteRun, '/api/remote-monkey', '/api/remote-monkey/')
    api.add_resource(AttackTelem, '/api/attack/<string:technique>')

    return app
Example #6
0
def init_app_services(app):
    init_jwt(app)
    mongo.init_app(app)

    with app.app_context():
        database.init()
        ConfigService.init_config()

    # If running on AWS, this will initialize the instance data, which is used "later" in the execution of the island.
    RemoteRunAwsService.init()
Example #7
0
 def apply_to_monkey_config():
     """
     Applies ATT&CK matrix to the monkey configuration
     :return:
     """
     attack_techniques = AttackConfig.get_technique_values()
     monkey_config = ConfigService.get_config(False, True, True)
     monkey_schema = ConfigService.get_config_schema()
     AttackConfig.set_arrays(attack_techniques, monkey_config, monkey_schema)
     AttackConfig.set_booleans(attack_techniques, monkey_config, monkey_schema)
     ConfigService.update_config(monkey_config, True)
Example #8
0
    def get_config_exploits():
        exploits_config_value = ['exploits', 'general', 'exploiter_classes']
        default_exploits = ConfigService.get_default_config(False)
        for namespace in exploits_config_value:
            default_exploits = default_exploits[namespace]
        exploits = ConfigService.get_config_value(exploits_config_value, True, True)

        if exploits == default_exploits:
            return ['default']

        return [ReportService.EXPLOIT_DISPLAY_DICT[exploit] for exploit in
                exploits]
Example #9
0
 def reset_db():
     logger.info("Resetting database")
     # We can't drop system collections.
     [
         Database.drop_collection(x) for x in mongo.db.collection_names()
         if not x.startswith("system.")
         and not x == AttackMitigations.COLLECTION_NAME
     ]
     ConfigService.init_config()
     AttackConfig.reset_config()
     logger.info("DB was reset")
     return jsonify(status="OK")
Example #10
0
    def get_config_exploits():
        exploits_config_value = EXPLOITER_CLASSES_PATH
        default_exploits = ConfigService.get_default_config(False)
        for namespace in exploits_config_value:
            default_exploits = default_exploits[namespace]
        exploits = ConfigService.get_config_value(exploits_config_value, True, True)

        if exploits == default_exploits:
            return ["default"]

        return [
            ExploiterDescriptorEnum.get_by_class_name(exploit).display_name for exploit in exploits
        ]
Example #11
0
 def reset_db():
     logger.info('Resetting database')
     remove_PBA_files()
     # We can't drop system collections.
     [
         Database.drop_collection(x) for x in mongo.db.collection_names()
         if not x.startswith('system.')
         and not x == AttackMitigations.COLLECTION_NAME
     ]
     ConfigService.init_config()
     AttackConfig.reset_config()
     logger.info('DB was reset')
     return jsonify(status='OK')
Example #12
0
 def get(self, file_type):
     """
     Sends file to filepond
     :param file_type: Type indicates which file to send, linux or windows
     :return: Returns file contents
     """
     # Verify that file_name is indeed a file from config
     if file_type == LINUX_PBA_TYPE:
         filename = ConfigService.get_config_value(
             copy.deepcopy(PBA_LINUX_FILENAME_PATH))
     else:
         filename = ConfigService.get_config_value(
             copy.deepcopy(PBA_WINDOWS_FILENAME_PATH))
     return send_from_directory(ABS_UPLOAD_PATH, filename)
Example #13
0
 def upload_pba_file(request_, is_linux=True):
     """
     Uploads PBA file to island's file system
     :param request_: Request object containing PBA file
     :param is_linux: Boolean indicating if this file is for windows or for linux
     :return: filename string
     """
     filename = secure_filename(request_.files['filepond'].filename)
     file_path = ABS_UPLOAD_PATH.joinpath(filename).absolute()
     request_.files['filepond'].save(str(file_path))
     ConfigService.set_config_value(
         (PBA_LINUX_FILENAME_PATH
          if is_linux else PBA_WINDOWS_FILENAME_PATH), filename)
     return filename
Example #14
0
    def get_config_exploits():
        exploits_config_value = EXPLOITER_CLASSES_PATH
        default_exploits = ConfigService.get_default_config(False)
        for namespace in exploits_config_value:
            default_exploits = default_exploits[namespace]
        exploits = ConfigService.get_config_value(exploits_config_value, True,
                                                  True)

        if exploits == default_exploits:
            return ['default']

        return [
            ReportService.EXPLOIT_DISPLAY_DICT[exploit] for exploit in exploits
        ]
Example #15
0
    def delete(self, file_type):
        """
        Deletes file that has been deleted on the front end
        :param file_type: Type indicates which file was deleted, linux of windows
        :return: Empty response
        """
        filename_path = (PBA_LINUX_FILENAME_PATH if file_type == "PBAlinux"
                         else PBA_WINDOWS_FILENAME_PATH)
        filename = ConfigService.get_config_value(filename_path)
        if filename:
            PostBreachFilesService.remove_file(filename)
            ConfigService.set_config_value(filename_path, "")

        return {}
Example #16
0
def init_app(mongo_url):
    app = Flask(__name__)

    api = flask_restful.Api(app)
    api.representations = {'application/json': output_json}

    app.config['MONGO_URI'] = mongo_url

    app.config['SECRET_KEY'] = str(uuid.getnode())
    app.config['JWT_AUTH_URL_RULE'] = '/api/auth'
    app.config['JWT_EXPIRATION_DELTA'] = env.get_auth_expiration_time()

    init_jwt(app)
    mongo.init_app(app)

    with app.app_context():
        database.init()
        ConfigService.init_config()

    app.add_url_rule('/', 'serve_home', serve_home)
    app.add_url_rule('/<path:static_path>', 'serve_static_file',
                     serve_static_file)

    api.add_resource(Root, '/api')
    api.add_resource(Monkey, '/api/monkey', '/api/monkey/',
                     '/api/monkey/<string:guid>')
    api.add_resource(LocalRun, '/api/local-monkey', '/api/local-monkey/')
    api.add_resource(ClientRun, '/api/client-monkey', '/api/client-monkey/')
    api.add_resource(Telemetry, '/api/telemetry', '/api/telemetry/',
                     '/api/telemetry/<string:monkey_guid>')
    api.add_resource(MonkeyConfiguration, '/api/configuration',
                     '/api/configuration/')
    api.add_resource(IslandConfiguration, '/api/configuration/island',
                     '/api/configuration/island/')
    api.add_resource(MonkeyDownload, '/api/monkey/download',
                     '/api/monkey/download/',
                     '/api/monkey/download/<string:path>')
    api.add_resource(NetMap, '/api/netmap', '/api/netmap/')
    api.add_resource(Edge, '/api/netmap/edge', '/api/netmap/edge/')
    api.add_resource(Node, '/api/netmap/node', '/api/netmap/node/')
    api.add_resource(Report, '/api/report', '/api/report/')
    api.add_resource(TelemetryFeed, '/api/telemetry-feed',
                     '/api/telemetry-feed/')
    api.add_resource(Log, '/api/log', '/api/log/')
    api.add_resource(IslandLog, '/api/log/island/download',
                     '/api/log/island/download/')
    api.add_resource(RemoteRun, '/api/remote-monkey', '/api/remote-monkey/')

    return app
Example #17
0
def add_system_info_creds_to_config(creds):
    for user in creds:
        ConfigService.creds_add_username(user)
        if 'password' in creds[user]:
            ConfigService.creds_add_password(creds[user]['password'])
        if 'lm_hash' in creds[user]:
            ConfigService.creds_add_lm_hash(creds[user]['lm_hash'])
        if 'ntlm_hash' in creds[user]:
            ConfigService.creds_add_ntlm_hash(creds[user]['ntlm_hash'])
Example #18
0
def add_system_info_creds_to_config(creds):
    for user in creds:
        ConfigService.creds_add_username(creds[user]["username"])
        if "password" in creds[user] and creds[user]["password"]:
            ConfigService.creds_add_password(creds[user]["password"])
        if "lm_hash" in creds[user] and creds[user]["lm_hash"]:
            ConfigService.creds_add_lm_hash(creds[user]["lm_hash"])
        if "ntlm_hash" in creds[user] and creds[user]["ntlm_hash"]:
            ConfigService.creds_add_ntlm_hash(creds[user]["ntlm_hash"])
Example #19
0
    def upload_pba_file(file_storage: FileStorage, is_linux=True):
        """
        Uploads PBA file to island's file system
        :param request_: Request object containing PBA file
        :param is_linux: Boolean indicating if this file is for windows or for linux
        :return: filename string
        """
        filename = secure_filename(file_storage.filename)
        file_contents = file_storage.read()

        PostBreachFilesService.save_file(filename, file_contents)

        ConfigService.set_config_value(
            (PBA_LINUX_FILENAME_PATH
             if is_linux else PBA_WINDOWS_FILENAME_PATH), filename)

        return filename
Example #20
0
 def _on_finished_infection():
     # Checking is_report_being_generated here, because we don't want to wait to generate a
     # report; rather,
     # we want to skip and reply.
     if not is_report_being_generated() and not ReportService.is_latest_report_exists():
         safe_generate_reports()
     if ConfigService.is_test_telem_export_enabled() and not TestTelemStore.TELEMS_EXPORTED:
         TestTelemStore.export_telems()
Example #21
0
    def update_aws_auth_params():
        """
        Updates the AWS authentication parameters according to config
        :return: True if new params allow successful authentication. False otherwise
        """
        access_key_id = ConfigService.get_config_value(
            ['cnc', 'aws_config', 'aws_access_key_id'], False, True)
        secret_access_key = ConfigService.get_config_value(
            ['cnc', 'aws_config', 'aws_secret_access_key'], False, True)

        if (access_key_id != AwsService.access_key_id) or (
                secret_access_key != AwsService.secret_access_key):
            AwsService.set_auth_params(access_key_id, secret_access_key)
            RemoteRunAwsService.is_auth = AwsService.test_client()

        AwsService.set_region(RemoteRunAwsService.aws_instance.region)

        return RemoteRunAwsService.is_auth
Example #22
0
def test_is_aws_keys_setup(tmp_path):
    # Mock default configuration
    ConfigService.init_default_config()
    mongo.db = MockObject()
    mongo.db.config = MockObject()
    ConfigService.encrypt_config(ConfigService.default_config)
    mongo.db.config.find_one = MagicMock(return_value=ConfigService.default_config)
    assert not is_aws_keys_setup()

    bogus_key_value = get_datastore_encryptor().encrypt("bogus_aws_key")
    dpath.util.set(
        ConfigService.default_config, AWS_KEYS_PATH + ["aws_secret_access_key"], bogus_key_value
    )
    dpath.util.set(
        ConfigService.default_config, AWS_KEYS_PATH + ["aws_access_key_id"], bogus_key_value
    )

    assert is_aws_keys_setup()
Example #23
0
def test_is_aws_keys_setup():
    # Mock default configuration
    ConfigService.init_default_config()
    mongo.db = MockObject()
    mongo.db.config = MockObject()
    ConfigService.encrypt_config(ConfigService.default_config)
    mongo.db.config.find_one = MagicMock(
        return_value=ConfigService.default_config)
    assert not is_aws_keys_setup()

    # Make sure noone changed config path and broke this function
    bogus_key_value = encryptor.encryptor.enc('bogus_aws_key')
    dpath.util.set(ConfigService.default_config,
                   AWS_KEYS_PATH + ['aws_secret_access_key'], bogus_key_value)
    dpath.util.set(ConfigService.default_config,
                   AWS_KEYS_PATH + ['aws_access_key_id'], bogus_key_value)

    assert is_aws_keys_setup()
Example #24
0
    def delete(self, file_type):
        """
        Deletes file that has been deleted on the front end
        :param file_type: Type indicates which file was deleted, linux of windows
        :return: Empty response
        """
        filename_path = PBA_LINUX_FILENAME_PATH if file_type == 'PBAlinux' else PBA_WINDOWS_FILENAME_PATH
        filename = ConfigService.get_config_value(filename_path)
        file_path = ABS_UPLOAD_PATH.joinpath(filename)
        try:
            if os.path.exists(file_path):
                os.remove(file_path)
            ConfigService.set_config_value(filename_path, '')
        except OSError as e:
            LOG.error(
                "Can't remove previously uploaded post breach files: %s" % e)

        return {}
Example #25
0
    def delete(self, file_type):
        """
        Deletes file that has been deleted on the front end
        :param file_type: Type indicates which file was deleted, linux of windows
        :return: Empty response
        """
        if self.is_pba_file_type_supported(file_type):
            return Response(status=HTTPStatus.UNPROCESSABLE_ENTITY,
                            mimetype="text/plain")

        filename_path = (PBA_LINUX_FILENAME_PATH if file_type == "PBAlinux"
                         else PBA_WINDOWS_FILENAME_PATH)
        filename = ConfigService.get_config_value(filename_path)
        if filename:
            PostBreachFilesService.remove_file(filename)
            ConfigService.set_config_value(filename_path, "")

        return {}
Example #26
0
def add_exploit_extracted_creds_to_config(telemetry_json):
    if 'credentials' in telemetry_json['data']['info']:
        creds = telemetry_json['data']['info']['credentials']
        for user in creds:
            ConfigService.creds_add_username(creds[user]['username'])
            if 'password' in creds[user] and creds[user]['password']:
                ConfigService.creds_add_password(creds[user]['password'])
            if 'lm_hash' in creds[user] and creds[user]['lm_hash']:
                ConfigService.creds_add_lm_hash(creds[user]['lm_hash'])
            if 'ntlm_hash' in creds[user] and creds[user]['ntlm_hash']:
                ConfigService.creds_add_ntlm_hash(creds[user]['ntlm_hash'])
Example #27
0
def add_exploit_extracted_creds_to_config(telemetry_json):
    if "credentials" in telemetry_json["data"]["info"]:
        creds = telemetry_json["data"]["info"]["credentials"]
        for user in creds:
            ConfigService.creds_add_username(creds[user]["username"])
            if "password" in creds[user] and creds[user]["password"]:
                ConfigService.creds_add_password(creds[user]["password"])
            if "lm_hash" in creds[user] and creds[user]["lm_hash"]:
                ConfigService.creds_add_lm_hash(creds[user]["lm_hash"])
            if "ntlm_hash" in creds[user] and creds[user]["ntlm_hash"]:
                ConfigService.creds_add_ntlm_hash(creds[user]["ntlm_hash"])
Example #28
0
    def get(self, file_type):
        """
        Sends file to filepond
        :param file_type: Type indicates which file to send, linux or windows
        :return: Returns file contents
        """
        if self.is_pba_file_type_supported(file_type):
            return Response(status=HTTPStatus.UNPROCESSABLE_ENTITY,
                            mimetype="text/plain")

        # Verify that file_name is indeed a file from config
        if file_type == LINUX_PBA_TYPE:
            filename = ConfigService.get_config_value(
                copy.deepcopy(PBA_LINUX_FILENAME_PATH))
        else:
            filename = ConfigService.get_config_value(
                copy.deepcopy(PBA_WINDOWS_FILENAME_PATH))
        return send_from_directory(
            PostBreachFilesService.get_custom_pba_directory(), filename)
Example #29
0
    def get(self, guid=None, **kw):
        NodeService.update_dead_monkeys()  # refresh monkeys status
        if not guid:
            guid = request.args.get('guid')

        if guid:
            monkey_json = mongo.db.monkey.find_one_or_404({"guid": guid})
            monkey_json['config'] = ConfigService.decrypt_flat_config(monkey_json['config'])
            return monkey_json

        return {}
Example #30
0
    def get_cross_segment_issues():
        scans = mongo.db.telemetry.find({'telem_type': 'scan'},
                                        {'monkey_guid': 1, 'data.machine.ip_addr': 1, 'data.machine.services': 1})

        cross_segment_issues = []

        # For now the feature is limited to 1 group.
        subnet_groups = [ConfigService.get_config_value(['basic_network', 'network_analysis', 'inaccessible_subnets'])]

        for subnet_group in subnet_groups:
            cross_segment_issues += ReportService.get_cross_segment_issues_per_subnet_group(scans, subnet_group)

        return cross_segment_issues