forked from p15670423/monkey
Added system info collectors as plugins and the first plugin - EnvironmentCollector
This commit is contained in:
parent
974e2205d1
commit
c0331f84ff
|
@ -1,3 +1,7 @@
|
|||
UNKNOWN = "Unknown"
|
||||
ON_PREMISE = "On Premise"
|
||||
AZURE = "Azure"
|
||||
AWS = "AWS"
|
||||
GCP = "GCP"
|
||||
|
||||
ALL_ENV_NAMES = [UNKNOWN, ON_PREMISE, AZURE, AWS, GCP]
|
||||
|
|
|
@ -125,6 +125,7 @@ class Configuration(object):
|
|||
|
||||
finger_classes = []
|
||||
exploiter_classes = []
|
||||
system_info_collectors_classes = ["EnvironmentCollector"]
|
||||
|
||||
# how many victims to look for in a single scan iteration
|
||||
victims_max_find = 100
|
||||
|
|
|
@ -9,6 +9,7 @@ from infection_monkey.network.info import get_host_subnets
|
|||
from infection_monkey.system_info.aws_collector import AwsCollector
|
||||
from infection_monkey.system_info.azure_cred_collector import AzureCollector
|
||||
from infection_monkey.system_info.netstat_collector import NetstatCollector
|
||||
from system_info.system_info_collectors_handler import SystemInfoCollectorsHandler
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -61,12 +62,16 @@ class InfoCollector(object):
|
|||
self.info = {}
|
||||
|
||||
def get_info(self):
|
||||
# Collect all hardcoded
|
||||
self.get_hostname()
|
||||
self.get_process_list()
|
||||
self.get_network_info()
|
||||
self.get_azure_info()
|
||||
self.get_aws_info()
|
||||
|
||||
# Collect all plugins
|
||||
SystemInfoCollectorsHandler().execute_all_configured()
|
||||
|
||||
def get_hostname(self):
|
||||
"""
|
||||
Adds the fully qualified computer hostname to the system information.
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
"""
|
||||
This package holds all the dynamic (plugin) collectors
|
||||
"""
|
|
@ -11,7 +11,7 @@ class SystemInfoCollector(Plugin):
|
|||
|
||||
@staticmethod
|
||||
def should_run(class_name) -> bool:
|
||||
return class_name in WormConfiguration.system_info_collectors
|
||||
return class_name in WormConfiguration.system_info_collectors_classes
|
||||
|
||||
@staticmethod
|
||||
def base_package_file():
|
||||
|
|
|
@ -10,7 +10,7 @@ PATH_TO_COLLECTORS = "infection_monkey.system_info.collectors."
|
|||
|
||||
|
||||
# TODO Add new collectors to config and config schema
|
||||
class SystemInfo(object):
|
||||
class SystemInfoCollectorsHandler(object):
|
||||
def __init__(self):
|
||||
self.collectors_list = self.config_to_collectors_list()
|
||||
|
||||
|
@ -27,7 +27,8 @@ class SystemInfo(object):
|
|||
LOG.error("Collector {} failed. Error info: {}".format(collector.name, e))
|
||||
LOG.info("All system info collectors executed. Total {} executed, out of which {} collected successfully.".
|
||||
format(len(self.collectors_list), successful_collections))
|
||||
# TODO Send SystemInfoTelem()
|
||||
|
||||
SystemInfoTelem({"collectors": system_info_telemetry}).send()
|
||||
|
||||
@staticmethod
|
||||
def config_to_collectors_list() -> Sequence[SystemInfoCollector]:
|
|
@ -9,6 +9,7 @@ from monkey_island.cc.models.monkey_ttl import MonkeyTtl, create_monkey_ttl_docu
|
|||
from monkey_island.cc.consts import DEFAULT_MONKEY_TTL_EXPIRY_DURATION_IN_SECONDS
|
||||
from monkey_island.cc.models.command_control_channel import CommandControlChannel
|
||||
from monkey_island.cc.utils import local_ip_addresses
|
||||
from common.cloud import environment_names
|
||||
|
||||
MAX_MONKEYS_AMOUNT_TO_CACHE = 100
|
||||
|
||||
|
@ -42,6 +43,9 @@ class Monkey(Document):
|
|||
ttl_ref = ReferenceField(MonkeyTtl)
|
||||
tunnel = ReferenceField("self")
|
||||
command_control_channel = EmbeddedDocumentField(CommandControlChannel)
|
||||
|
||||
# Environment related fields
|
||||
environment = StringField(default=environment_names.UNKNOWN, choices=environment_names.ALL_ENV_NAMES)
|
||||
aws_instance_id = StringField(required=False) # This field only exists when the monkey is running on an AWS
|
||||
|
||||
# instance. See https://github.com/guardicore/monkey/issues/426.
|
||||
|
@ -55,7 +59,8 @@ class Monkey(Document):
|
|||
raise MonkeyNotFoundError("info: {0} | id: {1}".format(ex, str(db_id)))
|
||||
|
||||
@staticmethod
|
||||
def get_single_monkey_by_guid(monkey_guid):
|
||||
# See https://www.python.org/dev/peps/pep-0484/#forward-references
|
||||
def get_single_monkey_by_guid(monkey_guid) -> 'Monkey':
|
||||
try:
|
||||
return Monkey.objects.get(guid=monkey_guid)
|
||||
except DoesNotExist as ex:
|
||||
|
|
|
@ -99,6 +99,20 @@ SCHEMA = {
|
|||
}
|
||||
]
|
||||
},
|
||||
"system_info_collectors_classes": {
|
||||
"title": "System Information Collectors",
|
||||
"type": "string",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"EnvironmentCollector"
|
||||
],
|
||||
"title": "Which Environment this machine is on (on prem/cloud)",
|
||||
"attack_techniques": []
|
||||
},
|
||||
],
|
||||
},
|
||||
"post_breach_acts": {
|
||||
"title": "Post breach actions",
|
||||
"type": "string",
|
||||
|
@ -433,6 +447,18 @@ SCHEMA = {
|
|||
"attack_techniques": ["T1003"],
|
||||
"description": "Determines whether to use Mimikatz"
|
||||
},
|
||||
"system_info_collectors_classes": {
|
||||
"title": "System info collectors",
|
||||
"type": "array",
|
||||
"uniqueItems": True,
|
||||
"items": {
|
||||
"$ref": "#/definitions/system_info_collectors_classes"
|
||||
},
|
||||
"default": [
|
||||
"EnvironmentCollector"
|
||||
],
|
||||
"description": "Determines which system information collectors will collect information."
|
||||
},
|
||||
}
|
||||
},
|
||||
"life_cycle": {
|
||||
|
|
|
@ -5,6 +5,7 @@ from monkey_island.cc.models import Monkey
|
|||
from monkey_island.cc.services import mimikatz_utils
|
||||
from monkey_island.cc.services.node import NodeService
|
||||
from monkey_island.cc.services.config import ConfigService
|
||||
from monkey_island.cc.services.telemetry.processing.system_info_collectors.environment import process_environment_telemetry
|
||||
from monkey_island.cc.services.telemetry.zero_trust_tests.antivirus_existence import test_antivirus_existence
|
||||
from monkey_island.cc.services.wmi_handler import WMIHandler
|
||||
from monkey_island.cc.encryptor import encryptor
|
||||
|
@ -20,6 +21,7 @@ def process_system_info_telemetry(telemetry_json):
|
|||
process_aws_data,
|
||||
update_db_with_new_hostname,
|
||||
test_antivirus_existence,
|
||||
process_environment_telemetry
|
||||
]
|
||||
|
||||
# Calling safe_process_telemetry so if one of the stages fail, we log and move on instead of failing the rest of
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import logging
|
||||
|
||||
from monkey_island.cc.models.monkey import Monkey
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def process_environment_telemetry(telemetry_json):
|
||||
if "EnvironmentCollector" in telemetry_json["data"]["collectors"]:
|
||||
env = telemetry_json["data"]["collectors"]["EnvironmentCollector"]["environment"]
|
||||
relevant_monkey = Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid'])
|
||||
relevant_monkey.environment = env
|
||||
relevant_monkey.save()
|
||||
logger.debug("Updated Monkey {} with env {}".format(str(relevant_monkey), env))
|
Loading…
Reference in New Issue