def update_edges_and_nodes_based_on_scan_telemetry(telemetry_json): edge = get_edge_by_scan_or_exploit_telemetry(telemetry_json) data = copy.deepcopy(telemetry_json['data']['machine']) ip_address = data.pop("ip_addr") domain_name = data.pop("domain_name") new_scan = \ { "timestamp": telemetry_json["timestamp"], "data": data } mongo.db.edge.update({"_id": edge["_id"]}, { "$push": { "scans": new_scan }, "$set": { "ip_address": ip_address, 'domain_name': domain_name } }) node = mongo.db.node.find_one({"_id": edge["to"]}) if node is not None: scan_os = new_scan["data"]["os"] if "type" in scan_os: mongo.db.node.update({"_id": node["_id"]}, {"$set": { "os.type": scan_os["type"] }}, upsert=False) if "version" in scan_os: mongo.db.node.update({"_id": node["_id"]}, {"$set": { "os.version": scan_os["version"] }}, upsert=False) EdgeService.update_label_by_endpoint(edge, node["_id"])
def update_edge_info_with_new_exploit(edge, telemetry_json): telemetry_json['data']['info']['started'] = dateutil.parser.parse( telemetry_json['data']['info']['started']) telemetry_json['data']['info']['finished'] = dateutil.parser.parse( telemetry_json['data']['info']['finished']) new_exploit = copy.deepcopy(telemetry_json['data']) new_exploit.pop('machine') new_exploit['timestamp'] = telemetry_json['timestamp'] mongo.db.edge.update({'_id': edge['_id']}, {'$push': { 'exploits': new_exploit }}) if new_exploit['result']: EdgeService.set_edge_exploited(edge)
def get_scanned(): formatted_nodes = [] nodes = \ [NodeService.get_displayed_node_by_id(node['_id'], True) for node in mongo.db.node.find({}, {'_id': 1})] \ + [NodeService.get_displayed_node_by_id(monkey['_id'], True) for monkey in mongo.db.monkey.find({}, {'_id': 1})] for node in nodes: formatted_nodes.append({ 'label': node['label'], 'ip_addresses': node['ip_addresses'], 'accessible_from_nodes': list((x['hostname'] for x in ( NodeService.get_displayed_node_by_id(edge['from'], True) for edge in EdgeService.get_displayed_edges_by_to( node['id'], True)))), 'services': node['services'], 'domain_name': node['domain_name'] }) logger.info('Scanned nodes generated for reporting') return formatted_nodes
def get_displayed_node_by_id(node_id, for_report=False): if ObjectId(node_id) == NodeService.get_monkey_island_pseudo_id(): return NodeService.get_monkey_island_node() new_node = {"id": node_id} node = NodeService.get_node_by_id(node_id) if node is None: monkey = NodeService.get_monkey_by_id(node_id) if monkey is None: return new_node # node is infected new_node = NodeService.monkey_to_net_node(monkey, for_report) for key in monkey: if key not in [ '_id', 'modifytime', 'parent', 'dead', 'description' ]: new_node[key] = monkey[key] else: # node is uninfected new_node = NodeService.node_to_net_node(node, for_report) new_node["ip_addresses"] = node["ip_addresses"] new_node["domain_name"] = node["domain_name"] accessible_from_nodes = [] accessible_from_nodes_hostnames = [] exploits = [] edges = EdgeService.get_displayed_edges_by_to(node_id, for_report) for edge in edges: from_node_id = edge["from"] from_node_label = Monkey.get_label_by_id(from_node_id) from_node_hostname = Monkey.get_hostname_by_id(from_node_id) accessible_from_nodes.append(from_node_label) accessible_from_nodes_hostnames.append(from_node_hostname) for exploit in edge["exploits"]: exploit["origin"] = from_node_label exploits.append(exploit) exploits.sort(cmp=NodeService._cmp_exploits_by_timestamp) new_node["exploits"] = exploits new_node["accessible_from_nodes"] = accessible_from_nodes new_node[ "accessible_from_nodes_hostnames"] = accessible_from_nodes_hostnames if len(edges) > 0: new_node["services"] = edges[-1]["services"] else: new_node["services"] = [] new_node[ 'has_log'] = monkey_island.cc.services.log.LogService.log_exists( ObjectId(node_id)) return new_node
def get(self, **kw): monkeys = [NodeService.monkey_to_net_node(x) for x in mongo.db.monkey.find({})] nodes = [NodeService.node_to_net_node(x) for x in mongo.db.node.find({})] edges = [EdgeService.edge_to_net_edge(x) for x in mongo.db.edge.find({})] if NodeService.get_monkey_island_monkey() is None: monkey_island = [NodeService.get_monkey_island_pseudo_net_node()] edges += EdgeService.get_monkey_island_pseudo_edges() else: monkey_island = [] edges += EdgeService.get_infected_monkey_island_pseudo_edges() return \ { "nodes": monkeys + nodes + monkey_island, "edges": edges }
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"])
def set_monkey_tunnel(monkey_id, tunnel_host_ip): tunnel_host_id = NodeService.get_monkey_by_ip(tunnel_host_ip)["_id"] NodeService.unset_all_monkey_tunnels(monkey_id) mongo.db.monkey.update( {"_id": monkey_id}, {'$set': {'tunnel': tunnel_host_id}}, upsert=False) tunnel_edge = EdgeService.get_or_create_edge(monkey_id, tunnel_host_id) mongo.db.edge.update({"_id": tunnel_edge["_id"]}, {'$set': {'tunnel': True, 'ip_address': tunnel_host_ip}}, upsert=False)
def process_exploit_telemetry(telemetry_json): edge = Telemetry.get_edge_by_scan_or_exploit_telemetry(telemetry_json) Telemetry.encrypt_exploit_creds(telemetry_json) new_exploit = copy.deepcopy(telemetry_json['data']) new_exploit.pop('machine') new_exploit['timestamp'] = telemetry_json['timestamp'] mongo.db.edge.update( {'_id': edge['_id']}, {'$push': {'exploits': new_exploit}} ) if new_exploit['result']: EdgeService.set_edge_exploited(edge) for attempt in telemetry_json['data']['attempts']: if attempt['result']: found_creds = {'user': attempt['user']} for field in ['password', 'lm_hash', 'ntlm_hash', 'ssh_key']: if len(attempt[field]) != 0: found_creds[field] = attempt[field] NodeService.add_credentials_to_node(edge['to'], found_creds)
def get_or_create_node_from_bootloader_telem( bootloader_telem: Dict, will_monkey_run: bool) -> Dict: if is_local_ips(bootloader_telem['ips']): raise NodeCreationException( "Bootloader ran on island, no need to create new node.") new_node = mongo.db.node.find_one( {"ip_addresses": { "$in": bootloader_telem['ips'] }}) # Temporary workaround to not create a node after monkey finishes monkey_node = mongo.db.monkey.find_one( {"ip_addresses": { "$in": bootloader_telem['ips'] }}) if monkey_node: # Don't create new node, monkey node is already present return monkey_node if new_node is None: new_node = NodeService.create_node_from_bootloader_telem( bootloader_telem, will_monkey_run) if bootloader_telem['tunnel']: dst_node = NodeService.get_node_or_monkey_by_ip( bootloader_telem['tunnel']) else: dst_node = NodeService.get_monkey_island_node() edge = EdgeService.get_or_create_edge(new_node['_id'], dst_node['id']) mongo.db.edge.update({"_id": edge["_id"]}, { '$set': { 'tunnel': bool(bootloader_telem['tunnel']), 'ip_address': bootloader_telem['ips'][0], 'group': NodeStates.get_by_keywords(['island']).value } }, upsert=False) return new_node
def get(self): edge_id = request.args.get('id') if edge_id: return {"edge": EdgeService.get_displayed_edge_by_id(edge_id)} return {}