Merge remote-tracking branch 'upstream/develop' into 393/python-3
# Conflicts: # monkey/common/cloud/aws_instance.py
This commit is contained in:
commit
341d905f1e
|
@ -30,14 +30,14 @@ class AwsInstance(object):
|
||||||
AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/instance-id', timeout=2).read()
|
AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/instance-id', timeout=2).read()
|
||||||
self.region = self._parse_region(
|
self.region = self._parse_region(
|
||||||
urllib.request.urlopen(AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/placement/availability-zone').read())
|
urllib.request.urlopen(AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/placement/availability-zone').read())
|
||||||
except urllib.error.URLError as e:
|
except (urllib.error.URLError, IOError) as e:
|
||||||
logger.debug("Failed init of AwsInstance while getting metadata: {}".format(e))
|
logger.debug("Failed init of AwsInstance while getting metadata: {}".format(e), exc_info=True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.account_id = self._extract_account_id(
|
self.account_id = self._extract_account_id(
|
||||||
urllib.request.urlopen(
|
urllib.request.urlopen(
|
||||||
AWS_LATEST_METADATA_URI_PREFIX + 'dynamic/instance-identity/document', timeout=2).read())
|
AWS_LATEST_METADATA_URI_PREFIX + 'dynamic/instance-identity/document', timeout=2).read())
|
||||||
except urllib.error.URLError as e:
|
except (urllib.error.URLError, IOError) as e:
|
||||||
logger.debug("Failed init of AwsInstance while getting dynamic instance data: {}".format(e))
|
logger.debug("Failed init of AwsInstance while getting dynamic instance data: {}".format(e))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -122,9 +122,11 @@ class InfoCollector(object):
|
||||||
def get_azure_info(self):
|
def get_azure_info(self):
|
||||||
"""
|
"""
|
||||||
Adds credentials possibly stolen from an Azure VM instance (if we're on one)
|
Adds credentials possibly stolen from an Azure VM instance (if we're on one)
|
||||||
Updates the credentials structure, creating it if neccesary (compat with mimikatz)
|
Updates the credentials structure, creating it if necessary (compat with mimikatz)
|
||||||
:return: None. Updates class information
|
:return: None. Updates class information
|
||||||
"""
|
"""
|
||||||
|
# noinspection PyBroadException
|
||||||
|
try:
|
||||||
from infection_monkey.config import WormConfiguration
|
from infection_monkey.config import WormConfiguration
|
||||||
if not WormConfiguration.extract_azure_creds:
|
if not WormConfiguration.extract_azure_creds:
|
||||||
return
|
return
|
||||||
|
@ -144,6 +146,14 @@ class InfoCollector(object):
|
||||||
if len(azure_creds) != 0:
|
if len(azure_creds) != 0:
|
||||||
self.info["Azure"] = {}
|
self.info["Azure"] = {}
|
||||||
self.info["Azure"]['usernames'] = [cred[0] for cred in azure_creds]
|
self.info["Azure"]['usernames'] = [cred[0] for cred in azure_creds]
|
||||||
|
except Exception:
|
||||||
|
# If we failed to collect azure info, no reason to fail all the collection. Log and continue.
|
||||||
|
LOG.error("Failed collecting Azure info.", exc_info=True)
|
||||||
|
|
||||||
def get_aws_info(self):
|
def get_aws_info(self):
|
||||||
|
# noinspection PyBroadException
|
||||||
|
try:
|
||||||
self.info['aws'] = AwsCollector().get_aws_info()
|
self.info['aws'] = AwsCollector().get_aws_info()
|
||||||
|
except Exception:
|
||||||
|
# If we failed to collect aws info, no reason to fail all the collection. Log and continue.
|
||||||
|
LOG.error("Failed collecting AWS info.", exc_info=True)
|
||||||
|
|
|
@ -9,6 +9,7 @@ __author__ = 'itay.mizeretz'
|
||||||
class AwsEnvironment(Environment):
|
class AwsEnvironment(Environment):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(AwsEnvironment, self).__init__()
|
super(AwsEnvironment, self).__init__()
|
||||||
|
# Not suppressing error here on purpose. This is critical if we're on AWS env.
|
||||||
self.aws_info = AwsInstance()
|
self.aws_info = AwsInstance()
|
||||||
self._instance_id = self._get_instance_id()
|
self._instance_id = self._get_instance_id()
|
||||||
self.region = self._get_region()
|
self.region = self._get_region()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
from monkey_island.cc.services.config import ConfigService
|
from monkey_island.cc.services.config import ConfigService
|
||||||
from common.cloud.aws_instance import AwsInstance
|
from common.cloud.aws_instance import AwsInstance
|
||||||
from common.cloud.aws_service import AwsService
|
from common.cloud.aws_service import AwsService
|
||||||
|
@ -7,6 +9,8 @@ from common.cmd.cmd_runner import CmdRunner
|
||||||
|
|
||||||
__author__ = "itay.mizeretz"
|
__author__ = "itay.mizeretz"
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class RemoteRunAwsService:
|
class RemoteRunAwsService:
|
||||||
aws_instance = None
|
aws_instance = None
|
||||||
|
@ -23,7 +27,15 @@ class RemoteRunAwsService:
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if RemoteRunAwsService.aws_instance is None:
|
if RemoteRunAwsService.aws_instance is None:
|
||||||
|
RemoteRunAwsService.try_init_aws_instance()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def try_init_aws_instance():
|
||||||
|
# noinspection PyBroadException
|
||||||
|
try:
|
||||||
RemoteRunAwsService.aws_instance = AwsInstance()
|
RemoteRunAwsService.aws_instance = AwsInstance()
|
||||||
|
except Exception:
|
||||||
|
logger.error("Failed init aws instance. Exception info: ", exc_info=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def run_aws_monkeys(instances, island_ip):
|
def run_aws_monkeys(instances, island_ip):
|
||||||
|
|
|
@ -24,6 +24,7 @@ class AWSExporter(Exporter):
|
||||||
logger.info('No issues were found by the monkey, no need to send anything')
|
logger.info('No issues were found by the monkey, no need to send anything')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# Not suppressing error here on purpose.
|
||||||
current_aws_region = AwsInstance().get_region()
|
current_aws_region = AwsInstance().get_region()
|
||||||
|
|
||||||
for machine in issues_list:
|
for machine in issues_list:
|
||||||
|
@ -70,6 +71,7 @@ class AWSExporter(Exporter):
|
||||||
configured_product_arn = load_server_configuration_from_file()['aws'].get('sec_hub_product_arn', '')
|
configured_product_arn = load_server_configuration_from_file()['aws'].get('sec_hub_product_arn', '')
|
||||||
product_arn = 'arn:aws:securityhub:{region}:{arn}'.format(region=region, arn=configured_product_arn)
|
product_arn = 'arn:aws:securityhub:{region}:{arn}'.format(region=region, arn=configured_product_arn)
|
||||||
instance_arn = 'arn:aws:ec2:' + str(region) + ':instance:{instance_id}'
|
instance_arn = 'arn:aws:ec2:' + str(region) + ':instance:{instance_id}'
|
||||||
|
# Not suppressing error here on purpose.
|
||||||
account_id = AwsInstance().get_account_id()
|
account_id = AwsInstance().get_account_id()
|
||||||
logger.debug("aws account id acquired: {}".format(account_id))
|
logger.debug("aws account id acquired: {}".format(account_id))
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,18 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def populate_exporter_list():
|
def populate_exporter_list():
|
||||||
manager = ReportExporterManager()
|
manager = ReportExporterManager()
|
||||||
RemoteRunAwsService.init()
|
try_add_aws_exporter_to_manager(manager)
|
||||||
if RemoteRunAwsService.is_running_on_aws() and ('aws' == env.get_deployment()):
|
|
||||||
manager.add_exporter_to_list(AWSExporter)
|
|
||||||
|
|
||||||
if len(manager.get_exporters_list()) != 0:
|
if len(manager.get_exporters_list()) != 0:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Populated exporters list with the following exporters: {0}".format(str(manager.get_exporters_list())))
|
"Populated exporters list with the following exporters: {0}".format(str(manager.get_exporters_list())))
|
||||||
|
|
||||||
|
|
||||||
|
def try_add_aws_exporter_to_manager(manager):
|
||||||
|
# noinspection PyBroadException
|
||||||
|
try:
|
||||||
|
RemoteRunAwsService.init()
|
||||||
|
if RemoteRunAwsService.is_running_on_aws() and ('aws' == env.get_deployment()):
|
||||||
|
manager.add_exporter_to_list(AWSExporter)
|
||||||
|
except Exception:
|
||||||
|
logger.error("Failed adding aws exporter to manager. Exception info:", exc_info=True)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
from monkey_island.cc.database import mongo
|
from monkey_island.cc.database import mongo
|
||||||
from monkey_island.cc.models import Monkey
|
from monkey_island.cc.models import Monkey
|
||||||
from monkey_island.cc.services import mimikatz_utils
|
from monkey_island.cc.services import mimikatz_utils
|
||||||
|
@ -7,14 +9,32 @@ from monkey_island.cc.services.telemetry.zero_trust_tests.antivirus_existence im
|
||||||
from monkey_island.cc.services.wmi_handler import WMIHandler
|
from monkey_island.cc.services.wmi_handler import WMIHandler
|
||||||
from monkey_island.cc.encryptor import encryptor
|
from monkey_island.cc.encryptor import encryptor
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def process_system_info_telemetry(telemetry_json):
|
def process_system_info_telemetry(telemetry_json):
|
||||||
process_ssh_info(telemetry_json)
|
telemetry_processing_stages = [
|
||||||
process_credential_info(telemetry_json)
|
process_ssh_info,
|
||||||
process_mimikatz_and_wmi_info(telemetry_json)
|
process_credential_info,
|
||||||
process_aws_data(telemetry_json)
|
process_mimikatz_and_wmi_info,
|
||||||
update_db_with_new_hostname(telemetry_json)
|
process_aws_data,
|
||||||
test_antivirus_existence(telemetry_json)
|
update_db_with_new_hostname,
|
||||||
|
test_antivirus_existence,
|
||||||
|
]
|
||||||
|
|
||||||
|
# Calling safe_process_telemetry so if one of the stages fail, we log and move on instead of failing the rest of
|
||||||
|
# them, as they are independent.
|
||||||
|
for stage in telemetry_processing_stages:
|
||||||
|
safe_process_telemetry(stage, telemetry_json)
|
||||||
|
|
||||||
|
|
||||||
|
def safe_process_telemetry(processing_function, telemetry_json):
|
||||||
|
# noinspection PyBroadException
|
||||||
|
try:
|
||||||
|
processing_function(telemetry_json)
|
||||||
|
except Exception as err:
|
||||||
|
logger.error("Error while in {} stage of processing telemetry.".format(processing_function.func_name),
|
||||||
|
exc_info=True)
|
||||||
|
|
||||||
|
|
||||||
def process_ssh_info(telemetry_json):
|
def process_ssh_info(telemetry_json):
|
||||||
|
@ -102,4 +122,4 @@ def process_aws_data(telemetry_json):
|
||||||
|
|
||||||
|
|
||||||
def update_db_with_new_hostname(telemetry_json):
|
def update_db_with_new_hostname(telemetry_json):
|
||||||
Monkey.get_single_monkey_by_id(telemetry_json['_id']).set_hostname(telemetry_json['data']['hostname'])
|
Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid']).set_hostname(telemetry_json['data']['hostname'])
|
||||||
|
|
Loading…
Reference in New Issue