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 flask import request, make_response, jsonify
import flask_restful
from flask import request, make_response, jsonify
from cc.database import mongo
from cc.services.config import ConfigService
from cc.services.node import NodeService
from cc.services.report import ReportService
from cc.utils import local_ip_addresses
__author__ = 'Barak'
@ -19,25 +18,34 @@ class Root(flask_restful.Resource):
action = request.args.get('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":
mongo.db.config.drop()
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')
return Root.reset_db()
elif action == "killall":
mongo.db.monkey.update({'dead': False}, {'$set': {'config.alive': False, 'modifytime': datetime.now()}}, upsert=False,
multi=True)
return jsonify(status='OK')
return Root.kill_all()
else:
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()
infection_done = NodeService.is_monkey_finished_running()
report_done = ReportService.is_report_generated()

View File

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

View File

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

View File

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

View File

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

View File

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