Skip to content
Snippets Groups Projects
Commit 9d0f659d authored by Jiří Rája's avatar Jiří Rája 🔥
Browse files

Updated Kali image and default modules directory

parent 76652668
No related branches found
No related tags found
No related merge requests found
CRYTON_WORKER_NAME=Worker
CRYTON_WORKER_MODULES_DIR=CHANGE_ME
CRYTON_WORKER_MODULES_DIRECTORY=APP_DIRECTORY/modules
CRYTON_WORKER_DEBUG=false
CRYTON_WORKER_INSTALL_REQUIREMENTS=true
CRYTON_WORKER_CONSUMER_COUNT=7
......
......@@ -13,6 +13,18 @@ RUN poetry install --without dev --no-root --no-interaction --no-ansi
COPY . /app/
RUN poetry install --only-root --no-interaction --no-ansi
FROM base as modules
WORKDIR /download
RUN apt update && apt install -y \
git
RUN W_VERSION=$(/app/.venv/bin/cryton-worker --version) && \
W_VERSION=${W_VERSION#*version } && \
W_VERSION=${W_VERSION%.*} && \
git clone https://gitlab.ics.muni.cz/cryton/cryton-modules.git --branch stable/$W_VERSION
FROM python:3.11-slim-bullseye as production
# Set environment
......@@ -28,7 +40,7 @@ RUN ln -s /app/.venv/bin/cryton-worker /usr/local/bin/cryton-worker
RUN _CRYTON_WORKER_COMPLETE=bash_source cryton-worker > /etc/profile.d/cryton-worker-complete.sh
RUN echo ". /etc/profile.d/cryton-worker-complete.sh" >> ~/.bashrc
CMD ["cryton-worker", "start"]
CMD [ "cryton-worker", "start" ]
FROM registry.gitlab.ics.muni.cz:443/cryton/configurations/kali-prebuilt:latest as kali
......@@ -38,6 +50,9 @@ ENV CRYTON_WORKER_APP_DIRECTORY=/app
# Copy app
COPY --from=base /app /app
# Copy modules
COPY --from=modules /download/cryton-modules/modules /app/modules
# Make the executable accessible
RUN ln -s /app/.venv/bin/cryton-worker /usr/local/bin/cryton-worker
......@@ -48,5 +63,4 @@ RUN ln -s -f /usr/bin/python3.11 /app/.venv/bin/python
RUN _CRYTON_WORKER_COMPLETE=bash_source cryton-worker > /etc/profile.d/cryton-worker-complete.sh
RUN echo ". /etc/profile.d/cryton-worker-complete.sh" >> ~/.bashrc
ENTRYPOINT [ "/app/docker/entrypoint.kali.sh" ]
CMD ["cryton-worker", "start"]
CMD [ "cryton-worker", "start" ]
......@@ -23,18 +23,12 @@ Make sure Git, Docker, and Docker Compose plugin are installed:
Optionally, check out these Docker [post-installation steps](https://docs.docker.com/engine/install/linux-postinstall/).
The following script clones the necessary repositories (Worker and modules), updates Worker's settings, and runs the
Docker Compose configuration which starts the Worker, and its prerequisites (Metasploit and Empire framework).
The following script clones the Worker repository and runs the Docker Compose configuration which starts
the Worker (with preinstalled modules), and its prerequisites (Metasploit and Empire framework).
```shell
git clone https://gitlab.ics.muni.cz/cryton/cryton-modules.git
cd cryton-modules
git checkout $(git tag --list "2023.1.*" | tail -n 1)
cd ..
export CRYTON_MODULES_PATH=$(pwd)/cryton-modules/modules
git clone https://gitlab.ics.muni.cz/cryton/cryton-worker.git
cd cryton-worker
git checkout $(git tag --list "2023.1.*" | tail -n 1)
sed -i "s|CRYTON_WORKER_MODULES_DIR=CHANGE_ME|CRYTON_WORKER_MODULES_DIR=$CRYTON_MODULES_PATH|" .env
docker compose up -d
```
......
......@@ -16,7 +16,13 @@ LOG_FILE_PATH = path.join(LOG_DIRECTORY, "cryton-worker.log")
LOG_FILE_PATH_DEBUG = path.join(LOG_DIRECTORY, "cryton-worker-debug.log")
WORKER_NAME = getenv("CRYTON_WORKER_NAME", "Worker")
MODULES_DIR = getenv("CRYTON_WORKER_MODULES_DIR") # TODO: The default should point to the app directory
MODULES_DIRECTORY = getenv("CRYTON_WORKER_MODULES_DIRECTORY", "APP_DIRECTORY/modules")
if MODULES_DIRECTORY.lower().startswith("app_directory"):
if not MODULES_DIRECTORY.endswith("/"):
MODULES_DIRECTORY += "/"
MODULES_DIRECTORY = path.join(APP_DIRECTORY, MODULES_DIRECTORY.split("/", 1)[1])
DEBUG = True if getenv("CRYTON_WORKER_DEBUG", "false").lower() == "true" else False
INSTALL_REQUIREMENTS = True if getenv("CRYTON_WORKER_INSTALL_REQUIREMENTS", "true").lower() == "true" else False
CONSUMER_COUNT = int(getenv("CRYTON_WORKER_CONSUMER_COUNT", 7))
......
......@@ -73,7 +73,7 @@ def execute_attack_module_on_worker(module_path: str, arguments: dict) -> dict:
result = executable(arguments)
except Exception as ex:
result = {co.RETURN_CODE: -2, co.OUTPUT: str({"module": module_path, "ex_type": str(ex.__class__),
"error": ex.__str__(), "traceback": traceback.format_exc()})}
"error": ex.__str__(), "traceback": traceback.format_exc()})}
logger.logger.debug("Module execution finished.", module_name=module_path, arguments=arguments, result=result)
return result
......@@ -103,7 +103,7 @@ def validate_module(module_path: str, arguments: dict) -> dict:
result = {co.RETURN_CODE: return_code, co.OUTPUT: f"Module {module_path} is valid."}
except Exception as ex:
result = {co.RETURN_CODE: -2, co.OUTPUT: str({"module": module_path, "ex_type": str(ex.__class__),
"error": ex.__str__(), "traceback": traceback.format_exc()})}
"error": ex.__str__(), "traceback": traceback.format_exc()})}
logger.logger.debug("Module validation finished.", module_name=module_path, arguments=arguments, result=result)
return result
......@@ -118,7 +118,7 @@ def import_module(module_path: str) -> ModuleType:
"""
logger.logger.debug("Importing module.", module_name=module_path)
module_name = "mod"
module_path = os.path.join(config.MODULES_DIR, module_path, module_name + ".py")
module_path = os.path.join(config.MODULES_DIRECTORY, module_path, module_name + ".py")
module_spec = importlib.util.spec_from_file_location(module_name, module_path)
module_obj = importlib.util.module_from_spec(module_spec)
......@@ -376,7 +376,7 @@ def list_modules() -> list:
:return: Available modules
"""
logger.logger.debug("Listing modules.")
default_modules_dir = config.MODULES_DIR
default_modules_dir = config.MODULES_DIRECTORY
# List all python files, exclude init files
files = [f.replace(default_modules_dir, "") for f in glob.glob(default_modules_dir + "**/*.py", recursive=True)]
files = list(filter(lambda a: a.find("__init__.py") == -1, files))
......@@ -396,7 +396,7 @@ def install_modules_requirements(verbose: bool = False) -> None:
additional_args.update({"stdout": subprocess.DEVNULL, "stderr": subprocess.DEVNULL})
logger.logger.debug("Installing module requirements.")
for root, dirs, files in os.walk(config.MODULES_DIR):
for root, dirs, files in os.walk(config.MODULES_DIRECTORY):
for filename in files:
if filename == "requirements.txt":
subprocess.check_call([sys.executable, "-m", "pip", "install", "-r", os.path.join(root, filename)],
......
......@@ -12,18 +12,33 @@ services:
- .env
volumes:
- ${CRYTON_WORKER_MODULES_DIR}:${CRYTON_WORKER_MODULES_DIR}
- cryton_worker_db_data:/var/lib/postgresql/15/main
depends_on:
cryton_empire:
condition: service_started
cryton_msf:
condition: service_started
cryton_empire:
restart: always
image: bcsecurity/empire:v4.10.0
container_name: cryton-empire
expose:
- 1337
network_mode: host
env_file:
- .env
stdin_open: true
command: [ "server", "--username", "$CRYTON_WORKER_EMPIRE_USERNAME", "--password", "$CRYTON_WORKER_EMPIRE_PASSWORD" ]
volumes:
cryton_worker_db_data:
cryton_msf:
restart: always
image: registry.gitlab.ics.muni.cz:443/cryton/configurations/metasploit-framework
container_name: cryton-msf
network_mode: host
env_file:
- .env
environment:
MSF_RPC_HOST: $CRYTON_WORKER_MSFRPCD_HOST
MSF_RPC_PORT: $CRYTON_WORKER_MSFRPCD_PORT
MSF_RPC_SSL: $CRYTON_WORKER_MSFRPCD_SSL
MSF_RPC_USERNAME: $CRYTON_WORKER_MSFRPCD_USERNAME
MSF_RPC_PASSWORD: $CRYTON_WORKER_MSFRPCD_PASSWORD
tty: true
......@@ -7,9 +7,11 @@ services:
network_mode: host
env_file:
- .env
volumes:
- ${CRYTON_WORKER_MODULES_DIR}:${CRYTON_WORKER_MODULES_DIR}
- cryton_worker_db_data:/var/lib/postgresql/15/main
depends_on:
cryton_empire:
condition: service_started
cryton_msf:
condition: service_started
cryton_empire:
restart: always
......@@ -21,5 +23,17 @@ services:
stdin_open: true
command: [ "server", "--username", "$CRYTON_WORKER_EMPIRE_USERNAME", "--password", "$CRYTON_WORKER_EMPIRE_PASSWORD" ]
volumes:
cryton_worker_db_data:
cryton_msf:
restart: always
image: registry.gitlab.ics.muni.cz:443/cryton/configurations/metasploit-framework
container_name: cryton-msf
network_mode: host
env_file:
- .env
environment:
MSF_RPC_HOST: $CRYTON_WORKER_MSFRPCD_HOST
MSF_RPC_PORT: $CRYTON_WORKER_MSFRPCD_PORT
MSF_RPC_SSL: $CRYTON_WORKER_MSFRPCD_SSL
MSF_RPC_USERNAME: $CRYTON_WORKER_MSFRPCD_USERNAME
MSF_RPC_PASSWORD: $CRYTON_WORKER_MSFRPCD_PASSWORD
tty: true
#!/bin/sh
service postgresql start
msfdb init
msfrpcd -P $CRYTON_WORKER_MSFRPCD_PASSWORD -U $CRYTON_WORKER_MSFRPCD_USERNAME -a 127.0.0.1 -p $CRYTON_WORKER_MSFRPCD_PORT
exec "$@"
[tool.poetry]
name = "cryton-worker"
version = "2023.1.1"
version = "2023.2.0"
description = "Attack scenario orchestrator for Cryton"
authors = [
"Ivo Nutár <nutar@ics.muni.cz>",
......
......@@ -83,7 +83,7 @@ class TestUtil(TestCase):
with self.assertRaises(ModuleNotFoundError):
util.import_module("test")
@patch("cryton_worker.etc.config.MODULES_DIR", "/tmp/mods4a4a5a7")
@patch("cryton_worker.etc.config.MODULES_DIRECTORY", "/tmp/mods4a4a5a7")
def test_list_modules(self):
ret = util.list_modules()
self.assertEqual([], ret)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment