Skip to content

Commit

Permalink
Merge pull request #235 from ThePorgs/dev
Browse files Browse the repository at this point in the history
Release 4.3.7
  • Loading branch information
Dramelac authored Oct 27, 2024
2 parents 5aa7e1e + 32307da commit 28e2ce5
Show file tree
Hide file tree
Showing 18 changed files with 179 additions and 57 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/entrypoint_prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,14 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
python-version: "3.12"
- name: Install requirements
run: python -m pip install --user build
run: python -m pip install --user build virtualenv setuptools
- name: Cleaning
run : python setup.py clean test
run : python setup.py clean
- name: Build Exegol
run: python -m build --sdist --outdir dist/ .
- name: Create testing venv
run: python -m venv vtest
- name: Install pip package
run: ./vtest/bin/pip install ./dist/*
9 changes: 7 additions & 2 deletions .github/workflows/entrypoint_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ on:
push:
branches-ignore:
- "dev"
- "master"
paths-ignore:
- ".github/**"
- "**.md"
Expand Down Expand Up @@ -43,10 +44,14 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
python-version: "3.12"
- name: Install requirements
run: python -m pip install --user build
run: python -m pip install --user build virtualenv setuptools
- name: Cleaning
run : python setup.py clean
- name: Build Exegol
run: python -m build --sdist --outdir dist/ .
- name: Create testing venv
run: python -m venv vtest
- name: Install pip package locally
run: ./vtest/bin/pip install ./dist/*
10 changes: 7 additions & 3 deletions .github/workflows/entrypoint_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
python-version: "3.12"
- name: Install requirements
run: python -m pip install --user build
run: python -m pip install --user build virtualenv setuptools
- name: Run package unitest
run : python setup.py clean test
run : python setup.py clean
- name: Build Exegol release
run: python -m build --sdist --outdir dist/ .
- name: Create testing venv
run: python -m venv vtest
- name: Install pip package locally
run: ./vtest/bin/pip install ./dist/*
#- name: Publish distribution 📦 to Test PyPI
# uses: pypa/gh-action-pypi-publish@release/v1
# with:
Expand Down
2 changes: 1 addition & 1 deletion exegol-docker-build
Submodule exegol-docker-build updated 67 files
+1 −1 .github/workflows/entrypoint_nightly.yml
+1 −1 .github/workflows/entrypoint_preprod_ad.yml
+1 −1 .github/workflows/entrypoint_preprod_base.yml
+1 −1 .github/workflows/entrypoint_preprod_full.yml
+1 −1 .github/workflows/entrypoint_preprod_light.yml
+1 −1 .github/workflows/entrypoint_preprod_osint.yml
+1 −1 .github/workflows/entrypoint_preprod_web.yml
+1 −1 .github/workflows/sub_build_belt.yml
+1 −1 .github/workflows/sub_release_manifest.yml
+19 −0 sources/assets/apt/preferences.d/default-stable
+5 −0 sources/assets/apt/sources.list.d/sid-debian.sources
+53 −37 sources/assets/bloodhound/customqueries.json
+1 −1 sources/assets/burpsuite/trust-ca-burp.sh
+0 −25 sources/assets/crackmapexec/cme.conf
+10 −4 sources/assets/desktop/bin/desktop-start
+12 −0 sources/assets/exegol/load_supported_setups.sh
+ sources/assets/firefox/places.sqlite
+2 −2 sources/assets/firefox/user-setup.py
+0 −16 sources/assets/grc/conf.cme
+0 −4 sources/assets/grc/grc.conf
+7 −4 sources/assets/shells/aliases.d/_init
+1 −0 sources/assets/shells/aliases.d/adminer
+1 −0 sources/assets/shells/aliases.d/binwalk
+0 −2 sources/assets/shells/aliases.d/crackmapexec
+8 −8 sources/assets/shells/aliases.d/metasploit
+3 −1 sources/assets/shells/aliases.d/netexec
+2 −0 sources/assets/shells/aliases.d/networkIP
+1 −0 sources/assets/shells/aliases.d/proxychains
+0 −1 sources/assets/shells/aliases.d/pyrit
+0 −1 sources/assets/shells/aliases.d/pywhisker
+4 −4 sources/assets/shells/aliases.d/responder
+0 −1 sources/assets/shells/aliases.d/sherlock
+1 −1 sources/assets/shells/aliases.d/spiderfoot
+1 −0 sources/assets/shells/aliases.d/uploader
+1 −0 sources/assets/shells/aliases.d/volatility3
+2 −0 sources/assets/shells/history.d/adminer
+1 −0 sources/assets/shells/history.d/conpass
+0 −42 sources/assets/shells/history.d/crackmapexec
+1 −0 sources/assets/shells/history.d/faketime
+2 −0 sources/assets/shells/history.d/gobuster
+23 −23 sources/assets/shells/history.d/impacket
+3 −0 sources/assets/shells/history.d/jsluice
+4 −0 sources/assets/shells/history.d/katana
+1 −0 sources/assets/shells/history.d/metasploit
+2 −1 sources/assets/shells/history.d/nmap
+1 −0 sources/assets/shells/history.d/postman
+1 −1 sources/assets/shells/history.d/pywhisker
+2 −0 sources/assets/shells/history.d/sherlock
+2 −0 sources/assets/shells/history.d/smbclient-ng
+1 −1 sources/assets/shells/history.d/uberfile
+2 −0 sources/assets/shells/history.d/uploader
+69 −38 sources/install/package_ad.sh
+20 −5 sources/install/package_base.sh
+27 −10 sources/install/package_c2.sh
+1 −3 sources/install/package_cloud.sh
+12 −1 sources/install/package_desktop.sh
+17 −7 sources/install/package_forensic.sh
+15 −0 sources/install/package_misc.sh
+10 −12 sources/install/package_mobile.sh
+0 −1 sources/install/package_most_used.sh
+19 −7 sources/install/package_network.sh
+7 −9 sources/install/package_osint.sh
+0 −1 sources/install/package_reverse.sh
+1 −1 sources/install/package_rfid.sh
+56 −3 sources/install/package_web.sh
+4 −2 sources/install/package_wifi.sh
+2 −8 sources/install/package_wordlists.sh
2 changes: 1 addition & 1 deletion exegol/config/ConstantConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class ConstantConfig:
"""Constant parameters information"""
# Exegol Version
version: str = "4.3.6"
version: str = "4.3.7"

# Exegol documentation link
documentation: str = "https://exegol.rtfd.io/"
Expand Down
11 changes: 8 additions & 3 deletions exegol/config/UserConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def __init__(self):
self.auto_remove_images: bool = True
self.auto_update_workspace_fs: bool = False
self.default_start_shell: str = "zsh"
self.enable_exegol_resources: bool = True
self.shell_logging_method: str = "asciinema"
self.shell_logging_compress: bool = True
self.desktop_default_enable: bool = False
Expand Down Expand Up @@ -61,6 +62,9 @@ def _build_file_content(self):
# Default shell command to start
default_start_shell: {self.default_start_shell}
# Enable Exegol resources
enable_exegol_resources: {self.enable_exegol_resources}
# Change the configuration of the shell logging functionality
shell_logging:
#Choice of the method used to record the sessions (script or asciinema)
Expand All @@ -82,8 +86,6 @@ def _build_file_content(self):
localhost_by_default: {self.desktop_default_localhost}
"""
# TODO handle default image selection
# TODO handle default start container
return config

@staticmethod
Expand Down Expand Up @@ -115,6 +117,7 @@ def _process_data(self):
self.auto_remove_images = self._load_config_bool(config_data, 'auto_remove_image', self.auto_remove_images)
self.auto_update_workspace_fs = self._load_config_bool(config_data, 'auto_update_workspace_fs', self.auto_update_workspace_fs)
self.default_start_shell = self._load_config_str(config_data, 'default_start_shell', self.default_start_shell, choices=self.start_shell_options)
self.enable_exegol_resources = self._load_config_bool(config_data, 'enable_exegol_resources', self.enable_exegol_resources)

# Shell_logging section
shell_logging_data = config_data.get("shell_logging", {})
Expand All @@ -132,7 +135,9 @@ def get_configs(self) -> List[str]:
configs = [
f"User config file: [magenta]{self._file_path}[/magenta]",
f"Private workspace: [magenta]{self.private_volume_path}[/magenta]",
f"Exegol resources: [magenta]{self.exegol_resources_path}[/magenta]",
"Exegol resources: " + (f"[magenta]{self.exegol_resources_path}[/magenta]"
if self.enable_exegol_resources else
boolFormatter(self.enable_exegol_resources)),
f"My resources: [magenta]{self.my_resources_path}[/magenta]",
f"Auto-check updates: {boolFormatter(self.auto_check_updates)}",
f"Auto-remove images: {boolFormatter(self.auto_remove_images)}",
Expand Down
6 changes: 4 additions & 2 deletions exegol/manager/ExegolController.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import http
import logging

try:
import docker
import requests
import git
import requests
import urllib3

from exegol.utils.ExeLog import logger, ExeLog, console
from exegol.utils.DockerUtils import DockerUtils
Expand Down Expand Up @@ -83,5 +85,5 @@ def main():
logger.critical(f"A critical error occurred while running this git command: {' '.join(git_error.command)}")
except Exception:
print_exception_banner()
console.print_exception(show_locals=True, suppress=[docker, requests, git])
console.print_exception(show_locals=True, suppress=[docker, requests, git, urllib3, http])
exit(1)
7 changes: 5 additions & 2 deletions exegol/manager/UpdateManager.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import re
from datetime import datetime, timedelta
from pathlib import Path
from typing import Optional, Dict, cast, Tuple, Sequence
from pathlib import Path, PurePath

from rich.prompt import Prompt

from exegol.config.ConstantConfig import ConstantConfig
from exegol.config.DataCache import DataCache
from exegol.config.UserConfig import UserConfig
from exegol.console.ExegolPrompt import Confirm
from exegol.console.TUI import ExegolTUI
from exegol.console.cli.ParametersManager import ParametersManager
Expand Down Expand Up @@ -117,6 +117,9 @@ def updateImageSource(cls) -> bool:
@classmethod
def updateResources(cls) -> bool:
"""Update Exegol-resources from git (submodule)"""
if not UserConfig().enable_exegol_resources:
logger.info("Skipping disabled Exegol resources.")
return False
try:
if not ExegolModules().isExegolResourcesReady() and not Confirm('Do you want to update exegol resources.', default=True):
return False
Expand Down
7 changes: 4 additions & 3 deletions exegol/model/ContainerConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from exegol.model.ExegolModules import ExegolModules
from exegol.utils import FsUtils
from exegol.utils.ExeLog import logger, ExeLog
from exegol.utils.FsUtils import check_sysctl_value
from exegol.utils.FsUtils import check_sysctl_value, mkdir
from exegol.utils.GuiUtils import GuiUtils

if EnvInfo.is_windows_shell or EnvInfo.is_mac_shell:
Expand Down Expand Up @@ -501,7 +501,8 @@ def enableExegolResources(self) -> bool:
raise CancelOperation
except CancelOperation:
# Error during installation, skipping operation
logger.warning("Exegol resources have not been downloaded, the feature cannot be enabled")
if UserConfig().enable_exegol_resources:
logger.warning("Exegol resources have not been downloaded, the feature cannot be enabled yet")
return False
logger.verbose("Config: Enabling exegol resources volume")
self.__exegol_resources = True
Expand Down Expand Up @@ -1038,7 +1039,7 @@ def addVolume(self,
else:
# If the directory is created by exegol, bypass user preference and enable shared perms (if available)
execute_update_fs = force_sticky_group or enable_sticky_group
path.mkdir(parents=True, exist_ok=True)
mkdir(path)
except PermissionError:
logger.error("Unable to create the volume folder on the filesystem locally.")
logger.critical(f"Insufficient permissions to create the folder: {host_path}")
Expand Down
87 changes: 72 additions & 15 deletions exegol/model/ExegolContainer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import os
import shutil
import subprocess
import tempfile
from datetime import datetime
from typing import Optional, Dict, Sequence, Tuple, Union

Expand All @@ -15,6 +17,7 @@
from exegol.model.SelectableInterface import SelectableInterface
from exegol.utils.ContainerLogStream import ContainerLogStream
from exegol.utils.ExeLog import logger, console
from exegol.utils.GuiUtils import GuiUtils
from exegol.utils.imgsync.ImageScriptSync import ImageScriptSync


Expand Down Expand Up @@ -115,7 +118,7 @@ def __start_container(self):
:return:
"""
with console.status(f"Waiting to start {self.name}", spinner_style="blue") as progress:
start_date = datetime.utcnow()
start_date = datetime.now()
try:
self.__container.start()
except APIError as e:
Expand Down Expand Up @@ -156,7 +159,7 @@ def spawnShell(self):
logger.info(f"Shared host device: {device.split(':')[0]}")
logger.success(f"Opening shell in Exegol '{self.name}'")
# In case of multi-user environment, xhost must be set before opening each session to be sure
self.__applyXhostACL()
self.__applyX11ACLs()
# Using system command to attach the shell to the user terminal (stdin / stdout / stderr)
envs = self.config.getShellEnvs()
options = ""
Expand Down Expand Up @@ -190,7 +193,9 @@ def exec(self, command: Union[str, Sequence[str]], as_daemon: bool = True, quiet
# stream[0] : exit code
# stream[1] : text stream
for log in stream[1]:
logger.raw(log.decode("utf-8"))
if type(log) is bytes:
log = log.decode("utf-8")
logger.raw(log)
if not quiet:
logger.success("End of the command")
except KeyboardInterrupt:
Expand Down Expand Up @@ -281,7 +286,7 @@ def __preStartSetup(self):
Operation to be performed before starting a container
:return:
"""
self.__applyXhostACL()
self.__applyX11ACLs()

def __check_start_version(self):
"""
Expand All @@ -305,7 +310,7 @@ def postCreateSetup(self, is_temporary: bool = False):
Operation to be performed after creating a container
:return:
"""
self.__applyXhostACL()
self.__applyX11ACLs()
# if not a temporary container, apply custom config
if not is_temporary:
# Update entrypoint script in the container
Expand All @@ -318,12 +323,14 @@ def postCreateSetup(self, is_temporary: bool = False):
if "is not running" in e.explanation:
logger.critical("An unexpected error occurred. Exegol cannot start the container after its creation...")

def __applyXhostACL(self):
def __applyX11ACLs(self):
"""
If X11 (GUI) is enabled, allow X11 access on host ACL (if not already allowed) for linux and mac.
On Windows host, WSLg X11 don't have xhost ACL.
If the host is accessed by SSH, propagate xauth cookie authentication if applicable.
On Windows host, WSLg X11 don't have xhost ACL. #TODO xauth remote x11 forwarding
:return:
"""
# TODO check if the xauth propagation should be performed on Windows, if so remove the "and not EnvInfo.isWindowsHost()"
if self.config.isGUIEnable() and not self.__xhost_applied and not EnvInfo.isWindowsHost():
self.__xhost_applied = True # Can be applied only once per execution
if shutil.which("xhost") is None:
Expand All @@ -335,15 +342,65 @@ def __applyXhostACL(self):
f"Exegol was unable to allow your container to access your graphical environment ({debug_msg}).")
return

if EnvInfo.isMacHost():
logger.debug(f"Adding xhost ACL to localhost")
# add xquartz inet ACL
with console.status(f"Starting XQuartz...", spinner_style="blue"):
os.system(f"xhost + localhost > /dev/null")
logger.debug(f"DISPLAY variable: {GuiUtils.getDisplayEnv()}")
# Extracts the left part of the display variable to determine if remote access is used
display_host = GuiUtils.getDisplayEnv().split(':')[0]
# Left part is empty, local access is used to start Exegol
if display_host == '' or EnvInfo.isMacHost():
logger.debug("Connecting to container from local GUI, no X11 forwarding to set up")
# TODO verify that the display format is the same on macOS, otherwise might not set up xauth and xhost correctly
if EnvInfo.isMacHost():
logger.debug(f"Adding xhost ACL to localhost")
# add xquartz inet ACL
with console.status(f"Starting XQuartz...", spinner_style="blue"):
os.system(f"xhost + localhost > /dev/null")
elif not EnvInfo.isWindowsHost():
logger.debug(f"Adding xhost ACL to local:{self.config.getUsername()}")
# add linux local ACL
os.system(f"xhost +local:{self.config.getUsername()} > /dev/null")
return

if shutil.which("xauth") is None:
if EnvInfo.is_linux_shell:
debug_msg = "Try to install the package [green]xorg-xauth[/green] to support X11 forwarding in your current environment?"
else:
debug_msg = "or it might not be supported for now"
logger.error(f"The [green]xauth[/green] command is not available on your [bold]host[/bold]. "
f"Exegol was unable to allow your container to access your graphical environment ({debug_msg}).")
return

# If the left part of the display variable is "localhost", x11 socket is exposed only on loopback and remote access is used
# If the container is not in host mode, it won't be able to reach the loopback interface of the host
if display_host == "localhost" and self.config.getNetworkMode() != "host":
logger.warning("X11 forwarding won't work on a bridged container unless you specify \"X11UseLocalhost no\" in your host sshd_config")
logger.warning("[red]Be aware[/red] changing \"X11UseLocalhost\" value can [red]expose your device[/red], correct firewalling is [red]required[/red]")
# TODO Add documentation to restrict the exposure of the x11 socket to the docker subnet
return

# Extracting the xauth cookie corresponding to the current display to a temporary file and reading it from there (grep cannot be used because display names are not accurate enough)
_, tmpXauthority = tempfile.mkstemp()
logger.debug(f"Extracting xauth entries to {tmpXauthority}")
os.system(f"xauth extract {tmpXauthority} $DISPLAY > /dev/null 2>&1")
xauthEntry = subprocess.check_output(f"xauth -f {tmpXauthority} list 2>/dev/null", shell=True).decode()
logger.debug(f"xauthEntry to propagate: {xauthEntry}")

# Replacing the hostname with localhost to support loopback exposed x11 socket and container in host mode (loopback is the same)
if display_host == "localhost":
logger.debug("X11UseLocalhost directive is set to \"yes\" or unspecified, X11 connections can be received only on loopback");
# Modifing the entry to convert <hostname>/unix:<display_number> to localhost:<display_number>
xauthEntry = f"localhost:{xauthEntry.split(':')[1]}"
else:
# TODO latter implement a check to see if the x11 socket is correctly firewalled and warn the user if it is not
logger.debug("X11UseLocalhost directive is set to \"no\", X11 connections can be received from anywere");

# Check if the host has a xauth entry corresponding to the current display.
if xauthEntry:
logger.debug(f"Adding xauth cookie to container: {xauthEntry}")
self.exec(f"xauth add {xauthEntry}", as_daemon=False, quiet=True)
logger.debug(f"Removing {tmpXauthority}")
os.remove(tmpXauthority)
else:
logger.debug(f"Adding xhost ACL to local:{self.config.getUsername()}")
# add linux local ACL
os.system(f"xhost +local:{self.config.getUsername()} > /dev/null")
logger.warning(f"No xauth cookie corresponding to the current display was found.")

def __updatePasswd(self):
"""
Expand Down
6 changes: 3 additions & 3 deletions exegol/model/ExegolModules.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from pathlib import Path
from typing import Optional, Union

from exegol.config.ConstantConfig import ConstantConfig
from exegol.config.UserConfig import UserConfig
from exegol.console.ExegolPrompt import Confirm
from exegol.console.cli.ParametersManager import ParametersManager
from exegol.exceptions.ExegolExceptions import CancelOperation
from exegol.config.ConstantConfig import ConstantConfig
from exegol.utils.ExeLog import logger
from exegol.utils.GitUtils import GitUtils
from exegol.utils.MetaSingleton import MetaSingleton
from exegol.config.UserConfig import UserConfig


class ExegolModules(metaclass=MetaSingleton):
Expand Down Expand Up @@ -51,7 +51,7 @@ def getResourcesGit(self, fast_load: bool = False, skip_install: bool = False) -
if self.__git_resources is None:
self.__git_resources = GitUtils(UserConfig().exegol_resources_path, "resources", "",
skip_submodule_update=fast_load)
if not self.__git_resources.isAvailable and not skip_install:
if not self.__git_resources.isAvailable and not skip_install and UserConfig().enable_exegol_resources:
self.__init_resources_repo()
return self.__git_resources

Expand Down
Loading

0 comments on commit 28e2ce5

Please sign in to comment.