forked from p15670423/monkey
Password setup: Backed environment changes and unit tests
This commit is contained in:
parent
d430b91eac
commit
18dec0c652
|
@ -0,0 +1,10 @@
|
|||
class ExploitingVulnerableMachineError(Exception):
|
||||
""" Raise when exploiter failed, but machine is vulnerable """
|
||||
|
||||
|
||||
class FailedExploitationError(Exception):
|
||||
""" Raise when exploiter fails instead of returning False """
|
||||
|
||||
|
||||
class ServerConfigFileChanged(Exception):
|
||||
""" Raise when server config file changed and island needs to restart """
|
|
@ -11,7 +11,7 @@ from infection_monkey.exploit.tools.http_tools import MonkeyHTTPServer
|
|||
from infection_monkey.exploit.tools.helpers import get_monkey_dest_path, build_monkey_commandline, get_monkey_depth
|
||||
from infection_monkey.model import DROPPER_ARG
|
||||
from infection_monkey.exploit.tools.payload_parsing import LimitedSizePayload
|
||||
from infection_monkey.exploit.tools.exceptions import ExploitingVulnerableMachineError, FailedExploitationError
|
||||
from common.utils.exceptions import ExploitingVulnerableMachineError, FailedExploitationError
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from infection_monkey.exploit.HostExploiter import HostExploiter
|
|||
from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline
|
||||
from infection_monkey.model import MONKEY_ARG
|
||||
from infection_monkey.network.tools import check_tcp_port, get_interface_to_target
|
||||
from infection_monkey.exploit.tools.exceptions import FailedExploitationError
|
||||
from common.utils.exceptions import FailedExploitationError
|
||||
from common.utils.exploit_enum import ExploitType
|
||||
from common.utils.attack_utils import ScanStatus
|
||||
from infection_monkey.telemetry.attack.t1105_telem import T1105Telem
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
class ExploitingVulnerableMachineError(Exception):
|
||||
""" Raise when exploiter failed, but machine is vulnerable"""
|
||||
|
||||
|
||||
class FailedExploitationError(Exception):
|
||||
""" Raise when exploiter fails instead of returning False"""
|
|
@ -28,7 +28,7 @@ from infection_monkey.telemetry.tunnel_telem import TunnelTelem
|
|||
from infection_monkey.windows_upgrader import WindowsUpgrader
|
||||
from infection_monkey.post_breach.post_breach_handler import PostBreach
|
||||
from infection_monkey.network.tools import get_interface_to_target, is_running_on_server
|
||||
from infection_monkey.exploit.tools.exceptions import ExploitingVulnerableMachineError, FailedExploitationError
|
||||
from common.utils.exceptions import ExploitingVulnerableMachineError, FailedExploitationError
|
||||
from infection_monkey.telemetry.attack.t1106_telem import T1106Telem
|
||||
from common.utils.attack_utils import ScanStatus, UsageEnum
|
||||
from common.version import get_version
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
import json
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from datetime import timedelta
|
||||
import os
|
||||
import hashlib
|
||||
|
||||
from typing import Dict
|
||||
|
||||
from common.utils.exceptions import ServerConfigFileChanged
|
||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||
|
||||
__author__ = 'itay.mizeretz'
|
||||
|
||||
|
||||
|
@ -18,6 +24,45 @@ class Environment(object, metaclass=ABCMeta):
|
|||
|
||||
_testing = False
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def _credentials_required(self) -> bool:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_auth_users(self):
|
||||
return
|
||||
|
||||
@staticmethod
|
||||
def set_server_config(config: Dict):
|
||||
Environment.upload_server_configuration_to_file(config)
|
||||
raise ServerConfigFileChanged
|
||||
|
||||
@staticmethod
|
||||
def upload_server_configuration_to_file(config: Dict):
|
||||
file_path = Environment.get_server_config_file_path()
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(json.dumps(config, indent=2))
|
||||
|
||||
@staticmethod
|
||||
def get_server_config_file_path():
|
||||
return os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc/server_config.json')
|
||||
|
||||
def needs_registration(self) -> bool:
|
||||
if not self._credentials_required:
|
||||
return False
|
||||
else:
|
||||
return not self._is_registered()
|
||||
|
||||
def _is_registered(self) -> bool:
|
||||
return self._credentials_required and self._is_credentials_set_up()
|
||||
|
||||
def _is_credentials_set_up(self) -> bool:
|
||||
if 'user' in self.config and 'hash' in self.config:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@property
|
||||
def testing(self):
|
||||
return self._testing
|
||||
|
@ -63,10 +108,6 @@ class Environment(object, metaclass=ABCMeta):
|
|||
val = self.config.get(key, val)
|
||||
return val
|
||||
|
||||
@abstractmethod
|
||||
def get_auth_users(self):
|
||||
return
|
||||
|
||||
@property
|
||||
def mongo_db_name(self):
|
||||
return self._MONGO_DB_NAME
|
||||
|
|
|
@ -6,6 +6,9 @@ __author__ = 'itay.mizeretz'
|
|||
|
||||
|
||||
class AwsEnvironment(Environment):
|
||||
|
||||
_credentials_required = True
|
||||
|
||||
def __init__(self):
|
||||
super(AwsEnvironment, self).__init__()
|
||||
# Not suppressing error here on purpose. This is critical if we're on AWS env.
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
env = None
|
||||
|
||||
from monkey_island.cc.environment import standard
|
||||
from monkey_island.cc.environment import standard, Environment
|
||||
from monkey_island.cc.environment import testing
|
||||
from monkey_island.cc.environment import aws
|
||||
from monkey_island.cc.environment import password
|
||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||
|
||||
__author__ = 'itay.mizeretz'
|
||||
|
||||
|
@ -27,17 +25,18 @@ ENV_DICT = {
|
|||
}
|
||||
|
||||
|
||||
def load_server_configuration_from_file():
|
||||
with open(os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc/server_config.json'), 'r') as f:
|
||||
config_content = f.read()
|
||||
return json.loads(config_content)
|
||||
|
||||
|
||||
def load_env_from_file():
|
||||
loaded_config_json = load_server_configuration_from_file()
|
||||
return loaded_config_json['server_config']
|
||||
|
||||
|
||||
def load_server_configuration_from_file():
|
||||
file_path = Environment.get_server_config_file_path()
|
||||
with open(file_path, 'r') as f:
|
||||
config_content = f.read()
|
||||
return json.loads(config_content)
|
||||
|
||||
|
||||
try:
|
||||
config_json = load_server_configuration_from_file()
|
||||
__env_type = config_json['server_config']
|
|
@ -6,7 +6,10 @@ __author__ = 'itay.mizeretz'
|
|||
|
||||
class PasswordEnvironment(Environment):
|
||||
|
||||
_credentials_required = True
|
||||
|
||||
def get_auth_users(self):
|
||||
return [
|
||||
monkey_island.cc.auth.User(1, self.config['user'], self.config['hash'])
|
||||
]
|
||||
if 'user' in self.config and 'hash' in self.config:
|
||||
return [monkey_island.cc.auth.User(1, self.config['user'], self.config['hash'])]
|
||||
else:
|
||||
return []
|
||||
|
|
|
@ -5,6 +5,9 @@ __author__ = 'itay.mizeretz'
|
|||
|
||||
|
||||
class StandardEnvironment(Environment):
|
||||
|
||||
_credentials_required = False
|
||||
|
||||
# SHA3-512 of '1234567890!@#$%^&*()_nothing_up_my_sleeve_1234567890!@#$%^&*()'
|
||||
NO_AUTH_CREDS = '55e97c9dcfd22b8079189ddaeea9bce8125887e3237b800c6176c9afa80d2062' \
|
||||
'8d2c8d0b1538d2208c1444ac66535b764a3d902b35e751df3faec1e477ed3557'
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
import json
|
||||
import os
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||
from common.utils.exceptions import ServerConfigFileChanged
|
||||
from monkey_island.cc.environment import Environment
|
||||
|
||||
|
||||
def get_server_config_file_path_test_version():
|
||||
return os.path.join(os.getcwd(), 'test_config.json')
|
||||
|
||||
|
||||
class TestEnvironment(TestCase):
|
||||
|
||||
class EnvironmentNoCredentials(Environment):
|
||||
_credentials_required = False
|
||||
|
||||
def get_auth_users(self):
|
||||
return []
|
||||
|
||||
class EnvironmentWithCredentials(Environment):
|
||||
_credentials_required = True
|
||||
|
||||
def get_auth_users(self):
|
||||
return []
|
||||
|
||||
# Username:test Password:test
|
||||
CONFIG_JSON_WITH_CREDENTIALS = {
|
||||
"server_config": "password",
|
||||
"deployment": "develop",
|
||||
"user": "test",
|
||||
"hash": "9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a"
|
||||
"4f2e9b3ca9f484f521d0ce464345cc1aec96779149c14"
|
||||
}
|
||||
|
||||
CONFIG_JSON_NO_CREDENTIALS = {
|
||||
"server_config": "password",
|
||||
"deployment": "develop"
|
||||
}
|
||||
|
||||
CONFIG_JSON_PARTIAL_CREDENTIALS = {
|
||||
"server_config": "password",
|
||||
"deployment": "develop",
|
||||
"user": "test"
|
||||
}
|
||||
|
||||
CONFIG_JSON_STANDARD_ENV = {
|
||||
"server_config": "standard",
|
||||
"deployment": "develop"
|
||||
}
|
||||
|
||||
CONFIG_JSON_STANDARD_WITH_CREDENTIALS = {
|
||||
"server_config": "standard",
|
||||
"deployment": "develop",
|
||||
"user": "test",
|
||||
"hash": "9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a"
|
||||
"4f2e9b3ca9f484f521d0ce464345cc1aec96779149c14"
|
||||
}
|
||||
|
||||
@patch.object(target=Environment, attribute="get_server_config_file_path",
|
||||
new=MagicMock(return_value=get_server_config_file_path_test_version()))
|
||||
def test_upload_server_configuration_to_file(self):
|
||||
Environment.upload_server_configuration_to_file(TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS)
|
||||
file_path = get_server_config_file_path_test_version()
|
||||
with open(file_path, 'r') as f:
|
||||
content_from_file = f.read()
|
||||
os.remove(file_path)
|
||||
|
||||
self.assertDictEqual(TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS, json.loads(content_from_file))
|
||||
|
||||
def test_get_server_config_file_path(self):
|
||||
server_file_path = MONKEY_ISLAND_ABS_PATH + "\cc/server_config.json"
|
||||
self.assertEqual(Environment.get_server_config_file_path(), server_file_path)
|
||||
|
||||
@patch.object(Environment, "upload_server_configuration_to_file", MagicMock())
|
||||
def test_set_server_config(self):
|
||||
with self.assertRaises(ServerConfigFileChanged):
|
||||
Environment.set_server_config(TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS)
|
||||
|
||||
def test_needs_registration(self):
|
||||
env = TestEnvironment.EnvironmentWithCredentials()
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS
|
||||
self.assertFalse(env.needs_registration())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_NO_CREDENTIALS
|
||||
self.assertTrue(env.needs_registration())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_PARTIAL_CREDENTIALS
|
||||
self.assertTrue(env.needs_registration())
|
||||
|
||||
env = TestEnvironment.EnvironmentNoCredentials()
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_STANDARD_ENV
|
||||
self.assertFalse(env.needs_registration())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_STANDARD_WITH_CREDENTIALS
|
||||
self.assertFalse(env.needs_registration())
|
||||
|
||||
def test_is_registered(self):
|
||||
env = TestEnvironment.EnvironmentWithCredentials()
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS
|
||||
self.assertTrue(env._is_registered())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_NO_CREDENTIALS
|
||||
self.assertFalse(env._is_registered())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_PARTIAL_CREDENTIALS
|
||||
self.assertFalse(env._is_registered())
|
||||
|
||||
env = TestEnvironment.EnvironmentNoCredentials()
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_STANDARD_ENV
|
||||
self.assertFalse(env._is_registered())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_STANDARD_WITH_CREDENTIALS
|
||||
self.assertFalse(env._is_registered())
|
||||
|
||||
def test_is_credentials_set_up(self):
|
||||
env = TestEnvironment.EnvironmentWithCredentials()
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_NO_CREDENTIALS
|
||||
self.assertFalse(env._is_credentials_set_up())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS
|
||||
self.assertTrue(env._is_credentials_set_up())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_PARTIAL_CREDENTIALS
|
||||
self.assertFalse(env._is_credentials_set_up())
|
||||
|
||||
env = TestEnvironment.EnvironmentNoCredentials()
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_STANDARD_ENV
|
||||
self.assertFalse(env._is_credentials_set_up())
|
|
@ -7,6 +7,8 @@ class TestingEnvironment(Environment):
|
|||
This will cause all mongo connections to happen via `mongomock` instead of using an actual mongodb instance.
|
||||
"""
|
||||
|
||||
_credentials_required = True
|
||||
|
||||
def __init__(self):
|
||||
super(TestingEnvironment, self).__init__()
|
||||
self.testing = True
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from mongoengine import connect
|
||||
|
||||
from monkey_island.cc.environment.environment import env
|
||||
from monkey_island.cc.environment.environment_singleton import env
|
||||
|
||||
# This section sets up the DB connection according to the environment.
|
||||
# If testing, use mongomock which only emulates mongo. for more information, see
|
||||
|
|
|
@ -6,7 +6,7 @@ import sys
|
|||
from flask import request, jsonify, make_response
|
||||
import flask_restful
|
||||
|
||||
from monkey_island.cc.environment.environment import env
|
||||
from monkey_island.cc.environment.environment_singleton import env
|
||||
from monkey_island.cc.models import Monkey
|
||||
from monkey_island.cc.resources.monkey_download import get_monkey_executable
|
||||
from monkey_island.cc.services.node import NodeService
|
||||
|
|
|
@ -6,7 +6,7 @@ from jsonschema import Draft4Validator, validators
|
|||
import monkey_island.cc.services.post_breach_files
|
||||
|
||||
from monkey_island.cc.database import mongo
|
||||
from monkey_island.cc.environment.environment import env
|
||||
from monkey_island.cc.environment.environment_singleton import env
|
||||
from monkey_island.cc.network_utils import local_ip_addresses
|
||||
from .config_schema import SCHEMA
|
||||
from monkey_island.cc.encryptor import encryptor
|
||||
|
|
|
@ -6,7 +6,7 @@ import boto3
|
|||
from botocore.exceptions import UnknownServiceError
|
||||
|
||||
from common.cloud.aws.aws_instance import AwsInstance
|
||||
from monkey_island.cc.environment.environment import load_server_configuration_from_file
|
||||
from monkey_island.cc.environment.environment_singleton import load_server_configuration_from_file
|
||||
from monkey_island.cc.services.reporting.exporter import Exporter
|
||||
|
||||
__authors__ = ['maor.rayzin', 'shay.nehmad']
|
||||
|
|
|
@ -3,7 +3,7 @@ import logging
|
|||
from monkey_island.cc.services.reporting.report_exporter_manager import ReportExporterManager
|
||||
from monkey_island.cc.services.reporting.aws_exporter import AWSExporter
|
||||
from monkey_island.cc.services.remote_run_aws import RemoteRunAwsService
|
||||
from monkey_island.cc.environment.environment import env
|
||||
from monkey_island.cc.environment.environment_singleton import env
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import logging
|
|||
import requests
|
||||
|
||||
from common.version import get_version
|
||||
from monkey_island.cc.environment.environment import env
|
||||
from monkey_island.cc.environment.environment_singleton import env
|
||||
|
||||
__author__ = "itay.mizeretz"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import unittest
|
||||
from monkey_island.cc.environment.environment import env
|
||||
from monkey_island.cc.environment.environment_singleton import env
|
||||
from monkey_island.cc.models import Monkey
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
|
||||
|
|
Loading…
Reference in New Issue