Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
Daniel Goldberg 2020-03-05 19:46:29 +02:00
commit 05c5b856f0
17 changed files with 92 additions and 19 deletions

1
monkey/common/BUILD Normal file
View File

@ -0,0 +1 @@
dev

25
monkey/common/version.py Normal file
View File

@ -0,0 +1,25 @@
# To get the version from shell, run `python ./version.py` (see `python ./version.py -h` for details).
import argparse
from pathlib import Path
MAJOR = "1"
MINOR = "8"
PATCH = "0"
build_file_path = Path(__file__).parent.joinpath("BUILD")
with open(build_file_path, "r") as build_file:
BUILD = build_file.read()
def get_version(build=BUILD):
return f"{MAJOR}.{MINOR}.{PATCH}+{build}"
def print_version():
parser = argparse.ArgumentParser()
parser.add_argument("-b", "--build", default=BUILD, help="Choose the build string for this version.", type=str)
args = parser.parse_args()
print(get_version(args.build))
if __name__ == '__main__':
print_version()

View File

@ -1,2 +1,17 @@
#!/bin/bash #!/bin/bash
# Allow custom build ID
# If the first argument is not empty...
if [[ -n "$1" ]]
then
# Validate argument is a valid build string
if [[ "$1" =~ ^[\da-zA-Z]*$ ]]
then
# And put it in the BUILD file
echo "$1" > ../common/BUILD
else
echo "Build ID $1 invalid!"
fi
fi
pyinstaller -F --log-level=DEBUG --clean monkey.spec pyinstaller -F --log-level=DEBUG --clean monkey.spec

View File

@ -1 +1,12 @@
REM Check if build ID was passed to the build script.
if "%1"=="" GOTO START_BUILD
REM Validate build ID
echo %1|findstr /r "^[0-9a-zA-Z]*$"
if %errorlevel% neq 0 (exit /b %errorlevel%)
REM replace build ID
echo %1> ../common/BUILD
:START_BUILD
pyinstaller -F --log-level=DEBUG --clean --upx-dir=.\bin monkey.spec pyinstaller -F --log-level=DEBUG --clean --upx-dir=.\bin monkey.spec

View File

@ -12,6 +12,7 @@ from infection_monkey.config import WormConfiguration, EXTERNAL_CONFIG_FILE
from infection_monkey.dropper import MonkeyDrops from infection_monkey.dropper import MonkeyDrops
from infection_monkey.model import MONKEY_ARG, DROPPER_ARG from infection_monkey.model import MONKEY_ARG, DROPPER_ARG
from infection_monkey.monkey import InfectionMonkey from infection_monkey.monkey import InfectionMonkey
from common.version import get_version
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
import infection_monkey.post_breach # dummy import for pyinstaller import infection_monkey.post_breach # dummy import for pyinstaller
@ -117,6 +118,8 @@ def main():
LOG.info(">>>>>>>>>> Initializing monkey (%s): PID %s <<<<<<<<<<", LOG.info(">>>>>>>>>> Initializing monkey (%s): PID %s <<<<<<<<<<",
monkey_cls.__name__, os.getpid()) monkey_cls.__name__, os.getpid())
LOG.info(f"version: {get_version()}")
monkey = monkey_cls(monkey_args) monkey = monkey_cls(monkey_args)
monkey.initialize() monkey.initialize()

View File

@ -30,6 +30,7 @@ from infection_monkey.network.tools import get_interface_to_target
from infection_monkey.exploit.tools.exceptions import ExploitingVulnerableMachineError, FailedExploitationError from infection_monkey.exploit.tools.exceptions import ExploitingVulnerableMachineError, FailedExploitationError
from infection_monkey.telemetry.attack.t1106_telem import T1106Telem from infection_monkey.telemetry.attack.t1106_telem import T1106Telem
from common.utils.attack_utils import ScanStatus, UsageEnum from common.utils.attack_utils import ScanStatus, UsageEnum
from common.version import get_version
from infection_monkey.exploit.HostExploiter import HostExploiter from infection_monkey.exploit.HostExploiter import HostExploiter
MAX_DEPTH_REACHED_MESSAGE = "Reached max depth, shutting down" MAX_DEPTH_REACHED_MESSAGE = "Reached max depth, shutting down"
@ -121,7 +122,7 @@ class InfectionMonkey(object):
if monkey_tunnel: if monkey_tunnel:
monkey_tunnel.start() monkey_tunnel.start()
StateTelem(is_done=False).send() StateTelem(is_done=False, version=get_version()).send()
TunnelTelem().send() TunnelTelem().send()
LOG.debug("Starting the post-breach phase.") LOG.debug("Starting the post-breach phase.")
@ -254,7 +255,7 @@ class InfectionMonkey(object):
InfectionMonkey.close_tunnel() InfectionMonkey.close_tunnel()
firewall.close() firewall.close()
else: else:
StateTelem(is_done=True).send() # Signal the server (before closing the tunnel) StateTelem(is_done=True, version=get_version()).send() # Signal the server (before closing the tunnel)
InfectionMonkey.close_tunnel() InfectionMonkey.close_tunnel()
firewall.close() firewall.close()
if WormConfiguration.send_log_to_server: if WormConfiguration.send_log_to_server:

View File

@ -19,7 +19,9 @@ def main():
hookspath=['./pyinstaller_hooks'], hookspath=['./pyinstaller_hooks'],
runtime_hooks=None, runtime_hooks=None,
binaries=None, binaries=None,
datas=None, datas=[
("../common/BUILD", "/common")
],
excludes=None, excludes=None,
win_no_prefer_redirects=None, win_no_prefer_redirects=None,
win_private_assemblies=None, win_private_assemblies=None,

View File

@ -5,15 +5,19 @@ __author__ = "itay.mizeretz"
class StateTelem(BaseTelem): class StateTelem(BaseTelem):
def __init__(self, is_done): def __init__(self, is_done, version="Unknown"):
""" """
Default state telemetry constructor Default state telemetry constructor
:param is_done: Whether the state of monkey is done. :param is_done: Whether the state of monkey is done.
""" """
super(StateTelem, self).__init__() super(StateTelem, self).__init__()
self.is_done = is_done self.is_done = is_done
self.version = version
telem_category = 'state' telem_category = 'state'
def get_data(self): def get_data(self):
return {'done': self.is_done} return {
'done': self.is_done,
'version': self.version
}

View File

@ -26,8 +26,6 @@ class Environment(object, metaclass=ABCMeta):
def testing(self, value): def testing(self, value):
self._testing = value self._testing = value
_MONKEY_VERSION = "1.7.0"
def __init__(self): def __init__(self):
self.config = None self.config = None
self._testing = False # Assume env is not for unit testing. self._testing = False # Assume env is not for unit testing.
@ -58,9 +56,6 @@ class Environment(object, metaclass=ABCMeta):
def is_develop(self): def is_develop(self):
return self.get_deployment() == 'develop' return self.get_deployment() == 'develop'
def get_version(self):
return self._MONKEY_VERSION + ('-dev' if self.is_develop() else '')
def _get_from_config(self, key, default_value=None): def _get_from_config(self, key, default_value=None):
val = default_value val = default_value
if self.config is not None: if self.config is not None:

View File

@ -25,6 +25,7 @@ from monkey_island.cc.utils import local_ip_addresses
from monkey_island.cc.environment.environment import env from monkey_island.cc.environment.environment import env
from monkey_island.cc.database import is_db_server_up, get_db_version from monkey_island.cc.database import is_db_server_up, get_db_version
from monkey_island.cc.resources.monkey_download import MonkeyDownload from monkey_island.cc.resources.monkey_download import MonkeyDownload
from common.version import get_version
def main(): def main():
@ -54,8 +55,9 @@ def main():
def log_init_info(): def log_init_info():
logger.info( logger.info('Monkey Island Server is running!')
'Monkey Island Server is running. Listening on the following URLs: {}'.format( logger.info(f"version: {get_version()}")
logger.info('Listening on the following URLs: {}'.format(
", ".join(["https://{}:{}".format(x, env.get_island_port()) for x in local_ip_addresses()]) ", ".join(["https://{}:{}".format(x, env.get_island_port()) for x in local_ip_addresses()])
) )
) )

View File

@ -1,7 +1,7 @@
import flask_restful import flask_restful
import logging import logging
from monkey_island.cc.environment.environment import env from common.version import get_version
from monkey_island.cc.services.version_update import VersionUpdateService from monkey_island.cc.services.version_update import VersionUpdateService
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'
@ -17,7 +17,7 @@ class VersionUpdate(flask_restful.Resource):
# even when not authenticated # even when not authenticated
def get(self): def get(self):
return { return {
'current_version': env.get_version(), 'current_version': get_version(),
'newer_version': VersionUpdateService.get_newer_version(), 'newer_version': VersionUpdateService.get_newer_version(),
'download_link': VersionUpdateService.get_download_link() 'download_link': VersionUpdateService.get_download_link()
} }

View File

@ -1,9 +1,14 @@
import logging
from monkey_island.cc.models import Monkey from monkey_island.cc.models import Monkey
from monkey_island.cc.services.node import NodeService from monkey_island.cc.services.node import NodeService
from monkey_island.cc.services.telemetry.zero_trust_tests.segmentation import \ from monkey_island.cc.services.telemetry.zero_trust_tests.segmentation import \
test_passed_findings_for_unreached_segments test_passed_findings_for_unreached_segments
logger = logging.getLogger(__name__)
def process_state_telemetry(telemetry_json): def process_state_telemetry(telemetry_json):
monkey = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid']) monkey = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])
NodeService.add_communication_info(monkey, telemetry_json['command_control_channel']) NodeService.add_communication_info(monkey, telemetry_json['command_control_channel'])
@ -15,3 +20,6 @@ def process_state_telemetry(telemetry_json):
if telemetry_json['data']['done']: if telemetry_json['data']['done']:
current_monkey = Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid']) current_monkey = Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid'])
test_passed_findings_for_unreached_segments(current_monkey) test_passed_findings_for_unreached_segments(current_monkey)
if telemetry_json['data']['version']:
logger.info(f"monkey {telemetry_json['monkey_guid']} has version {telemetry_json['data']['version']}")

View File

@ -2,6 +2,7 @@ import logging
import requests import requests
from common.version import get_version
from monkey_island.cc.environment.environment import env from monkey_island.cc.environment.environment import env
__author__ = "itay.mizeretz" __author__ = "itay.mizeretz"
@ -39,7 +40,7 @@ class VersionUpdateService:
Checks if newer monkey version is available Checks if newer monkey version is available
:return: False if not, version in string format ('1.6.2') otherwise :return: False if not, version in string format ('1.6.2') otherwise
""" """
url = VersionUpdateService.VERSION_SERVER_CHECK_NEW_URL % (env.get_deployment(), env.get_version()) url = VersionUpdateService.VERSION_SERVER_CHECK_NEW_URL % (env.get_deployment(), get_version())
reply = requests.get(url, timeout=15) reply = requests.get(url, timeout=15)
@ -53,4 +54,4 @@ class VersionUpdateService:
@staticmethod @staticmethod
def get_download_link(): def get_download_link():
return VersionUpdateService.VERSION_SERVER_DOWNLOAD_URL % (env.get_deployment(), env.get_version()) return VersionUpdateService.VERSION_SERVER_DOWNLOAD_URL % (env.get_deployment(), get_version())

View File

@ -6,7 +6,7 @@ PYTHON_FOLDER=/var/monkey/monkey_island/bin/python
# Prepare python virtualenv # Prepare python virtualenv
pip3 install virtualenv --no-index --find-links file://$INSTALLATION_FOLDER pip3 install virtualenv --no-index --find-links file://$INSTALLATION_FOLDER
virtualenv -p python3 ${PYTHON_FOLDER} python3 -m virtualenv -p python3 ${PYTHON_FOLDER}
# install pip requirements # install pip requirements
${PYTHON_FOLDER}/bin/python -m pip install -r $MONKEY_FOLDER/monkey_island/requirements.txt --no-index --find-links file://$INSTALLATION_FOLDER ${PYTHON_FOLDER}/bin/python -m pip install -r $MONKEY_FOLDER/monkey_island/requirements.txt --no-index --find-links file://$INSTALLATION_FOLDER

View File

@ -6,7 +6,7 @@ PYTHON_FOLDER=/var/monkey/monkey_island/bin/python
# Prepare python virtualenv # Prepare python virtualenv
pip3 install virtualenv --no-index --find-links file://$INSTALLATION_FOLDER pip3 install virtualenv --no-index --find-links file://$INSTALLATION_FOLDER
virtualenv -p python3 ${PYTHON_FOLDER} python3 -m virtualenv -p python3 ${PYTHON_FOLDER}
# install pip requirements # install pip requirements
${PYTHON_FOLDER}/bin/python -m pip install -r $MONKEY_FOLDER/monkey_island/requirements.txt --no-index --find-links file://$INSTALLATION_FOLDER ${PYTHON_FOLDER}/bin/python -m pip install -r $MONKEY_FOLDER/monkey_island/requirements.txt --no-index --find-links file://$INSTALLATION_FOLDER

View File

@ -23,6 +23,9 @@ elif [[ ${os_version_monkey} == "Debian GNU/Linux 9"* ]]; then
elif [[ ${os_version_monkey} == "Debian GNU/Linux 10"* ]]; then elif [[ ${os_version_monkey} == "Debian GNU/Linux 10"* ]]; then
echo Detected Debian 10 echo Detected Debian 10
export tgz_url="https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-debian10-4.2.3.tgz" export tgz_url="https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-debian10-4.2.3.tgz"
elif [[ ${os_version_monkey} == "Kali GNU/Linux"* ]]; then
echo Detected Kali Linux
export tgz_url="https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-debian10-4.2.3.tgz"
else else
echo Unsupported OS echo Unsupported OS
exit 1 exit 1

View File

@ -15,7 +15,9 @@ def main():
hookspath=None, hookspath=None,
runtime_hooks=None, runtime_hooks=None,
binaries=None, binaries=None,
datas=None, datas=[
("../common/BUILD", "../common/BUILD")
],
excludes=None, excludes=None,
win_no_prefer_redirects=None, win_no_prefer_redirects=None,
win_private_assemblies=None, win_private_assemblies=None,