Change infected monkey island label

add edges for infected monkey island
add edge types
add exploited node type
This commit is contained in:
Itay Mizeretz 2017-09-13 17:20:23 +03:00
parent 77f7e4c5a8
commit 9a9906326a
4 changed files with 129 additions and 57 deletions

View File

@ -11,12 +11,14 @@ class NetMap(flask_restful.Resource):
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 = [self.edge_to_net_edge(x) for x in mongo.db.edge.find({})]
monkey_island = []
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()]
# TODO: implement when monkey exists on island
edges += EdgeService.get_monkey_island_pseudo_edges()
else:
monkey_island = []
edges += EdgeService.get_infected_monkey_island_pseudo_edges()
return \
{
@ -24,10 +26,4 @@ class NetMap(flask_restful.Resource):
"edges": edges
}
def edge_to_net_edge(self, edge):
return \
{
"id": edge["_id"],
"from": edge["from"],
"to": edge["to"]
}

View File

@ -47,8 +47,10 @@ class Telemetry(flask_restful.Resource):
self.process_tunnel_telemetry(telemetry_json)
elif telemetry_json.get('telem_type') == 'state':
self.process_state_telemetry(telemetry_json)
elif telemetry_json.get('telem_type') in ['scan', 'exploit']:
self.process_scan_exploit_telemetry(telemetry_json)
elif telemetry_json.get('telem_type') == 'exploit':
self.process_exploit_telemetry(telemetry_json)
elif telemetry_json.get('telem_type') == 'scan':
self.process_scan_telemetry(telemetry_json)
elif telemetry_json.get('telem_type') == 'system_info_collection':
self.process_system_info_telemetry(telemetry_json)
NodeService.update_monkey_modify_time(monkey["_id"])
@ -58,6 +60,15 @@ class Telemetry(flask_restful.Resource):
return mongo.db.telemetry.find_one_or_404({"_id": telem_id})
def get_edge_by_scan_or_exploit_telemetry(self, telemetry_json):
dst_ip = telemetry_json['data']['machine']['ip_addr']
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)
return EdgeService.get_or_create_edge(src_monkey["_id"], dst_node["_id"])
def process_tunnel_telemetry(self, telemetry_json):
monkey_id = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])["_id"]
if telemetry_json['data']['proxy'] is not None:
@ -74,29 +85,25 @@ class Telemetry(flask_restful.Resource):
else:
NodeService.set_monkey_dead(monkey, False)
def process_scan_exploit_telemetry(self, telemetry_json):
dst_ip = telemetry_json['data']['machine']['ip_addr']
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)
def process_exploit_telemetry(self, telemetry_json):
edge = self.get_edge_by_scan_or_exploit_telemetry(telemetry_json)
data = telemetry_json['data']
data["machine"].pop("ip_addr")
new_exploit = \
{
"timestamp": telemetry_json["timestamp"],
"data": data,
"exploiter": telemetry_json['data']['exploiter']
}
mongo.db.edge.update(
{"_id": edge["_id"]},
{"$push": {"exploits": new_exploit}}
)
if data['result']:
EdgeService.set_edge_exploited(edge)
edge = EdgeService.get_or_create_edge(src_monkey["_id"], dst_node["_id"])
if telemetry_json.get('telem_type') == 'scan':
self.add_scan_to_edge(edge, telemetry_json)
else:
self.add_exploit_to_edge(edge, telemetry_json)
def process_system_info_telemetry(self, telemetry_json):
if 'credentials' in telemetry_json['data']:
creds = telemetry_json['data']['credentials']
for user in creds:
ConfigService.creds_add_username(user)
if 'password' in creds[user]:
ConfigService.creds_add_password(creds[user]['password'])
def add_scan_to_edge(self, edge, telemetry_json):
def process_scan_telemetry(self, telemetry_json):
edge = self.get_edge_by_scan_or_exploit_telemetry(telemetry_json)
data = telemetry_json['data']['machine']
data.pop("ip_addr")
new_scan = \
@ -123,17 +130,12 @@ class Telemetry(flask_restful.Resource):
{"$set": {"os.version": scan_os["version"]}},
upsert=False)
def add_exploit_to_edge(self, edge, telemetry_json):
data = telemetry_json['data']
data["machine"].pop("ip_addr")
new_exploit = \
{
"timestamp": telemetry_json["timestamp"],
"data": data,
"exploiter": telemetry_json['data']['exploiter']
}
mongo.db.edge.update(
{"_id": edge["_id"]},
{"$push": {"exploits": new_exploit}}
)
def process_system_info_telemetry(self, telemetry_json):
if 'credentials' in telemetry_json['data']:
creds = telemetry_json['data']['credentials']
for user in creds:
ConfigService.creds_add_username(user)
if 'password' in creds[user]:
ConfigService.creds_add_password(creds[user]['password'])

View File

@ -1,6 +1,7 @@
from bson import ObjectId
from cc.database import mongo
import cc.services.node
__author__ = "itay.mizeretz"
@ -99,7 +100,8 @@ class EdgeService:
"to": to_id,
"scans": [],
"exploits": [],
"tunnel": False
"tunnel": False,
"exploited": False
})
return mongo.db.edge.find_one({"_id": edge_insert_result.inserted_id})
@ -111,6 +113,16 @@ class EdgeService:
return tunnel_edge
@staticmethod
def generate_pseudo_edge(edge_id, edge_from, edge_to):
return \
{
"id": edge_id,
"from": edge_from,
"to": edge_to,
"group": "island"
}
@staticmethod
def get_monkey_island_pseudo_edges():
edges = []
@ -120,13 +132,26 @@ class EdgeService:
count = 0
for monkey_id in monkey_ids:
count += 1
edges.append(
{
"id": ObjectId(hex(count)[2:].zfill(24)),
"from": monkey_id,
"to": ObjectId("000000000000000000000000")
}
)
edges.append(EdgeService.generate_pseudo_edge(
ObjectId(hex(count)[2:].zfill(24)), monkey_id, ObjectId("000000000000000000000000")))
return edges
@staticmethod
def get_infected_monkey_island_pseudo_edges():
monkey = cc.services.node.NodeService.get_monkey_island_monkey()
existing_ids = [x["_id"] for x in mongo.db.edge.find({"to": monkey["_id"]})]
monkey_ids = [x["_id"] for x in mongo.db.monkey.find({})
if ("tunnel" not in x) and (x["_id"] not in existing_ids)]
edges = []
# We're using fake ids because the frontend graph module requires unique ids.
# Collision with real id is improbable.
count = 0
for monkey_id in monkey_ids:
count += 1
edges.append(EdgeService.generate_pseudo_edge(
ObjectId(hex(count)[2:].zfill(24)), monkey_id, monkey["_id"]))
return edges
@ -134,3 +159,33 @@ class EdgeService:
def services_to_displayed_services(services):
# TODO: Consider returning extended information on services.
return [x + ": " + services[x]["name"] for x in services]
@staticmethod
def edge_to_net_edge(edge):
return \
{
"id": edge["_id"],
"from": edge["from"],
"to": edge["to"],
"group": EdgeService.get_edge_group(edge)
}
@staticmethod
def get_edge_group(edge):
if edge["exploited"]:
return "exploited"
if edge["tunnel"]:
return "tunnel"
if (len(edge["scans"]) > 0) or (len(edge["exploits"]) > 0):
return "scan"
return "empty"
@staticmethod
def set_edge_exploited(edge):
mongo.db.edge.update(
{"_id": edge["_id"]},
{"$set": {"exploited": True}}
)
cc.services.node.NodeService.set_node_exploited(edge["to"])

View File

@ -89,7 +89,11 @@ class NodeService:
@staticmethod
def get_monkey_label(monkey):
return monkey["hostname"] + " : " + monkey["ip_addresses"][0]
label = monkey["hostname"] + " : " + monkey["ip_addresses"][0]
ip_addresses = local_ip_addresses()
if len(set(monkey["ip_addresses"]).intersection(ip_addresses)) > 0:
label = "MonkeyIsland - " + label
return label
@staticmethod
def get_monkey_group(monkey):
@ -98,6 +102,13 @@ class NodeService:
return "manuallyInfected" if NodeService.get_monkey_manual_run(monkey) else "infected"
@staticmethod
def get_node_group(node):
if node["exploited"]:
return "exploited"
else:
return "clean"
@staticmethod
def monkey_to_net_node(monkey):
return \
@ -115,7 +126,7 @@ class NodeService:
{
"id": node["_id"],
"label": NodeService.get_node_label(node),
"group": "clean",
"group": NodeService.get_node_group(node),
"os": node["os"]["type"]
}
@ -148,6 +159,7 @@ class NodeService:
new_node_insert_result = mongo.db.node.insert_one(
{
"ip_addresses": [ip_address],
"exploited": False,
"os":
{
"type": "unknown",
@ -218,3 +230,10 @@ class NodeService:
island_node = NodeService.get_monkey_island_pseudo_net_node()
island_node["ip_addresses"] = local_ip_addresses()
return island_node
@staticmethod
def set_node_exploited(node_id):
mongo.db.node.update(
{"_id": node_id},
{"$set": {"exploited": True}}
)