Merge pull request #145 from guardicore/feature/support-common-folder

Feature/support common folder
This commit is contained in:
itaymmguardicore 2018-09-13 14:56:24 +03:00 committed by GitHub
commit 0518899475
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
202 changed files with 365 additions and 359 deletions

10
.gitignore vendored
View File

@ -62,9 +62,9 @@ docs/_build/
# PyBuilder # PyBuilder
target/ target/
db
bin bin
/monkey_island/cc/server.key /monkey/monkey_island/db
/monkey_island/cc/server.crt /monkey/monkey_island/cc/server.key
/monkey_island/cc/server.csr /monkey/monkey_island/cc/server.crt
monkey_island/cc/ui/node_modules/ /monkey/monkey_island/cc/server.csr
/monkey/monkey_island/cc/ui/node_modules/

View File

@ -1,30 +0,0 @@
from abc import ABCMeta, abstractmethod
__author__ = 'itamar'
class HostScanner(object):
__metaclass__ = ABCMeta
@abstractmethod
def is_host_alive(self, host):
raise NotImplementedError()
class HostFinger(object):
__metaclass__ = ABCMeta
@abstractmethod
def get_host_fingerprint(self, host):
raise NotImplementedError()
from ping_scanner import PingScanner
from tcp_scanner import TcpScanner
from smbfinger import SMBFinger
from sshfinger import SSHFinger
from httpfinger import HTTPFinger
from elasticfinger import ElasticFinger
from mysqlfinger import MySQLFinger
from info import local_ips
from info import get_free_tcp_port
from mssql_fingerprint import MSSQLFinger

View File

@ -1,3 +0,0 @@
from http import HTTPServer, LockedHTTPServer
__author__ = 'hoffer'

View File

@ -0,0 +1 @@
__author__ = 'itay.mizeretz'

View File

@ -0,0 +1,4 @@
import infection_monkey.main
if "__main__" == __name__:
infection_monkey.main.main()

View File

@ -0,0 +1 @@
__author__ = 'itay.mizeretz'

View File

@ -1,15 +1,13 @@
import os import os
import struct import json
import sys import sys
import types import types
import uuid import uuid
from abc import ABCMeta from abc import ABCMeta
from itertools import product from itertools import product
import importlib
from exploit import WmiExploiter, Ms08_067_Exploiter, SmbExploiter, RdpExploiter, SSHExploiter, ShellShockExploiter, \ importlib.import_module('infection_monkey', 'network')
SambaCryExploiter, ElasticGroovyExploiter, Struts2Exploiter, WebLogicExploiter, HadoopExploiter
from network import TcpScanner, PingScanner, SMBFinger, SSHFinger, HTTPFinger, MySQLFinger, ElasticFinger, \
MSSQLFinger
__author__ = 'itamar' __author__ = 'itamar'
@ -18,57 +16,47 @@ GUID = str(uuid.getnode())
EXTERNAL_CONFIG_FILE = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), 'monkey.bin') EXTERNAL_CONFIG_FILE = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), 'monkey.bin')
def _cast_by_example(value, example):
"""
a method that casts a value to the type of the parameter given as example
"""
example_type = type(example)
if example_type is str:
return os.path.expandvars(value).encode("utf8")
elif example_type is tuple and len(example) != 0:
if value is None or value == tuple([None]):
return tuple()
return tuple([_cast_by_example(x, example[0]) for x in value])
elif example_type is list and len(example) != 0:
if value is None or value == [None]:
return []
return [_cast_by_example(x, example[0]) for x in value]
elif example_type is type(value):
return value
elif example_type is bool:
return value.lower() == 'true'
elif example_type is int:
return int(value)
elif example_type is float:
return float(value)
elif example_type in (type, ABCMeta):
return globals()[value]
else:
return None
class Configuration(object): class Configuration(object):
def from_dict(self, data):
""" def from_kv(self, formatted_data):
Get a dict of config variables, set known variables as attributes on self. # now we won't work at <2.7 for sure
Return dict of unknown variables encountered. network_import = importlib.import_module('infection_monkey.network')
""" exploit_import = importlib.import_module('infection_monkey.exploit')
unknown_variables = {}
for key, value in data.items(): unknown_items = []
for key, value in formatted_data.items():
if key.startswith('_'): if key.startswith('_'):
continue continue
if key in ["name", "id", "current_server"]: if key in ["name", "id", "current_server"]:
continue continue
if self._depth_from_commandline and key == "depth": if self._depth_from_commandline and key == "depth":
continue continue
try: # handle in cases
default_value = getattr(Configuration, key) if key == 'finger_classes':
except AttributeError: class_objects = [getattr(network_import, val) for val in value]
unknown_variables[key] = value setattr(self, key, class_objects)
continue elif key == 'scanner_class':
scanner_object = getattr(network_import, value)
setattr(self, key, scanner_object)
elif key == 'exploiter_classes':
class_objects = [getattr(exploit_import, val) for val in value]
setattr(self, key, class_objects)
else:
if hasattr(self, key):
setattr(self, key, value)
else:
unknown_items.append(key)
return unknown_items
setattr(self, key, _cast_by_example(value, default_value)) def from_json(self, json_data):
return unknown_variables """
Gets a json data object, parses it and applies it to the configuration
:param json_data:
:return:
"""
formatted_data = json.loads(json_data)
result = self.from_kv(formatted_data)
return result
def as_dict(self): def as_dict(self):
result = {} result = {}
@ -145,12 +133,9 @@ class Configuration(object):
# how many scan iterations to perform on each run # how many scan iterations to perform on each run
max_iterations = 1 max_iterations = 1
scanner_class = TcpScanner scanner_class = None
finger_classes = [SMBFinger, SSHFinger, PingScanner, HTTPFinger, MySQLFinger, ElasticFinger, MSSQLFinger] finger_classes = []
exploiter_classes = [SmbExploiter, WmiExploiter, # Windows exploits exploiter_classes = []
SSHExploiter, ShellShockExploiter, SambaCryExploiter, # Linux
ElasticGroovyExploiter, Struts2Exploiter, WebLogicExploiter, HadoopExploiter # multi
]
# how many victims to look for in a single scan iteration # how many victims to look for in a single scan iteration
victims_max_find = 30 victims_max_find = 30

View File

@ -6,12 +6,12 @@ from socket import gethostname
import requests import requests
from requests.exceptions import ConnectionError from requests.exceptions import ConnectionError
import monkeyfs import infection_monkey.monkeyfs as monkeyfs
import tunnel import infection_monkey.tunnel as tunnel
from config import WormConfiguration, GUID from infection_monkey.config import WormConfiguration, GUID
from network.info import local_ips, check_internet_access from infection_monkey.network.info import local_ips, check_internet_access
from transport.http import HTTPConnectProxy from infection_monkey.transport.http import HTTPConnectProxy
from transport.tcp import TcpProxy from infection_monkey.transport.tcp import TcpProxy
__author__ = 'hoffer' __author__ = 'hoffer'
@ -160,7 +160,7 @@ class ControlClient(object):
return return
try: try:
unknown_variables = WormConfiguration.from_dict(reply.json().get('config')) unknown_variables = WormConfiguration.from_kv(reply.json().get('config'))
LOG.info("New configuration was loaded from server: %r" % (WormConfiguration.as_dict(),)) LOG.info("New configuration was loaded from server: %r" % (WormConfiguration.as_dict(),))
except Exception as exc: except Exception as exc:
# we don't continue with default conf here because it might be dangerous # we don't continue with default conf here because it might be dangerous

View File

@ -10,10 +10,10 @@ import time
from ctypes import c_char_p from ctypes import c_char_p
import filecmp import filecmp
from config import WormConfiguration from infection_monkey.config import WormConfiguration
from exploit.tools import build_monkey_commandline_explicitly from infection_monkey.exploit.tools import build_monkey_commandline_explicitly
from model import MONKEY_CMDLINE_WINDOWS, MONKEY_CMDLINE_LINUX, GENERAL_CMDLINE_LINUX from infection_monkey.model import MONKEY_CMDLINE_WINDOWS, MONKEY_CMDLINE_LINUX, GENERAL_CMDLINE_LINUX
from system_info import SystemInfoCollector, OperatingSystem from infection_monkey.system_info import SystemInfoCollector, OperatingSystem
if "win32" == sys.platform: if "win32" == sys.platform:
from win32process import DETACHED_PROCESS from win32process import DETACHED_PROCESS

View File

@ -1,4 +1,5 @@
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
import infection_monkey.config
__author__ = 'itamar' __author__ = 'itamar'
@ -9,7 +10,7 @@ class HostExploiter(object):
_TARGET_OS_TYPE = [] _TARGET_OS_TYPE = []
def __init__(self, host): def __init__(self, host):
self._config = infection_monkey.config.WormConfiguration
self._exploit_info = {} self._exploit_info = {}
self._exploit_attempts = [] self._exploit_attempts = []
self.host = host self.host = host
@ -18,7 +19,7 @@ class HostExploiter(object):
return self.host.os.get('type') in self._TARGET_OS_TYPE return self.host.os.get('type') in self._TARGET_OS_TYPE
def send_exploit_telemetry(self, result): def send_exploit_telemetry(self, result):
from control import ControlClient from infection_monkey.control import ControlClient
ControlClient.send_telemetry( ControlClient.send_telemetry(
'exploit', 'exploit',
{'result': result, 'machine': self.host.__dict__, 'exploiter': self.__class__.__name__, {'result': result, 'machine': self.host.__dict__, 'exploiter': self.__class__.__name__,
@ -33,14 +34,14 @@ class HostExploiter(object):
raise NotImplementedError() raise NotImplementedError()
from win_ms08_067 import Ms08_067_Exploiter from infection_monkey.exploit.win_ms08_067 import Ms08_067_Exploiter
from wmiexec import WmiExploiter from infection_monkey.exploit.wmiexec import WmiExploiter
from smbexec import SmbExploiter from infection_monkey.exploit.smbexec import SmbExploiter
from rdpgrinder import RdpExploiter from infection_monkey.exploit.rdpgrinder import RdpExploiter
from sshexec import SSHExploiter from infection_monkey.exploit.sshexec import SSHExploiter
from shellshock import ShellShockExploiter from infection_monkey.exploit.shellshock import ShellShockExploiter
from sambacry import SambaCryExploiter from infection_monkey.exploit.sambacry import SambaCryExploiter
from elasticgroovy import ElasticGroovyExploiter from infection_monkey.exploit.elasticgroovy import ElasticGroovyExploiter
from struts2 import Struts2Exploiter from infection_monkey.exploit.struts2 import Struts2Exploiter
from weblogic import WebLogicExploiter from infection_monkey.exploit.weblogic import WebLogicExploiter
from hadoop import HadoopExploiter from infection_monkey.exploit.hadoop import HadoopExploiter

View File

@ -7,9 +7,9 @@
import json import json
import logging import logging
import requests import requests
from exploit.web_rce import WebRCE from infection_monkey.exploit.web_rce import WebRCE
from model import WGET_HTTP_UPLOAD, RDP_CMDLINE_HTTP from infection_monkey.model import WGET_HTTP_UPLOAD, RDP_CMDLINE_HTTP
from network.elasticfinger import ES_PORT, ES_SERVICE from infection_monkey.network.elasticfinger import ES_PORT, ES_SERVICE
import re import re

View File

@ -8,10 +8,11 @@ import json
import random import random
import string import string
import logging import logging
from exploit.web_rce import WebRCE
from tools import HTTPTools, build_monkey_commandline, get_monkey_depth
import posixpath import posixpath
from model import MONKEY_ARG, ID_STRING
from infection_monkey.exploit.web_rce import WebRCE
from infection_monkey.exploit.tools import HTTPTools, build_monkey_commandline, get_monkey_depth
from infection_monkey.model import MONKEY_ARG, ID_STRING
__author__ = 'VakarisZ' __author__ = 'VakarisZ'

View File

@ -9,12 +9,12 @@ from rdpy.core.error import RDPSecurityNegoFail
from rdpy.protocol.rdp import rdp from rdpy.protocol.rdp import rdp
from twisted.internet import reactor from twisted.internet import reactor
from exploit import HostExploiter from infection_monkey.exploit import HostExploiter
from exploit.tools import HTTPTools, get_monkey_depth from infection_monkey.exploit.tools import HTTPTools, get_monkey_depth
from exploit.tools import get_target_monkey from infection_monkey.exploit.tools import get_target_monkey
from model import RDP_CMDLINE_HTTP_BITS, RDP_CMDLINE_HTTP_VBS from infection_monkey.model import RDP_CMDLINE_HTTP_BITS, RDP_CMDLINE_HTTP_VBS
from network.tools import check_tcp_port from infection_monkey.network.tools import check_tcp_port
from tools import build_monkey_commandline from infection_monkey.exploit.tools import build_monkey_commandline
__author__ = 'hoffer' __author__ = 'hoffer'
@ -237,8 +237,6 @@ class RdpExploiter(HostExploiter):
def __init__(self, host): def __init__(self, host):
super(RdpExploiter, self).__init__(host) super(RdpExploiter, self).__init__(host)
self._config = __import__('config').WormConfiguration
self._guid = __import__('config').GUID
def is_os_supported(self): def is_os_supported(self):
if super(RdpExploiter, self).is_os_supported(): if super(RdpExploiter, self).is_os_supported():

View File

@ -15,12 +15,12 @@ from impacket.smb3structs import SMB2_IL_IMPERSONATION, SMB2_CREATE, SMB2_FLAGS_
SMB2Packet, SMB2Create_Response, SMB2_OPLOCK_LEVEL_NONE SMB2Packet, SMB2Create_Response, SMB2_OPLOCK_LEVEL_NONE
from impacket.smbconnection import SMBConnection from impacket.smbconnection import SMBConnection
import monkeyfs import infection_monkey.monkeyfs as monkeyfs
from exploit import HostExploiter from infection_monkey.exploit import HostExploiter
from model import DROPPER_ARG from infection_monkey.model import DROPPER_ARG
from network.smbfinger import SMB_SERVICE from infection_monkey.network.smbfinger import SMB_SERVICE
from tools import build_monkey_commandline, get_target_monkey_by_os, get_monkey_depth from infection_monkey.exploit.tools import build_monkey_commandline, get_target_monkey_by_os, get_monkey_depth
from pyinstaller_utils import get_binary_file_path from infection_monkey.pyinstaller_utils import get_binary_file_path
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'
@ -53,7 +53,6 @@ class SambaCryExploiter(HostExploiter):
def __init__(self, host): def __init__(self, host):
super(SambaCryExploiter, self).__init__(host) super(SambaCryExploiter, self).__init__(host)
self._config = __import__('config').WormConfiguration
def exploit_host(self): def exploit_host(self):
if not self.is_vulnerable(): if not self.is_vulnerable():

View File

@ -6,11 +6,11 @@ from random import choice
import requests import requests
from exploit import HostExploiter from infection_monkey.exploit import HostExploiter
from exploit.tools import get_target_monkey, HTTPTools, get_monkey_depth from infection_monkey.exploit.tools import get_target_monkey, HTTPTools, get_monkey_depth
from model import DROPPER_ARG from infection_monkey.model import DROPPER_ARG
from shellshock_resources import CGI_FILES from infection_monkey.exploit.shellshock_resources import CGI_FILES
from tools import build_monkey_commandline from infection_monkey.exploit.tools import build_monkey_commandline
__author__ = 'danielg' __author__ = 'danielg'
@ -29,7 +29,6 @@ class ShellShockExploiter(HostExploiter):
def __init__(self, host): def __init__(self, host):
super(ShellShockExploiter, self).__init__(host) super(ShellShockExploiter, self).__init__(host)
self._config = __import__('config').WormConfiguration
self.HTTP = [str(port) for port in self._config.HTTP_PORTS] self.HTTP = [str(port) for port in self._config.HTTP_PORTS]
self.success_flag = ''.join( self.success_flag = ''.join(
choice(string.ascii_uppercase + string.digits choice(string.ascii_uppercase + string.digits

View File

@ -3,12 +3,12 @@ from logging import getLogger
from impacket.dcerpc.v5 import transport, scmr from impacket.dcerpc.v5 import transport, scmr
from impacket.smbconnection import SMB_DIALECT from impacket.smbconnection import SMB_DIALECT
from exploit import HostExploiter from infection_monkey.exploit import HostExploiter
from exploit.tools import SmbTools, get_target_monkey, get_monkey_depth from infection_monkey.exploit.tools import SmbTools, get_target_monkey, get_monkey_depth
from model import MONKEY_CMDLINE_DETACHED_WINDOWS, DROPPER_CMDLINE_DETACHED_WINDOWS from infection_monkey.model import MONKEY_CMDLINE_DETACHED_WINDOWS, DROPPER_CMDLINE_DETACHED_WINDOWS
from network import SMBFinger from infection_monkey.network import SMBFinger
from network.tools import check_tcp_port from infection_monkey.network.tools import check_tcp_port
from tools import build_monkey_commandline from infection_monkey.exploit.tools import build_monkey_commandline
LOG = getLogger(__name__) LOG = getLogger(__name__)
@ -23,8 +23,6 @@ class SmbExploiter(HostExploiter):
def __init__(self, host): def __init__(self, host):
super(SmbExploiter, self).__init__(host) super(SmbExploiter, self).__init__(host)
self._config = __import__('config').WormConfiguration
self._guid = __import__('config').GUID
def is_os_supported(self): def is_os_supported(self):
if super(SmbExploiter, self).is_os_supported(): if super(SmbExploiter, self).is_os_supported():

View File

@ -4,12 +4,12 @@ import time
import paramiko import paramiko
import StringIO import StringIO
import monkeyfs import infection_monkey.monkeyfs as monkeyfs
from exploit import HostExploiter from infection_monkey.exploit import HostExploiter
from exploit.tools import get_target_monkey, get_monkey_depth from infection_monkey.exploit.tools import get_target_monkey, get_monkey_depth
from model import MONKEY_ARG from infection_monkey.model import MONKEY_ARG
from network.tools import check_tcp_port from infection_monkey.network.tools import check_tcp_port
from tools import build_monkey_commandline from infection_monkey.exploit.tools import build_monkey_commandline
__author__ = 'hoffer' __author__ = 'hoffer'
@ -23,7 +23,6 @@ class SSHExploiter(HostExploiter):
def __init__(self, host): def __init__(self, host):
super(SSHExploiter, self).__init__(host) super(SSHExploiter, self).__init__(host)
self._config = __import__('config').WormConfiguration
self._update_timestamp = 0 self._update_timestamp = 0
self.skip_exist = self._config.skip_exploit_if_file_exist self.skip_exist = self._config.skip_exploit_if_file_exist

View File

@ -9,7 +9,7 @@ import unicodedata
import re import re
import logging import logging
from web_rce import WebRCE from infection_monkey.exploit.web_rce import WebRCE
__author__ = "VakarisZ" __author__ = "VakarisZ"

View File

@ -17,11 +17,12 @@ from impacket.dcerpc.v5.dtypes import NULL
from impacket.smb3structs import SMB2_DIALECT_002, SMB2_DIALECT_21 from impacket.smb3structs import SMB2_DIALECT_002, SMB2_DIALECT_21
from impacket.smbconnection import SMBConnection, SMB_DIALECT from impacket.smbconnection import SMBConnection, SMB_DIALECT
import monkeyfs import infection_monkey.config
from network import local_ips import infection_monkey.monkeyfs as monkeyfs
from network.firewall import app as firewall from infection_monkey.network import local_ips
from network.info import get_free_tcp_port, get_routes from infection_monkey.network.firewall import app as firewall
from transport import HTTPServer, LockedHTTPServer from infection_monkey.network.info import get_free_tcp_port, get_routes
from infection_monkey.transport import HTTPServer, LockedHTTPServer
from threading import Lock from threading import Lock
@ -174,8 +175,7 @@ class SmbTools(object):
@staticmethod @staticmethod
def copy_file(host, src_path, dst_path, username, password, lm_hash='', ntlm_hash='', timeout=60): def copy_file(host, src_path, dst_path, username, password, lm_hash='', ntlm_hash='', timeout=60):
assert monkeyfs.isfile(src_path), "Source file to copy (%s) is missing" % (src_path,) assert monkeyfs.isfile(src_path), "Source file to copy (%s) is missing" % (src_path,)
config = infection_monkey.config.WormConfiguration
config = __import__('config').WormConfiguration
src_file_size = monkeyfs.getsize(src_path) src_file_size = monkeyfs.getsize(src_path)
smb, dialect = SmbTools.new_smb_connection(host, username, password, lm_hash, ntlm_hash, timeout) smb, dialect = SmbTools.new_smb_connection(host, username, password, lm_hash, ntlm_hash, timeout)
@ -445,7 +445,7 @@ def get_interface_to_target(dst):
def get_target_monkey(host): def get_target_monkey(host):
from control import ControlClient from infection_monkey.control import ControlClient
import platform import platform
import sys import sys
@ -471,7 +471,7 @@ def get_target_monkey(host):
def get_target_monkey_by_os(is_windows, is_32bit): def get_target_monkey_by_os(is_windows, is_32bit):
from control import ControlClient from infection_monkey.control import ControlClient
return ControlClient.download_monkey_exe_by_os(is_windows, is_32bit) return ControlClient.download_monkey_exe_by_os(is_windows, is_32bit)
@ -495,13 +495,13 @@ def build_monkey_commandline_explicitly(parent=None, tunnel=None, server=None, d
def build_monkey_commandline(target_host, depth, location=None): def build_monkey_commandline(target_host, depth, location=None):
from config import GUID from infection_monkey.config import GUID
return build_monkey_commandline_explicitly( return build_monkey_commandline_explicitly(
GUID, target_host.default_tunnel, target_host.default_server, depth, location) GUID, target_host.default_tunnel, target_host.default_server, depth, location)
def get_monkey_depth(): def get_monkey_depth():
from config import WormConfiguration from infection_monkey.config import WormConfiguration
return WormConfiguration.depth return WormConfiguration.depth
@ -511,7 +511,7 @@ def get_monkey_dest_path(url_to_monkey):
:param url_to_monkey: Hosted monkey's url. egz : http://localserver:9999/monkey/windows-32.exe :param url_to_monkey: Hosted monkey's url. egz : http://localserver:9999/monkey/windows-32.exe
:return: Corresponding monkey path from configuration :return: Corresponding monkey path from configuration
""" """
from config import WormConfiguration from infection_monkey.config import WormConfiguration
if not url_to_monkey or ('linux' not in url_to_monkey and 'windows' not in url_to_monkey): if not url_to_monkey or ('linux' not in url_to_monkey and 'windows' not in url_to_monkey):
LOG.error("Can't get destination path because source path %s is invalid.", url_to_monkey) LOG.error("Can't get destination path because source path %s is invalid.", url_to_monkey)
return False return False

View File

@ -1,12 +1,12 @@
import logging import logging
from exploit import HostExploiter
from model import *
from posixpath import join
import re import re
from posixpath import join
from abc import abstractmethod from abc import abstractmethod
from exploit.tools import get_target_monkey, get_monkey_depth, build_monkey_commandline, HTTPTools
from network.tools import check_tcp_port, tcp_port_to_service from infection_monkey.exploit import HostExploiter
from infection_monkey.model import *
from infection_monkey.exploit.tools import get_target_monkey, get_monkey_depth, build_monkey_commandline, HTTPTools
from infection_monkey.network.tools import check_tcp_port, tcp_port_to_service
__author__ = 'VakarisZ' __author__ = 'VakarisZ'

View File

@ -7,8 +7,8 @@
# CVE: CVE-2017-10271 # CVE: CVE-2017-10271
from requests import post, exceptions from requests import post, exceptions
from web_rce import WebRCE from infection_monkey.exploit.web_rce import WebRCE
from exploit.tools import get_free_tcp_port, get_interface_to_target from infection_monkey.exploit.tools import get_free_tcp_port, get_interface_to_target
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import threading import threading

View File

@ -14,11 +14,11 @@ from enum import IntEnum
from impacket import uuid from impacket import uuid
from impacket.dcerpc.v5 import transport from impacket.dcerpc.v5 import transport
from exploit.tools import SmbTools, get_target_monkey, get_monkey_depth from infection_monkey.exploit.tools import SmbTools, get_target_monkey, get_monkey_depth
from model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS from infection_monkey.model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS
from network import SMBFinger from infection_monkey.network import SMBFinger
from network.tools import check_tcp_port from infection_monkey.network.tools import check_tcp_port
from tools import build_monkey_commandline from infection_monkey.exploit.tools import build_monkey_commandline
from . import HostExploiter from . import HostExploiter
LOG = getLogger(__name__) LOG = getLogger(__name__)
@ -158,8 +158,6 @@ class Ms08_067_Exploiter(HostExploiter):
def __init__(self, host): def __init__(self, host):
super(Ms08_067_Exploiter, self).__init__(host) super(Ms08_067_Exploiter, self).__init__(host)
self._config = __import__('config').WormConfiguration
self._guid = __import__('config').GUID
def is_os_supported(self): def is_os_supported(self):
if self.host.os.get('type') in self._TARGET_OS_TYPE and \ if self.host.os.get('type') in self._TARGET_OS_TYPE and \

View File

@ -5,10 +5,10 @@ import traceback
from impacket.dcerpc.v5.rpcrt import DCERPCException from impacket.dcerpc.v5.rpcrt import DCERPCException
from exploit import HostExploiter from infection_monkey.exploit import HostExploiter
from exploit.tools import SmbTools, WmiTools, AccessDeniedException, get_target_monkey, get_monkey_depth from infection_monkey.exploit.tools import SmbTools, WmiTools, AccessDeniedException, get_target_monkey, \
from model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS get_monkey_depth, build_monkey_commandline
from tools import build_monkey_commandline from infection_monkey.model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -18,8 +18,6 @@ class WmiExploiter(HostExploiter):
def __init__(self, host): def __init__(self, host):
super(WmiExploiter, self).__init__(host) super(WmiExploiter, self).__init__(host)
self._config = __import__('config').WormConfiguration
self._guid = __import__('config').GUID
@WmiTools.dcom_wrap @WmiTools.dcom_wrap
def exploit_host(self): def exploit_host(self):

View File

@ -8,14 +8,11 @@ import os
import sys import sys
import traceback import traceback
from config import WormConfiguration, EXTERNAL_CONFIG_FILE import infection_monkey.utils as utils
from dropper import MonkeyDrops from infection_monkey.config import WormConfiguration, EXTERNAL_CONFIG_FILE
from model import MONKEY_ARG, DROPPER_ARG from infection_monkey.dropper import MonkeyDrops
from monkey import InfectionMonkey from infection_monkey.model import MONKEY_ARG, DROPPER_ARG
import utils from infection_monkey.monkey import InfectionMonkey
if __name__ == "__main__":
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
__author__ = 'itamar' __author__ = 'itamar'
@ -63,7 +60,7 @@ def main():
try: try:
with open(config_file) as config_fo: with open(config_file) as config_fo:
json_dict = json.load(config_fo) json_dict = json.load(config_fo)
WormConfiguration.from_dict(json_dict) WormConfiguration.from_kv(json_dict)
except ValueError as e: except ValueError as e:
print("Error loading config: %s, using default" % (e,)) print("Error loading config: %s, using default" % (e,))
else: else:

View File

@ -1,4 +1,4 @@
from host import VictimHost from infection_monkey.model.host import VictimHost
__author__ = 'itamar' __author__ = 'itamar'

View File

@ -4,7 +4,7 @@ block_cipher = None
a = Analysis(['main.py'], a = Analysis(['main.py'],
pathex=['.', '..'], pathex=['..'],
binaries=None, binaries=None,
datas=None, datas=None,
hiddenimports=['_cffi_backend'], hiddenimports=['_cffi_backend'],

View File

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View File

@ -4,18 +4,18 @@ import os
import subprocess import subprocess
import sys import sys
import time import time
import tunnel
import utils
from config import WormConfiguration
from control import ControlClient
from model import DELAY_DELETE_CMD
from network.firewall import app as firewall
from network.network_scanner import NetworkScanner
from six.moves import xrange from six.moves import xrange
from system_info import SystemInfoCollector
from system_singleton import SystemSingleton import infection_monkey.tunnel as tunnel
from windows_upgrader import WindowsUpgrader import infection_monkey.utils as utils
from infection_monkey.config import WormConfiguration
from infection_monkey.control import ControlClient
from infection_monkey.model import DELAY_DELETE_CMD
from infection_monkey.network.firewall import app as firewall
from infection_monkey.network.network_scanner import NetworkScanner
from infection_monkey.system_info import SystemInfoCollector
from infection_monkey.system_singleton import SystemSingleton
from infection_monkey.windows_upgrader import WindowsUpgrader
__author__ = 'itamar' __author__ = 'itamar'

View File

@ -14,7 +14,7 @@ def get_mimikatz_zip_path():
a = Analysis(['main.py'], a = Analysis(['main.py'],
pathex=['.', '..'], pathex=['..'],
hiddenimports=['_cffi_backend', 'queue'], hiddenimports=['_cffi_backend', 'queue'],
hookspath=None, hookspath=None,
runtime_hooks=None) runtime_hooks=None)

View File

@ -0,0 +1,29 @@
from abc import ABCMeta, abstractmethod
__author__ = 'itamar'
class HostScanner(object):
__metaclass__ = ABCMeta
@abstractmethod
def is_host_alive(self, host):
raise NotImplementedError()
class HostFinger(object):
__metaclass__ = ABCMeta
@abstractmethod
def get_host_fingerprint(self, host):
raise NotImplementedError()
from infection_monkey.network.ping_scanner import PingScanner
from infection_monkey.network.tcp_scanner import TcpScanner
from infection_monkey.network.smbfinger import SMBFinger
from infection_monkey.network.sshfinger import SSHFinger
from infection_monkey.network.httpfinger import HTTPFinger
from infection_monkey.network.elasticfinger import ElasticFinger
from infection_monkey.network.mysqlfinger import MySQLFinger
from infection_monkey.network.info import local_ips, get_free_tcp_port
from infection_monkey.network.mssql_fingerprint import MSSQLFinger

View File

@ -5,8 +5,9 @@ from contextlib import closing
import requests import requests
from requests.exceptions import Timeout, ConnectionError from requests.exceptions import Timeout, ConnectionError
from model.host import VictimHost import infection_monkey.config
from network import HostFinger from infection_monkey.model.host import VictimHost
from infection_monkey.network import HostFinger
ES_PORT = 9200 ES_PORT = 9200
ES_SERVICE = 'elastic-search-9200' ES_SERVICE = 'elastic-search-9200'
@ -21,7 +22,7 @@ class ElasticFinger(HostFinger):
""" """
def __init__(self): def __init__(self):
self._config = __import__('config').WormConfiguration self._config = infection_monkey.config.WormConfiguration
def get_host_fingerprint(self, host): def get_host_fingerprint(self, host):
""" """

View File

@ -1,16 +1,18 @@
from network import HostFinger import infection_monkey.config
from model.host import VictimHost from infection_monkey.network import HostFinger
from infection_monkey.model.host import VictimHost
import logging import logging
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class HTTPFinger(HostFinger): class HTTPFinger(HostFinger):
""" """
Goal is to recognise HTTP servers, where what we currently care about is apache. Goal is to recognise HTTP servers, where what we currently care about is apache.
""" """
def __init__(self): def __init__(self):
self._config = __import__('config').WormConfiguration self._config = infection_monkey.config.WormConfiguration
self.HTTP = [(port, str(port)) for port in self._config.HTTP_PORTS] self.HTTP = [(port, str(port)) for port in self._config.HTTP_PORTS]
@staticmethod @staticmethod

View File

@ -1,8 +1,9 @@
import logging import logging
import socket import socket
from model.host import VictimHost from infection_monkey.model.host import VictimHost
from network import HostFinger from infection_monkey.network import HostFinger
import infection_monkey.config
__author__ = 'Maor Rayzin' __author__ = 'Maor Rayzin'
@ -18,7 +19,7 @@ class MSSQLFinger(HostFinger):
SERVICE_NAME = 'MSSQL' SERVICE_NAME = 'MSSQL'
def __init__(self): def __init__(self):
self._config = __import__('config').WormConfiguration self._config = infection_monkey.config.WormConfiguration
def get_host_fingerprint(self, host): def get_host_fingerprint(self, host):
"""Gets Microsoft SQL Server instance information by querying the SQL Browser service. """Gets Microsoft SQL Server instance information by querying the SQL Browser service.

View File

@ -1,9 +1,10 @@
import logging import logging
import socket import socket
from model.host import VictimHost import infection_monkey.config
from network import HostFinger from infection_monkey.model.host import VictimHost
from .tools import struct_unpack_tracker, struct_unpack_tracker_string from infection_monkey.network import HostFinger
from infection_monkey.network.tools import struct_unpack_tracker, struct_unpack_tracker_string
MYSQL_PORT = 3306 MYSQL_PORT = 3306
SQL_SERVICE = 'mysqld-3306' SQL_SERVICE = 'mysqld-3306'
@ -20,7 +21,7 @@ class MySQLFinger(HostFinger):
HEADER_SIZE = 4 # in bytes HEADER_SIZE = 4 # in bytes
def __init__(self): def __init__(self):
self._config = __import__('config').WormConfiguration self._config = infection_monkey.config.WormConfiguration
def get_host_fingerprint(self, host): def get_host_fingerprint(self, host):
""" """

View File

@ -1,11 +1,11 @@
import logging import logging
import time import time
from config import WormConfiguration
from info import local_ips, get_interfaces_ranges
from common.network.network_range import * from common.network.network_range import *
from model import VictimHost from infection_monkey.config import WormConfiguration
from . import HostScanner from infection_monkey.network.info import local_ips, get_interfaces_ranges
from infection_monkey.model import VictimHost
from infection_monkey.network import HostScanner
__author__ = 'itamar' __author__ = 'itamar'
@ -63,7 +63,15 @@ class NetworkScanner(object):
return subnets_to_scan return subnets_to_scan
def get_victim_machines(self, scan_type, max_find=5, stop_callback=None): def get_victim_machines(self, scan_type, max_find=5, stop_callback=None):
assert issubclass(scan_type, HostScanner) """
Finds machines according to the ranges specified in the object
:param scan_type: A hostscanner class, will be instanced and used to scan for new machines
:param max_find: Max number of victims to find regardless of ranges
:param stop_callback: A callback to check at any point if we should stop scanning
:return: yields a sequence of VictimHost instances
"""
if not scan_type:
return
scanner = scan_type() scanner = scan_type()
victims_count = 0 victims_count = 0

View File

@ -4,8 +4,9 @@ import re
import subprocess import subprocess
import sys import sys
from model.host import VictimHost import infection_monkey.config
from . import HostScanner, HostFinger from infection_monkey.model.host import VictimHost
from infection_monkey.network import HostScanner, HostFinger
__author__ = 'itamar' __author__ = 'itamar'
@ -20,7 +21,7 @@ LOG = logging.getLogger(__name__)
class PingScanner(HostScanner, HostFinger): class PingScanner(HostScanner, HostFinger):
def __init__(self): def __init__(self):
self._config = __import__('config').WormConfiguration self._config = infection_monkey.config.WormConfiguration
self._devnull = open(os.devnull, "w") self._devnull = open(os.devnull, "w")
self._ttl_regex = re.compile(TTL_REGEX_STR, re.IGNORECASE) self._ttl_regex = re.compile(TTL_REGEX_STR, re.IGNORECASE)

View File

@ -1,10 +1,11 @@
import socket import socket
import struct import struct
import logging import logging
from network import HostFinger
from model.host import VictimHost
from odict import odict from odict import odict
from infection_monkey.network import HostFinger
from infection_monkey.model.host import VictimHost
SMB_PORT = 445 SMB_PORT = 445
SMB_SERVICE = 'tcp-445' SMB_SERVICE = 'tcp-445'
@ -100,7 +101,8 @@ class SMBSessionFingerData(Packet):
class SMBFinger(HostFinger): class SMBFinger(HostFinger):
def __init__(self): def __init__(self):
self._config = __import__('config').WormConfiguration from infection_monkey.config import WormConfiguration
self._config = WormConfiguration
def get_host_fingerprint(self, host): def get_host_fingerprint(self, host):
assert isinstance(host, VictimHost) assert isinstance(host, VictimHost)

View File

@ -1,8 +1,9 @@
import re import re
from model.host import VictimHost import infection_monkey.config
from network import HostFinger from infection_monkey.model.host import VictimHost
from network.tools import check_tcp_port from infection_monkey.network import HostFinger
from infection_monkey.network.tools import check_tcp_port
SSH_PORT = 22 SSH_PORT = 22
SSH_SERVICE_DEFAULT = 'tcp-22' SSH_SERVICE_DEFAULT = 'tcp-22'
@ -14,7 +15,7 @@ LINUX_DIST_SSH = ['ubuntu', 'debian']
class SSHFinger(HostFinger): class SSHFinger(HostFinger):
def __init__(self): def __init__(self):
self._config = __import__('config').WormConfiguration self._config = infection_monkey.config.WormConfiguration
self._banner_regex = re.compile(SSH_REGEX, re.IGNORECASE) self._banner_regex = re.compile(SSH_REGEX, re.IGNORECASE)
@staticmethod @staticmethod

View File

@ -1,8 +1,9 @@
from itertools import izip_longest from itertools import izip_longest
from random import shuffle from random import shuffle
from network import HostScanner, HostFinger import infection_monkey.config
from network.tools import check_tcp_ports, tcp_port_to_service from infection_monkey.network import HostScanner, HostFinger
from infection_monkey.network.tools import check_tcp_ports, tcp_port_to_service
__author__ = 'itamar' __author__ = 'itamar'
@ -11,7 +12,7 @@ BANNER_READ = 1024
class TcpScanner(HostScanner, HostFinger): class TcpScanner(HostScanner, HostFinger):
def __init__(self): def __init__(self):
self._config = __import__('config').WormConfiguration self._config = infection_monkey.config.WormConfiguration
def is_host_alive(self, host): def is_host_alive(self, host):
return self.get_host_fingerprint(host, True) return self.get_host_fingerprint(host, True)

View File

@ -5,8 +5,8 @@ import sys
import psutil import psutil
from enum import IntEnum from enum import IntEnum
from network.info import get_host_subnets from infection_monkey.network.info import get_host_subnets
from azure_cred_collector import AzureCollector from infection_monkey.system_info.azure_cred_collector import AzureCollector
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -112,7 +112,7 @@ class InfoCollector(object):
Updates the credentials structure, creating it if neccesary (compat with mimikatz) Updates the credentials structure, creating it if neccesary (compat with mimikatz)
:return: None. Updates class information :return: None. Updates class information
""" """
from config import WormConfiguration from infection_monkey.config import WormConfiguration
if not WormConfiguration.extract_azure_creds: if not WormConfiguration.extract_azure_creds:
return return
LOG.debug("Harvesting creds if on an Azure machine") LOG.debug("Harvesting creds if on an Azure machine")

View File

@ -1,7 +1,7 @@
import logging import logging
from . import InfoCollector from infection_monkey.system_info import InfoCollector
from SSH_info_collector import SSHCollector from infection_monkey.system_info.SSH_info_collector import SSHCollector
__author__ = 'uri' __author__ = 'uri'

View File

@ -4,7 +4,9 @@ import logging
import socket import socket
import zipfile import zipfile
from pyinstaller_utils import get_binary_file_path, get_binaries_dir_path import infection_monkey.config
from infection_monkey.pyinstaller_utils import get_binary_file_path, get_binaries_dir_path
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'
@ -26,7 +28,7 @@ class MimikatzCollector(object):
MIMIKATZ_ZIP_PASSWORD = r'VTQpsJPXgZuXhX6x3V84G' MIMIKATZ_ZIP_PASSWORD = r'VTQpsJPXgZuXhX6x3V84G'
def __init__(self): def __init__(self):
self._config = __import__('config').WormConfiguration self._config = infection_monkey.config.WormConfiguration
self._isInit = False self._isInit = False
self._dll = None self._dll = None
self._collect = None self._collect = None

View File

@ -1,7 +1,8 @@
import logging import logging
from mimikatz_collector import MimikatzCollector import infection_monkey.config
from . import InfoCollector from infection_monkey.system_info.mimikatz_collector import MimikatzCollector
from infection_monkey.system_info import InfoCollector
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -15,7 +16,7 @@ class WindowsInfoCollector(InfoCollector):
def __init__(self): def __init__(self):
super(WindowsInfoCollector, self).__init__() super(WindowsInfoCollector, self).__init__()
self._config = __import__('config').WormConfiguration self._config = infection_monkey.config.WormConfiguration
def get_info(self): def get_info(self):
""" """

View File

@ -3,7 +3,7 @@ import logging
import sys import sys
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
from config import WormConfiguration from infection_monkey.config import WormConfiguration
__author__ = 'itamar' __author__ = 'itamar'

View File

@ -0,0 +1,4 @@
from infection_monkey.transport.http import HTTPServer, LockedHTTPServer
__author__ = 'hoffer'

View File

@ -3,6 +3,7 @@ from threading import Thread
g_last_served = None g_last_served = None
class TransportProxyBase(Thread): class TransportProxyBase(Thread):
def __init__(self, local_port, dest_host=None, dest_port=None, local_host=''): def __init__(self, local_port, dest_host=None, dest_port=None, local_host=''):
global g_last_served global g_last_served

View File

@ -8,8 +8,8 @@ from logging import getLogger
from urlparse import urlsplit from urlparse import urlsplit
from threading import Lock from threading import Lock
import monkeyfs import infection_monkey.monkeyfs as monkeyfs
from base import TransportProxyBase, update_last_serve_time from infection_monkey.transport.base import TransportProxyBase, update_last_serve_time
__author__ = 'hoffer' __author__ = 'hoffer'

View File

@ -1,9 +1,10 @@
import socket import socket
import select import select
from threading import Thread from threading import Thread
from base import TransportProxyBase, update_last_serve_time
from logging import getLogger from logging import getLogger
from infection_monkey.transport.base import TransportProxyBase, update_last_serve_time
READ_BUFFER_SIZE = 8192 READ_BUFFER_SIZE = 8192
DEFAULT_TIMEOUT = 30 DEFAULT_TIMEOUT = 30

View File

@ -5,11 +5,11 @@ import time
from difflib import get_close_matches from difflib import get_close_matches
from threading import Thread from threading import Thread
from model import VictimHost from infection_monkey.model import VictimHost
from network.firewall import app as firewall from infection_monkey.network.firewall import app as firewall
from network.info import local_ips, get_free_tcp_port from infection_monkey.network.info import local_ips, get_free_tcp_port
from network.tools import check_tcp_port from infection_monkey.network.tools import check_tcp_port
from transport.base import get_last_serve_time from infection_monkey.transport.base import get_last_serve_time
__author__ = 'hoffer' __author__ = 'hoffer'

View File

@ -2,7 +2,7 @@ import os
import sys import sys
import struct import struct
from config import WormConfiguration from infection_monkey.config import WormConfiguration
def get_monkey_log_path(): def get_monkey_log_path():

View File

@ -5,12 +5,12 @@ import shutil
import time import time
import monkeyfs import infection_monkey.monkeyfs as monkeyfs
from config import WormConfiguration from infection_monkey.config import WormConfiguration
from control import ControlClient from infection_monkey.control import ControlClient
from exploit.tools import build_monkey_commandline_explicitly from infection_monkey.exploit.tools import build_monkey_commandline_explicitly
from model import MONKEY_CMDLINE_WINDOWS from infection_monkey.model import MONKEY_CMDLINE_WINDOWS
from utils import is_windows_os, is_64bit_windows_os, is_64bit_python from infection_monkey.utils import is_windows_os, is_64bit_windows_os, is_64bit_python
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'

4
monkey/monkey_island.py Normal file
View File

@ -0,0 +1,4 @@
import monkey_island.cc.main
if "__main__" == __name__:
monkey_island.cc.main.main()

View File

@ -0,0 +1 @@
__author__ = 'itay.mizeretz'

View File

@ -4,7 +4,7 @@ from datetime import datetime
import bson import bson
import flask_restful import flask_restful
from bson.json_util import dumps from bson.json_util import dumps
from flask import Flask, send_from_directory, make_response from flask import Flask, send_from_directory, make_response, Response
from werkzeug.exceptions import NotFound from werkzeug.exceptions import NotFound
from cc.auth import init_jwt from cc.auth import init_jwt
@ -29,18 +29,24 @@ from cc.services.config import ConfigService
__author__ = 'Barak' __author__ = 'Barak'
HOME_FILE = 'index.html'
def serve_static_file(static_path): def serve_static_file(static_path):
if static_path.startswith('api/'): if static_path.startswith('api/'):
raise NotFound() raise NotFound()
try: try:
return send_from_directory('ui/dist', static_path) return send_from_directory(os.path.join(os.getcwd(), 'monkey_island/cc/ui/dist'), static_path)
except NotFound: except NotFound:
# Because react uses various urls for same index page, this is probably the user's intention. # Because react uses various urls for same index page, this is probably the user's intention.
if static_path == HOME_FILE:
flask_restful.abort(
Response("Page not found. Make sure you ran the npm script and the cwd is monkey\\monkey.", 500))
return serve_home() return serve_home()
def serve_home(): def serve_home():
return serve_static_file('index.html') return serve_static_file(HOME_FILE)
def normalize_obj(obj): def normalize_obj(obj):

View File

@ -9,7 +9,7 @@ __author__ = "itay.mizeretz"
class Encryptor: class Encryptor:
_BLOCK_SIZE = 32 _BLOCK_SIZE = 32
_DB_PASSWORD_FILENAME = "mongo_key.bin" _DB_PASSWORD_FILENAME = "monkey_island/cc/mongo_key.bin"
def __init__(self): def __init__(self):
self._load_key() self._load_key()

View File

@ -13,7 +13,7 @@ ENV_DICT = {
def load_env_from_file(): def load_env_from_file():
with open('server_config.json', 'r') as f: with open('monkey_island/cc/server_config.json', 'r') as f:
config_content = f.read() config_content = f.read()
config_json = json.loads(config_content) config_json = json.loads(config_content)
return config_json['server_config'] return config_json['server_config']

View File

@ -6,10 +6,6 @@ import time
import logging import logging
BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PARENT_PATH = os.path.dirname(BASE_PATH)
if PARENT_PATH not in sys.path:
sys.path.insert(0, PARENT_PATH)
if BASE_PATH not in sys.path: if BASE_PATH not in sys.path:
sys.path.insert(0, BASE_PATH) sys.path.insert(0, BASE_PATH)
@ -38,11 +34,11 @@ def main():
app = init_app(mongo_url) app = init_app(mongo_url)
if env.is_debug(): if env.is_debug():
app.run(host='0.0.0.0', debug=True, ssl_context=('server.crt', 'server.key')) app.run(host='0.0.0.0', debug=True, ssl_context=('monkey_island/cc/server.crt', 'monkey_island/cc/server.key'))
else: else:
http_server = HTTPServer(WSGIContainer(app), http_server = HTTPServer(WSGIContainer(app),
ssl_options={'certfile': os.environ.get('SERVER_CRT', 'server.crt'), ssl_options={'certfile': os.environ.get('SERVER_CRT', 'monkey_island/cc/server.crt'),
'keyfile': os.environ.get('SERVER_KEY', 'server.key')}) 'keyfile': os.environ.get('SERVER_KEY', 'monkey_island/cc/server.key')})
http_server.listen(env.get_island_port()) http_server.listen(env.get_island_port())
logger.info( logger.info(
'Monkey Island Server is running on https://{}:{}'.format(local_ip_addresses()[0], env.get_island_port())) 'Monkey Island Server is running on https://{}:{}'.format(local_ip_addresses()[0], env.get_island_port()))

View File

@ -26,8 +26,8 @@ def run_local_monkey():
if not result: if not result:
return False, "OS Type not found" return False, "OS Type not found"
monkey_path = os.path.join('binaries', result['filename']) monkey_path = os.path.join(os.getcwd(), 'monkey_island', 'cc', 'binaries', result['filename'])
target_path = os.path.join(os.getcwd(), result['filename']) target_path = os.path.join(os.getcwd(), 'monkey_island', result['filename'])
# copy the executable to temp path (don't run the monkey from its current location as it may delete itself) # copy the executable to temp path (don't run the monkey from its current location as it may delete itself)
try: try:

Some files were not shown because too many files have changed in this diff Show More