2017-08-25 22:47:08 +08:00
|
|
|
import json
|
2017-09-06 19:49:58 +08:00
|
|
|
import traceback
|
2017-10-15 21:01:39 +08:00
|
|
|
from datetime import datetime
|
2017-08-25 22:47:08 +08:00
|
|
|
|
|
|
|
import dateutil
|
|
|
|
import flask_restful
|
2017-10-15 21:01:39 +08:00
|
|
|
from flask import request
|
2017-08-25 22:47:08 +08:00
|
|
|
|
|
|
|
from cc.database import mongo
|
2017-10-15 21:01:39 +08:00
|
|
|
from cc.services.config import ConfigService
|
2017-09-06 19:49:58 +08:00
|
|
|
from cc.services.edge import EdgeService
|
|
|
|
from cc.services.node import NodeService
|
2017-08-25 22:47:08 +08:00
|
|
|
|
|
|
|
__author__ = 'Barak'
|
|
|
|
|
|
|
|
|
|
|
|
class Telemetry(flask_restful.Resource):
|
|
|
|
def get(self, **kw):
|
|
|
|
monkey_guid = request.args.get('monkey_guid')
|
|
|
|
telem_type = request.args.get('telem_type')
|
|
|
|
timestamp = request.args.get('timestamp')
|
|
|
|
if "null" == timestamp: # special case to avoid ugly JS code...
|
|
|
|
timestamp = None
|
|
|
|
|
|
|
|
result = {'timestamp': datetime.now().isoformat()}
|
|
|
|
find_filter = {}
|
|
|
|
|
|
|
|
if monkey_guid:
|
|
|
|
find_filter["monkey_guid"] = {'$eq': monkey_guid}
|
|
|
|
if telem_type:
|
|
|
|
find_filter["telem_type"] = {'$eq': telem_type}
|
|
|
|
if timestamp:
|
|
|
|
find_filter['timestamp'] = {'$gt': dateutil.parser.parse(timestamp)}
|
|
|
|
|
2017-09-15 00:01:42 +08:00
|
|
|
result['objects'] = self.telemetry_to_displayed_telemetry(mongo.db.telemetry.find(find_filter))
|
2017-08-25 22:47:08 +08:00
|
|
|
return result
|
|
|
|
|
|
|
|
def post(self):
|
|
|
|
telemetry_json = json.loads(request.data)
|
|
|
|
telemetry_json['timestamp'] = datetime.now()
|
|
|
|
|
|
|
|
telem_id = mongo.db.telemetry.insert(telemetry_json)
|
2017-09-06 19:49:58 +08:00
|
|
|
monkey = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])
|
2017-08-25 22:47:08 +08:00
|
|
|
|
|
|
|
try:
|
2017-09-06 19:49:58 +08:00
|
|
|
NodeService.update_monkey_modify_time(monkey["_id"])
|
2017-10-18 21:06:03 +08:00
|
|
|
telem_type = telemetry_json.get('telem_type')
|
|
|
|
if telem_type in TELEM_PROCESS_DICT:
|
|
|
|
TELEM_PROCESS_DICT[telem_type](telemetry_json)
|
|
|
|
else:
|
|
|
|
print('Got unknown type of telemetry: %s' % telem_type)
|
2017-08-25 22:47:08 +08:00
|
|
|
except StandardError as ex:
|
2017-09-06 19:49:58 +08:00
|
|
|
print("Exception caught while processing telemetry: %s" % str(ex))
|
|
|
|
traceback.print_exc()
|
2017-08-25 22:47:08 +08:00
|
|
|
|
|
|
|
return mongo.db.telemetry.find_one_or_404({"_id": telem_id})
|
|
|
|
|
2017-10-16 22:07:56 +08:00
|
|
|
@staticmethod
|
|
|
|
def telemetry_to_displayed_telemetry(telemetry):
|
2017-09-15 00:01:42 +08:00
|
|
|
monkey_guid_dict = {}
|
|
|
|
monkeys = mongo.db.monkey.find({})
|
|
|
|
for monkey in monkeys:
|
|
|
|
monkey_guid_dict[monkey["guid"]] = NodeService.get_monkey_label(monkey)
|
|
|
|
|
|
|
|
objects = []
|
|
|
|
for x in telemetry:
|
|
|
|
telem_monkey_guid = x.pop("monkey_guid")
|
|
|
|
monkey_label = monkey_guid_dict.get(telem_monkey_guid)
|
|
|
|
if monkey_label is None:
|
|
|
|
monkey_label = telem_monkey_guid
|
|
|
|
x["monkey"] = monkey_label
|
|
|
|
objects.append(x)
|
|
|
|
|
|
|
|
return objects
|
|
|
|
|
2017-10-16 22:07:56 +08:00
|
|
|
@staticmethod
|
|
|
|
def get_edge_by_scan_or_exploit_telemetry(telemetry_json):
|
2017-09-13 22:20:23 +08:00
|
|
|
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"])
|
|
|
|
|
2017-10-16 22:07:56 +08:00
|
|
|
@staticmethod
|
|
|
|
def process_tunnel_telemetry(telemetry_json):
|
2017-09-06 19:49:58 +08:00
|
|
|
monkey_id = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])["_id"]
|
2017-09-26 19:16:17 +08:00
|
|
|
if telemetry_json['data']['proxy'] is not None:
|
2017-10-01 21:34:11 +08:00
|
|
|
tunnel_host_ip = telemetry_json['data']['proxy'].split(":")[-2].replace("//", "")
|
|
|
|
NodeService.set_monkey_tunnel(monkey_id, tunnel_host_ip)
|
2017-09-12 18:48:36 +08:00
|
|
|
else:
|
|
|
|
NodeService.unset_all_monkey_tunnels(monkey_id)
|
2017-09-06 19:49:58 +08:00
|
|
|
|
2017-10-16 22:07:56 +08:00
|
|
|
@staticmethod
|
|
|
|
def process_state_telemetry(telemetry_json):
|
2017-09-06 19:49:58 +08:00
|
|
|
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)
|
|
|
|
|
2017-10-16 22:07:56 +08:00
|
|
|
@staticmethod
|
|
|
|
def process_exploit_telemetry(telemetry_json):
|
|
|
|
edge = Telemetry.get_edge_by_scan_or_exploit_telemetry(telemetry_json)
|
2017-10-15 21:01:39 +08:00
|
|
|
new_exploit = telemetry_json['data']
|
|
|
|
|
|
|
|
new_exploit.pop('machine')
|
|
|
|
new_exploit['timestamp'] = telemetry_json['timestamp']
|
|
|
|
|
2017-09-13 22:20:23 +08:00
|
|
|
mongo.db.edge.update(
|
2017-10-15 21:01:39 +08:00
|
|
|
{'_id': edge['_id']},
|
|
|
|
{'$push': {'exploits': new_exploit}}
|
2017-09-13 22:20:23 +08:00
|
|
|
)
|
2017-10-15 21:01:39 +08:00
|
|
|
if new_exploit['result']:
|
2017-09-13 22:20:23 +08:00
|
|
|
EdgeService.set_edge_exploited(edge)
|
2017-09-06 19:49:58 +08:00
|
|
|
|
2017-10-16 22:07:56 +08:00
|
|
|
@staticmethod
|
|
|
|
def process_scan_telemetry(telemetry_json):
|
|
|
|
edge = Telemetry.get_edge_by_scan_or_exploit_telemetry(telemetry_json)
|
2017-08-25 22:47:08 +08:00
|
|
|
data = telemetry_json['data']['machine']
|
2017-09-17 23:54:35 +08:00
|
|
|
ip_address = data.pop("ip_addr")
|
2017-08-25 22:47:08 +08:00
|
|
|
new_scan = \
|
|
|
|
{
|
|
|
|
"timestamp": telemetry_json["timestamp"],
|
|
|
|
"data": data,
|
|
|
|
"scanner": telemetry_json['data']['scanner']
|
|
|
|
}
|
|
|
|
mongo.db.edge.update(
|
|
|
|
{"_id": edge["_id"]},
|
2017-09-17 23:54:35 +08:00
|
|
|
{"$push": {"scans": new_scan},
|
|
|
|
"$set": {"ip_address": ip_address}}
|
2017-08-25 22:47:08 +08:00
|
|
|
)
|
|
|
|
|
2017-09-06 19:49:58 +08:00
|
|
|
node = mongo.db.node.find_one({"_id": edge["to"]})
|
|
|
|
if node is not None:
|
|
|
|
if new_scan["scanner"] == "TcpScanner":
|
|
|
|
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)
|
|
|
|
|
2017-10-16 22:07:56 +08:00
|
|
|
@staticmethod
|
|
|
|
def process_system_info_telemetry(telemetry_json):
|
2017-09-13 22:20:23 +08:00
|
|
|
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'])
|
2017-09-26 23:11:13 +08:00
|
|
|
if 'lm_hash' in creds[user]:
|
|
|
|
ConfigService.creds_add_lm_hash(creds[user]['lm_hash'])
|
|
|
|
if 'ntlm_hash' in creds[user]:
|
|
|
|
ConfigService.creds_add_ntlm_hash(creds[user]['ntlm_hash'])
|
2017-10-16 22:07:56 +08:00
|
|
|
|
2017-10-18 21:06:03 +08:00
|
|
|
@staticmethod
|
|
|
|
def process_trace_telemetry(telemetry_json):
|
|
|
|
# Nothing to do
|
|
|
|
return
|
2017-10-16 22:07:56 +08:00
|
|
|
|
|
|
|
TELEM_PROCESS_DICT = \
|
|
|
|
{
|
|
|
|
'tunnel': Telemetry.process_tunnel_telemetry,
|
|
|
|
'state': Telemetry.process_state_telemetry,
|
|
|
|
'exploit': Telemetry.process_exploit_telemetry,
|
|
|
|
'scan': Telemetry.process_scan_telemetry,
|
|
|
|
'system_info_collection': Telemetry.process_system_info_telemetry,
|
2017-10-18 21:06:03 +08:00
|
|
|
'trace': Telemetry.process_trace_telemetry
|
2017-10-16 22:07:56 +08:00
|
|
|
}
|