forked from p15670423/monkey
Fixed CR
This commit is contained in:
parent
7e77e2d33b
commit
e1803a7ff9
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,4 +10,6 @@ Flask-Pymongo
|
||||||
Flask-Restful
|
Flask-Restful
|
||||||
jsonschema
|
jsonschema
|
||||||
netifaces
|
netifaces
|
||||||
|
ipaddress
|
||||||
|
enum34
|
||||||
virtualenv
|
virtualenv
|
|
@ -10,4 +10,5 @@ Flask-Pymongo
|
||||||
Flask-Restful
|
Flask-Restful
|
||||||
jsonschema
|
jsonschema
|
||||||
netifaces
|
netifaces
|
||||||
ipaddress
|
ipaddress
|
||||||
|
enum34
|
Loading…
Reference in New Issue