This commit is contained in:
Itay Mizeretz 2018-01-16 17:23:17 +02:00
parent 7e77e2d33b
commit e1803a7ff9
6 changed files with 61 additions and 58 deletions

View File

@ -1,13 +1,12 @@
from datetime import datetime from datetime import datetime
from flask import request, make_response, jsonify
import flask_restful import flask_restful
from flask import request, make_response, jsonify
from cc.database import mongo from cc.database import mongo
from cc.services.config import ConfigService from cc.services.config import ConfigService
from cc.services.node import NodeService from cc.services.node import NodeService
from cc.services.report import ReportService from cc.services.report import ReportService
from cc.utils import local_ip_addresses from cc.utils import local_ip_addresses
__author__ = 'Barak' __author__ = 'Barak'
@ -19,25 +18,34 @@ class Root(flask_restful.Resource):
action = request.args.get('action') action = request.args.get('action')
if not action: if not action:
return jsonify(ip_addresses=local_ip_addresses(), mongo=str(mongo.db), completed_steps=self.get_completed_steps()) return Root.get_server_info()
elif action == "reset": elif action == "reset":
mongo.db.config.drop() return Root.reset_db()
mongo.db.monkey.drop()
mongo.db.telemetry.drop()
mongo.db.node.drop()
mongo.db.edge.drop()
mongo.db.report.drop()
ConfigService.init_config()
return jsonify(status='OK')
elif action == "killall": elif action == "killall":
mongo.db.monkey.update({'dead': False}, {'$set': {'config.alive': False, 'modifytime': datetime.now()}}, upsert=False, return Root.kill_all()
multi=True)
return jsonify(status='OK')
else: else:
return make_response(400, {'error': 'unknown action'}) return make_response(400, {'error': 'unknown action'})
def get_completed_steps(self): @staticmethod
def get_server_info():
return jsonify(ip_addresses=local_ip_addresses(), mongo=str(mongo.db),
completed_steps=Root.get_completed_steps())
@staticmethod
def reset_db():
[mongo.db[x].drop() for x in ['config', 'monkey', 'telemetry', 'node', 'edge', 'report']]
ConfigService.init_config()
return jsonify(status='OK')
@staticmethod
def kill_all():
mongo.db.monkey.update({'dead': False}, {'$set': {'config.alive': False, 'modifytime': datetime.now()}},
upsert=False,
multi=True)
return jsonify(status='OK')
@staticmethod
def get_completed_steps():
is_any_exists = NodeService.is_any_monkey_exists() is_any_exists = NodeService.is_any_monkey_exists()
infection_done = NodeService.is_monkey_finished_running() infection_done = NodeService.is_monkey_finished_running()
report_done = ReportService.is_report_generated() report_done = ReportService.is_report_generated()

View File

@ -124,9 +124,7 @@ class Telemetry(flask_restful.Resource):
for attempt in telemetry_json['data']['attempts']: for attempt in telemetry_json['data']['attempts']:
if attempt['result']: if attempt['result']:
attempt.pop('result') attempt.pop('result')
for field in ['password', 'lm_hash', 'ntlm_hash']: [attempt.pop(field) for field in ['password', 'lm_hash', 'ntlm_hash'] if len(attempt[field]) == 0]
if len(attempt[field]) == 0:
attempt.pop(field)
NodeService.add_credentials_to_node(edge['to'], attempt) NodeService.add_credentials_to_node(edge['to'], attempt)
@staticmethod @staticmethod

View File

@ -1,4 +1,5 @@
import ipaddress import ipaddress
from enum import Enum
from cc.database import mongo from cc.database import mongo
from cc.services.config import ConfigService from cc.services.config import ConfigService
@ -25,7 +26,7 @@ class ReportService:
'ShellShockExploiter': 'ShellShock Exploiter', 'ShellShockExploiter': 'ShellShock Exploiter',
} }
class ISSUES_DICT: class ISSUES_DICT(Enum):
WEAK_PASSWORD = 0 WEAK_PASSWORD = 0
STOLEN_CREDS = 1 STOLEN_CREDS = 1
ELASTIC = 2 ELASTIC = 2
@ -33,7 +34,7 @@ class ReportService:
SHELLSHOCK = 4 SHELLSHOCK = 4
CONFICKER = 5 CONFICKER = 5
class WARNINGS_DICT: class WARNINGS_DICT(Enum):
CROSS_SEGMENT = 0 CROSS_SEGMENT = 0
TUNNEL = 1 TUNNEL = 1
@ -49,18 +50,15 @@ class ReportService:
def get_monkey_duration(): def get_monkey_duration():
delta = ReportService.get_last_monkey_dead_time() - ReportService.get_first_monkey_time() delta = ReportService.get_last_monkey_dead_time() - ReportService.get_first_monkey_time()
st = "" st = ""
hours, rem = divmod(delta.seconds, 60 * 60)
minutes, seconds = divmod(rem, 60)
if delta.days > 0: if delta.days > 0:
st += "%d days, " % delta.days st += "%d days, " % delta.days
total = delta.seconds
seconds = total % 60
total = (total - seconds) / 60
minutes = total % 60
total = (total - minutes) / 60
hours = total
if hours > 0: if hours > 0:
st += "%d hours, " % hours st += "%d hours, " % hours
st += "%d minutes and %d seconds" % (minutes, seconds) st += "%d minutes and %d seconds" % (minutes, seconds)
return st return st
@staticmethod @staticmethod
@ -77,7 +75,8 @@ class ReportService:
def get_scanned(): def get_scanned():
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(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})] + [NodeService.get_displayed_node_by_id(monkey['_id'], True) for monkey in
mongo.db.monkey.find({}, {'_id': 1})]
nodes = [ nodes = [
{ {
'label': node['label'], 'label': node['label'],
@ -95,7 +94,8 @@ class ReportService:
@staticmethod @staticmethod
def get_exploited(): def get_exploited():
exploited = \ exploited = \
[NodeService.get_displayed_node_by_id(monkey['_id'], True) for monkey in mongo.db.monkey.find({}, {'_id': 1}) [NodeService.get_displayed_node_by_id(monkey['_id'], True) for monkey in
mongo.db.monkey.find({}, {'_id': 1})
if not NodeService.get_monkey_manual_run(NodeService.get_monkey_by_id(monkey['_id']))] \ if not NodeService.get_monkey_manual_run(NodeService.get_monkey_by_id(monkey['_id']))] \
+ [NodeService.get_displayed_node_by_id(node['_id'], True) + [NodeService.get_displayed_node_by_id(node['_id'], True)
for node in mongo.db.node.find({'exploited': True}, {'_id': 1})] for node in mongo.db.node.find({'exploited': True}, {'_id': 1})]
@ -215,22 +215,18 @@ class ReportService:
@staticmethod @staticmethod
def process_exploit(exploit): def process_exploit(exploit):
exploiter_type = exploit['data']['exploiter'] exploiter_type = exploit['data']['exploiter']
if exploiter_type == 'SmbExploiter': EXPLOIT_PROCESS_FUNCTION_DICT = {
return ReportService.process_smb_exploit(exploit) 'SmbExploiter': ReportService.process_smb_exploit,
if exploiter_type == 'WmiExploiter': 'WmiExploiter': ReportService.process_wmi_exploit,
return ReportService.process_wmi_exploit(exploit) 'SSHExploiter': ReportService.process_ssh_exploit,
if exploiter_type == 'SSHExploiter': 'RdpExploiter': ReportService.process_rdp_exploit,
return ReportService.process_ssh_exploit(exploit) 'SambaCryExploiter': ReportService.process_sambacry_exploit,
if exploiter_type == 'RdpExploiter': 'ElasticGroovyExploiter': ReportService.process_elastic_exploit,
return ReportService.process_rdp_exploit(exploit) 'Ms08_067_Exploiter': ReportService.process_conficker_exploit,
if exploiter_type == 'SambaCryExploiter': 'ShellShockExploiter': ReportService.process_shellshock_exploit,
return ReportService.process_sambacry_exploit(exploit) }
if exploiter_type == 'ElasticGroovyExploiter':
return ReportService.process_elastic_exploit(exploit) return EXPLOIT_PROCESS_FUNCTION_DICT[exploiter_type](exploit)
if exploiter_type == 'Ms08_067_Exploiter':
return ReportService.process_conficker_exploit(exploit)
if exploiter_type == 'ShellShockExploiter':
return ReportService.process_shellshock_exploit(exploit)
@staticmethod @staticmethod
def get_exploits(): def get_exploits():
@ -334,18 +330,18 @@ class ReportService:
for machine in issues: for machine in issues:
for issue in issues[machine]: for issue in issues[machine]:
if issue['type'] == 'elastic': if issue['type'] == 'elastic':
issues_byte_array[ReportService.ISSUES_DICT.ELASTIC] = True issues_byte_array[ReportService.ISSUES_DICT.ELASTIC.value] = True
elif issue['type'] == 'sambacry': elif issue['type'] == 'sambacry':
issues_byte_array[ReportService.ISSUES_DICT.SAMBACRY] = True issues_byte_array[ReportService.ISSUES_DICT.SAMBACRY.value] = True
elif issue['type'] == 'shellshock': elif issue['type'] == 'shellshock':
issues_byte_array[ReportService.ISSUES_DICT.SHELLSHOCK] = True issues_byte_array[ReportService.ISSUES_DICT.SHELLSHOCK.value] = True
elif issue['type'] == 'conficker': elif issue['type'] == 'conficker':
issues_byte_array[ReportService.ISSUES_DICT.CONFICKER] = True issues_byte_array[ReportService.ISSUES_DICT.CONFICKER.value] = True
elif issue['type'].endswith('_password') and issue['password'] in config_passwords and \ elif issue['type'].endswith('_password') and issue['password'] in config_passwords and \
issue['username'] in config_users: issue['username'] in config_users:
issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD] = True issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD.value] = True
elif issue['type'].endswith('_pth') or issue['type'].endswith('_password'): elif issue['type'].endswith('_pth') or issue['type'].endswith('_password'):
issues_byte_array[ReportService.ISSUES_DICT.STOLEN_CREDS] = True issues_byte_array[ReportService.ISSUES_DICT.STOLEN_CREDS.value] = True
return issues_byte_array return issues_byte_array
@ -356,9 +352,9 @@ class ReportService:
for machine in issues: for machine in issues:
for issue in issues[machine]: for issue in issues[machine]:
if issue['type'] == 'cross_segment': if issue['type'] == 'cross_segment':
warnings_byte_array[ReportService.WARNINGS_DICT.CROSS_SEGMENT] = True warnings_byte_array[ReportService.WARNINGS_DICT.CROSS_SEGMENT.value] = True
elif issue['type'] == 'tunnel': elif issue['type'] == 'tunnel':
warnings_byte_array[ReportService.WARNINGS_DICT.TUNNEL] = True warnings_byte_array[ReportService.WARNINGS_DICT.TUNNEL.value] = True
return warnings_byte_array return warnings_byte_array

View File

@ -7,8 +7,6 @@ import struct
import ipaddress import ipaddress
from netifaces import interfaces, ifaddresses, AF_INET from netifaces import interfaces, ifaddresses, AF_INET
from cc.database import mongo
__author__ = 'Barak' __author__ = 'Barak'

View File

@ -10,4 +10,6 @@ Flask-Pymongo
Flask-Restful Flask-Restful
jsonschema jsonschema
netifaces netifaces
ipaddress
enum34
virtualenv virtualenv

View File

@ -10,4 +10,5 @@ Flask-Pymongo
Flask-Restful Flask-Restful
jsonschema jsonschema
netifaces netifaces
ipaddress ipaddress
enum34