示例#1
0
文件: report.py 项目: vanyell/monkey
 def get_ssh_keys():
     """
     Return private ssh keys found as credentials
     :return: List of credentials
     """
     creds = []
     for telem in mongo.db.telemetry.find(
         {"telem_category": "system_info", "data.ssh_info": {"$exists": True}},
         {"data.ssh_info": 1, "monkey_guid": 1},
     ):
         origin = NodeService.get_monkey_by_guid(telem["monkey_guid"])["hostname"]
         if telem["data"]["ssh_info"]:
             # Pick out all ssh keys not yet included in creds
             ssh_keys = [
                 {
                     "username": key_pair["name"],
                     "type": "Clear SSH private key",
                     "origin": origin,
                 }
                 for key_pair in telem["data"]["ssh_info"]
                 if key_pair["private_key"]
                 and {
                     "username": key_pair["name"],
                     "type": "Clear SSH private key",
                     "origin": origin,
                 }
                 not in creds
             ]
             creds.extend(ssh_keys)
     return creds
示例#2
0
 def get_ssh_keys():
     """
     Return private ssh keys found as credentials
     :return: List of credentials
     """
     creds = []
     for telem in mongo.db.telemetry.find(
         {
             'telem_category': 'system_info',
             'data.ssh_info': {
                 '$exists': True
             }
         }, {
             'data.ssh_info': 1,
             'monkey_guid': 1
         }):
         origin = NodeService.get_monkey_by_guid(
             telem['monkey_guid'])['hostname']
         if telem['data']['ssh_info']:
             # Pick out all ssh keys not yet included in creds
             ssh_keys = [{
                 'username': key_pair['name'],
                 'type': 'Clear SSH private key',
                 'origin': origin
             } for key_pair in telem['data']['ssh_info']
                         if key_pair['private_key'] and {
                             'username': key_pair['name'],
                             'type': 'Clear SSH private key',
                             'origin': origin
                         } not in creds]
             creds.extend(ssh_keys)
     return creds
示例#3
0
    def get_azure_creds():
        """
        Recover all credentials marked as being from an Azure machine
        :return: List of credentials.
        """
        creds = []
        for telem in mongo.db.telemetry.find(
            {
                'telem_category': 'system_info',
                'data.Azure': {
                    '$exists': True
                }
            }, {
                'data.Azure': 1,
                'monkey_guid': 1
            }):
            azure_users = telem['data']['Azure']['usernames']
            if len(azure_users) == 0:
                continue
            origin = NodeService.get_monkey_by_guid(
                telem['monkey_guid'])['hostname']
            azure_leaked_users = [{
                'username': user.replace(',', '.'),
                'type': 'Clear Password',
                'origin': origin
            } for user in azure_users]
            creds.extend(azure_leaked_users)

        logger.info('Azure machines creds generated for reporting')
        return creds
示例#4
0
 def get_stolen_creds():
     PASS_TYPE_DICT = {
         'password': '******',
         'lm_hash': 'LM hash',
         'ntlm_hash': 'NTLM hash'
     }
     creds = []
     for telem in mongo.db.telemetry.find(
         {
             'telem_type': 'system_info_collection',
             'data.credentials': {
                 '$exists': True
             }
         }, {
             'data.credentials': 1,
             'monkey_guid': 1
         }):
         monkey_creds = telem['data']['credentials']
         if len(monkey_creds) == 0:
             continue
         origin = NodeService.get_monkey_by_guid(
             telem['monkey_guid'])['hostname']
         for user in monkey_creds:
             for pass_type in monkey_creds[user]:
                 cred_row = \
                     {
                         'username': user.replace(',', '.'),
                         'type': PASS_TYPE_DICT[pass_type],
                         'origin': origin
                     }
                 if cred_row not in creds:
                     creds.append(cred_row)
     logger.info('Stolen creds generated for reporting')
     return creds
示例#5
0
 def process_tunnel_telemetry(telemetry_json):
     monkey_id = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])["_id"]
     if telemetry_json['data']['proxy'] is not None:
         tunnel_host_ip = telemetry_json['data']['proxy'].split(":")[-2].replace("//", "")
         NodeService.set_monkey_tunnel(monkey_id, tunnel_host_ip)
     else:
         NodeService.unset_all_monkey_tunnels(monkey_id)
示例#6
0
def process_wmi_info(telemetry_json):
    users_secrets = {}

    if "wmi" in telemetry_json["data"]:
        monkey_id = NodeService.get_monkey_by_guid(telemetry_json["monkey_guid"]).get("_id")
        wmi_handler = WMIHandler(monkey_id, telemetry_json["data"]["wmi"], users_secrets)
        wmi_handler.process_and_handle_wmi_info()
示例#7
0
 def process_system_info_telemetry(telemetry_json):
     users_secrets = {}
     monkey_id = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid']).get('_id')
     if 'ssh_info' in telemetry_json['data']:
         ssh_info = telemetry_json['data']['ssh_info']
         Telemetry.encrypt_system_info_ssh_keys(ssh_info)
         if telemetry_json['data']['network_info']['networks']:
             # We use user_name@machine_ip as the name of the ssh key stolen, thats why we need ip from telemetry
             Telemetry.add_ip_to_ssh_keys(telemetry_json['data']['network_info']['networks'][0], ssh_info)
         Telemetry.add_system_info_ssh_keys_to_config(ssh_info)
     if 'credentials' in telemetry_json['data']:
         creds = telemetry_json['data']['credentials']
         Telemetry.encrypt_system_info_creds(creds)
         Telemetry.add_system_info_creds_to_config(creds)
         Telemetry.replace_user_dot_with_comma(creds)
     if 'mimikatz' in telemetry_json['data']:
         users_secrets = mimikatz_utils.MimikatzSecrets.\
             extract_secrets_from_mimikatz(telemetry_json['data'].get('mimikatz', ''))
     if 'wmi' in telemetry_json['data']:
         wmi_handler = WMIHandler(monkey_id, telemetry_json['data']['wmi'], users_secrets)
         wmi_handler.process_and_handle_wmi_info()
     if 'aws' in telemetry_json['data']:
         if 'instance_id' in telemetry_json['data']['aws']:
             mongo.db.monkey.update_one({'_id': monkey_id},
                                        {'$set': {'aws_instance_id': telemetry_json['data']['aws']['instance_id']}})
示例#8
0
    def get_azure_creds():
        """
        Recover all credentials marked as being from an Azure machine
        :return: List of credentials.
        """
        creds = []
        for telem in mongo.db.telemetry.find(
            {
                "telem_category": "system_info",
                "data.Azure": {
                    "$exists": True
                }
            },
            {
                "data.Azure": 1,
                "monkey_guid": 1
            },
        ):
            azure_users = telem["data"]["Azure"]["usernames"]
            if len(azure_users) == 0:
                continue
            origin = NodeService.get_monkey_by_guid(
                telem["monkey_guid"])["hostname"]
            azure_leaked_users = [{
                "username": user.replace(",", "."),
                "type": "Clear Password",
                "origin": origin
            } for user in azure_users]
            creds.extend(azure_leaked_users)

        logger.info("Azure machines creds generated for reporting")
        return creds
示例#9
0
    def patch(self, guid):
        monkey_json = json.loads(request.data)
        update = {"$set": {'modifytime': datetime.now()}}
        monkey = NodeService.get_monkey_by_guid(guid)
        if 'keepalive' in monkey_json:
            update['$set']['keepalive'] = dateutil.parser.parse(
                monkey_json['keepalive'])
        else:
            update['$set']['keepalive'] = datetime.now()
        if 'config' in monkey_json:
            update['$set']['config'] = monkey_json['config']
        if 'config_error' in monkey_json:
            update['$set']['config_error'] = monkey_json['config_error']

        if 'tunnel' in monkey_json:
            tunnel_host_ip = monkey_json['tunnel'].split(":")[-2].replace(
                "//", "")
            NodeService.set_monkey_tunnel(monkey["_id"], tunnel_host_ip)

        ttl = create_monkey_ttl_document(
            DEFAULT_MONKEY_TTL_EXPIRY_DURATION_IN_SECONDS)
        update['$set']['ttl_ref'] = ttl.id

        return mongo.db.monkey.update({"_id": monkey["_id"]},
                                      update,
                                      upsert=False)
示例#10
0
def process_tunnel_telemetry(telemetry_json):
    check_tunneling_violation(telemetry_json)
    monkey_id = NodeService.get_monkey_by_guid(telemetry_json["monkey_guid"])["_id"]
    if telemetry_json["data"]["proxy"] is not None:
        tunnel_host_ip = get_tunnel_host_ip_from_proxy_field(telemetry_json)
        NodeService.set_monkey_tunnel(monkey_id, tunnel_host_ip)
    else:
        NodeService.unset_all_monkey_tunnels(monkey_id)
示例#11
0
def process_mimikatz_and_wmi_info(telemetry_json):
    users_secrets = {}
    if 'mimikatz' in telemetry_json['data']:
        users_secrets = mimikatz_utils.MimikatzSecrets. \
            extract_secrets_from_mimikatz(telemetry_json['data'].get('mimikatz', ''))
    if 'wmi' in telemetry_json['data']:
        monkey_id = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid']).get('_id')
        wmi_handler = WMIHandler(monkey_id, telemetry_json['data']['wmi'], users_secrets)
        wmi_handler.process_and_handle_wmi_info()
示例#12
0
def process_wmi_info(telemetry_json):
    users_secrets = {}

    if 'wmi' in telemetry_json['data']:
        monkey_id = NodeService.get_monkey_by_guid(
            telemetry_json['monkey_guid']).get('_id')
        wmi_handler = WMIHandler(monkey_id, telemetry_json['data']['wmi'],
                                 users_secrets)
        wmi_handler.process_and_handle_wmi_info()
示例#13
0
    def get_edge_by_scan_or_exploit_telemetry(telemetry_json):
        dst_ip = telemetry_json['data']['machine']['ip_addr']
        dst_domain_name = telemetry_json['data']['machine']['domain_name']
        src_monkey = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])
        dst_node = NodeService.get_monkey_by_ip(dst_ip)
        if dst_node is None:
            dst_node = NodeService.get_or_create_node(dst_ip, dst_domain_name)

        return EdgeService.get_or_create_edge(src_monkey["_id"], dst_node["_id"])
示例#14
0
 def get_displayed_telemetry(telem):
     monkey = NodeService.get_monkey_by_guid(telem['monkey_guid'])
     default_hostname = "GUID-" + telem['monkey_guid']
     return \
         {
             'id': telem['_id'],
             'timestamp': telem['timestamp'].strftime('%d/%m/%Y %H:%M:%S'),
             'hostname': monkey.get('hostname', default_hostname) if monkey else default_hostname,
             'brief': TELEM_PROCESS_DICT[telem['telem_type']](telem)
         }
示例#15
0
    def post(self):
        telemetry_json = json.loads(request.data)

        monkey_id = NodeService.get_monkey_by_guid(
            telemetry_json['monkey_guid'])['_id']
        # This shouldn't contain any unicode characters. this'll take 2 time less space.
        log_data = str(telemetry_json['log'])
        log_id = LogService.add_log(monkey_id, log_data)

        return mongo.db.log.find_one_or_404({"_id": log_id})
示例#16
0
 def get_displayed_telemetry(telem):
     monkey = NodeService.get_monkey_by_guid(telem["monkey_guid"])
     default_hostname = "GUID-" + telem["monkey_guid"]
     return {
         "id": telem["_id"],
         "timestamp": telem["timestamp"].strftime("%d/%m/%Y %H:%M:%S"),
         "hostname": monkey.get("hostname", default_hostname)
         if monkey else default_hostname,
         "brief": TelemetryFeed.get_telem_brief(telem),
     }
示例#17
0
文件: report.py 项目: vanyell/monkey
 def _get_credentials_from_system_info_telems():
     formatted_creds = []
     for telem in mongo.db.telemetry.find(
         {"telem_category": "system_info", "data.credentials": {"$exists": True}},
         {"data.credentials": 1, "monkey_guid": 1},
     ):
         creds = telem["data"]["credentials"]
         origin = NodeService.get_monkey_by_guid(telem["monkey_guid"])["hostname"]
         formatted_creds.extend(ReportService._format_creds_for_reporting(telem, creds, origin))
     return formatted_creds
示例#18
0
def process_aws_data(telemetry_json):
    if 'aws' in telemetry_json['data']:
        if 'instance_id' in telemetry_json['data']['aws']:
            monkey_id = NodeService.get_monkey_by_guid(
                telemetry_json['monkey_guid']).get('_id')
            mongo.db.monkey.update_one({'_id': monkey_id}, {
                '$set': {
                    'aws_instance_id':
                    telemetry_json['data']['aws']['instance_id']
                }
            })
示例#19
0
def get_edge_by_scan_or_exploit_telemetry(telemetry_json):
    dst_ip = telemetry_json["data"]["machine"]["ip_addr"]
    dst_domain_name = telemetry_json["data"]["machine"]["domain_name"]
    src_monkey = NodeService.get_monkey_by_guid(telemetry_json["monkey_guid"])
    dst_node = NodeService.get_monkey_by_ip(dst_ip)
    if dst_node is None:
        dst_node = NodeService.get_or_create_node(dst_ip, dst_domain_name)

    src_label = NodeService.get_label_for_endpoint(src_monkey["_id"])
    dst_label = NodeService.get_label_for_endpoint(dst_node["_id"])

    return EdgeService.get_or_create_edge(src_monkey["_id"], dst_node["_id"],
                                          src_label, dst_label)
示例#20
0
def process_state_telemetry(telemetry_json):
    monkey = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])
    NodeService.add_communication_info(
        monkey, telemetry_json['command_control_channel'])
    if telemetry_json['data']['done']:
        NodeService.set_monkey_dead(monkey, True)
    else:
        NodeService.set_monkey_dead(monkey, False)

    if telemetry_json['data']['done']:
        current_monkey = Monkey.get_single_monkey_by_guid(
            telemetry_json['monkey_guid'])
        test_passed_findings_for_unreached_segments(current_monkey)
示例#21
0
    def post(self):
        telemetry_json = json.loads(request.data)
        telemetry_json['data'] = json.loads(telemetry_json['data'])
        telemetry_json['timestamp'] = datetime.now()
        telemetry_json['command_control_channel'] = {'src': request.remote_addr, 'dst': request.host}

        # Monkey communicated, so it's alive. Update the TTL.
        Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid']).renew_ttl()

        monkey = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])
        NodeService.update_monkey_modify_time(monkey["_id"])

        process_telemetry(telemetry_json)

        telem_id = mongo.db.telemetry.insert(telemetry_json)
        return mongo.db.telemetry.find_one_or_404({"_id": telem_id})
示例#22
0
文件: state.py 项目: vanyell/monkey
def process_state_telemetry(telemetry_json):
    monkey = NodeService.get_monkey_by_guid(telemetry_json["monkey_guid"])
    NodeService.add_communication_info(
        monkey, telemetry_json["command_control_channel"])
    if telemetry_json["data"]["done"]:
        NodeService.set_monkey_dead(monkey, True)
    else:
        NodeService.set_monkey_dead(monkey, False)

    if telemetry_json["data"]["done"]:
        current_monkey = Monkey.get_single_monkey_by_guid(
            telemetry_json["monkey_guid"])
        check_passed_findings_for_unreached_segments(current_monkey)

    if telemetry_json["data"]["version"]:
        logger.info(f"monkey {telemetry_json['monkey_guid']} has version "
                    f"{telemetry_json['data']['version']}")
示例#23
0
    def get_cross_segment_issues_per_subnet_pair(scans, source_subnet,
                                                 target_subnet):
        """
        Gets list of cross segment issues from source_subnet to target_subnet.
        :param scans:           List of all scan telemetry entries. Must have monkey_guid,
        ip_addr and services.
                                This should be a PyMongo cursor object.
        :param source_subnet:   The subnet which shouldn't be able to access target_subnet.
        :param target_subnet:   The subnet which shouldn't be accessible from source_subnet.
        :return:
        """
        if source_subnet == target_subnet:
            return []
        source_subnet_range = NetworkRange.get_range_obj(source_subnet)
        target_subnet_range = NetworkRange.get_range_obj(target_subnet)

        cross_segment_issues = []

        scans.rewind()  # If we iterated over scans already we need to rewind.
        for scan in scans:
            target_ip = scan["data"]["machine"]["ip_addr"]
            if target_subnet_range.is_in_range(str(target_ip)):
                monkey = NodeService.get_monkey_by_guid(scan["monkey_guid"])
                cross_segment_ip = get_ip_in_src_and_not_in_dst(
                    monkey["ip_addresses"], source_subnet_range,
                    target_subnet_range)

                if cross_segment_ip is not None:
                    cross_segment_issues.append({
                        "source":
                        cross_segment_ip,
                        "hostname":
                        monkey["hostname"],
                        "target":
                        target_ip,
                        "services":
                        scan["data"]["machine"]["services"],
                        "icmp":
                        scan["data"]["machine"]["icmp"],
                        "is_self":
                        False,
                    })

        return cross_segment_issues + ReportService.get_cross_segment_issues_of_single_machine(
            source_subnet_range, target_subnet_range)
示例#24
0
    def post(self):
        telemetry_json = json.loads(request.data)
        telemetry_json['timestamp'] = datetime.now()

        monkey = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])

        try:
            NodeService.update_monkey_modify_time(monkey["_id"])
            telem_type = telemetry_json.get('telem_type')
            if telem_type in TELEM_PROCESS_DICT:
                TELEM_PROCESS_DICT[telem_type](telemetry_json)
            else:
                logger.info('Got unknown type of telemetry: %s' % telem_type)
        except Exception as ex:
            logger.error("Exception caught while processing telemetry", exc_info=True)

        telem_id = mongo.db.telemetry.insert(telemetry_json)
        return mongo.db.telemetry.find_one_or_404({"_id": telem_id})
示例#25
0
 def _get_credentials_from_system_info_telems():
     formatted_creds = []
     for telem in mongo.db.telemetry.find(
         {
             'telem_category': 'system_info',
             'data.credentials': {
                 '$exists': True
             }
         }, {
             'data.credentials': 1,
             'monkey_guid': 1
         }):
         creds = telem['data']['credentials']
         origin = NodeService.get_monkey_by_guid(
             telem['monkey_guid'])['hostname']
         formatted_creds.extend(
             ReportService._format_creds_for_reporting(
                 telem, creds, origin))
     return formatted_creds
示例#26
0
    def get_cross_segment_issues_per_subnet_pair(scans, source_subnet,
                                                 target_subnet):
        """
        Gets list of cross segment issues from source_subnet to target_subnet.
        :param scans:           List of all scan telemetry entries. Must have monkey_guid, ip_addr and services.
                                This should be a PyMongo cursor object.
        :param source_subnet:   The subnet which shouldn't be able to access target_subnet.
        :param target_subnet:   The subnet which shouldn't be accessible from source_subnet.
        :return:
        """
        if source_subnet == target_subnet:
            return []
        source_subnet_range = NetworkRange.get_range_obj(source_subnet)
        target_subnet_range = NetworkRange.get_range_obj(target_subnet)

        cross_segment_issues = []

        scans.rewind()  # If we iterated over scans already we need to rewind.
        for scan in scans:
            target_ip = scan['data']['machine']['ip_addr']
            if target_subnet_range.is_in_range(text_type(target_ip)):
                monkey = NodeService.get_monkey_by_guid(scan['monkey_guid'])
                cross_segment_ip = ReportService.get_ip_in_src_and_not_in_dst(
                    monkey['ip_addresses'], source_subnet_range,
                    target_subnet_range)

                if cross_segment_ip is not None:
                    cross_segment_issues.append({
                        'source':
                        cross_segment_ip,
                        'hostname':
                        monkey['hostname'],
                        'target':
                        target_ip,
                        'services':
                        scan['data']['machine']['services'],
                        'is_self':
                        False
                    })

        return cross_segment_issues + ReportService.get_cross_segment_issues_of_single_machine(
            source_subnet_range, target_subnet_range)
示例#27
0
    def post(self):
        telemetry_json = json.loads(request.data)
        telemetry_json["data"] = json.loads(telemetry_json["data"])
        telemetry_json["timestamp"] = datetime.now()
        telemetry_json["command_control_channel"] = {
            "src": request.remote_addr,
            "dst": request.host,
        }

        # Monkey communicated, so it's alive. Update the TTL.
        Monkey.get_single_monkey_by_guid(
            telemetry_json["monkey_guid"]).renew_ttl()

        monkey = NodeService.get_monkey_by_guid(telemetry_json["monkey_guid"])
        NodeService.update_monkey_modify_time(monkey["_id"])

        process_telemetry(telemetry_json)

        save_telemetry(telemetry_json)

        return {}, 201
示例#28
0
    def patch(self, guid):
        monkey_json = json.loads(request.data)
        update = {"$set": {'modifytime': datetime.now()}}
        monkey = NodeService.get_monkey_by_guid(guid)
        if 'keepalive' in monkey_json:
            update['$set']['keepalive'] = dateutil.parser.parse(
                monkey_json['keepalive'])
        else:
            update['$set']['keepalive'] = datetime.now()
        if 'config' in monkey_json:
            update['$set']['config'] = monkey_json['config']
        if 'config_error' in monkey_json:
            update['$set']['config_error'] = monkey_json['config_error']

        if 'tunnel' in monkey_json:
            tunnel_host_ip = monkey_json['tunnel'].split(":")[-2].replace(
                "//", "")
            NodeService.set_monkey_tunnel(monkey["_id"], tunnel_host_ip)

        return mongo.db.monkey.update({"_id": monkey["_id"]},
                                      update,
                                      upsert=False)
示例#29
0
 def process_state_telemetry(telemetry_json):
     monkey = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])
     if telemetry_json['data']['done']:
         NodeService.set_monkey_dead(monkey, True)
     else:
         NodeService.set_monkey_dead(monkey, False)