├── C2_Profiles └── .keep ├── agent_icons ├── .keep └── sliver.svg ├── documentation-c2 └── .keep ├── documentation-payload └── .keep ├── documentation-wrapper └── .keep ├── Payload_Type ├── sliverapi │ ├── __init__.py │ ├── sliverapi │ │ ├── SliverRequests │ │ │ ├── __init__.py │ │ │ └── SliverAPI.py │ │ ├── agent_functions │ │ │ ├── __init__.py │ │ │ ├── sliver.svg │ │ │ ├── licenses.py │ │ │ ├── operators.py │ │ │ ├── canaries.py │ │ │ ├── builders.py │ │ │ ├── hosts.py │ │ │ ├── version.py │ │ │ ├── dns.py │ │ │ ├── armory.py │ │ │ ├── cursed.py │ │ │ ├── http.py │ │ │ ├── beacons.py │ │ │ ├── wg.py │ │ │ ├── mtls.py │ │ │ ├── websites.py │ │ │ ├── sessions.py │ │ │ ├── https.py │ │ │ ├── reaction.py │ │ │ ├── stage_listener.py │ │ │ ├── implants.py │ │ │ ├── builder.py │ │ │ ├── regenerate.py │ │ │ └── jobs.py │ │ └── __init__.py │ ├── requirements.txt │ ├── main.py │ ├── rabbitmq_config.json.example │ └── Dockerfile └── sliverimplant │ ├── __init__.py │ ├── sliverimplant │ ├── SliverRequests │ │ ├── __init__.py │ │ └── SliverAPI.py │ ├── agent_functions │ │ ├── __init__.py │ │ ├── sliver.svg │ │ ├── getpid.py │ │ ├── getuid.py │ │ ├── getgid.py │ │ ├── whoami.py │ │ ├── ifconfig.py │ │ ├── memfiles.py │ │ ├── pwd.py │ │ ├── socks5.py │ │ ├── ping.py │ │ ├── portfwd.py │ │ ├── rportfwd.py │ │ ├── kill.py │ │ ├── chown.py │ │ ├── chtimes.py │ │ ├── extensions.py │ │ ├── cd.py │ │ ├── msf.py │ │ ├── pivots.py │ │ ├── procdump.py │ │ ├── chmod.py │ │ ├── builder.py │ │ ├── mkdir.py │ │ ├── netstat.py │ │ ├── msf_inject.py │ │ ├── tasks.py │ │ ├── terminate.py │ │ ├── screenshot.py │ │ ├── interactive.py │ │ ├── mv.py │ │ ├── reconfig.py │ │ ├── ssh.py │ │ ├── upload.py │ │ ├── ps.py │ │ ├── sideload.py │ │ ├── cat.py │ │ ├── execute_shellcode.py │ │ ├── rm.py │ │ ├── download.py │ │ ├── execute.py │ │ ├── execute_assembly.py │ │ ├── info.py │ │ └── ls.py │ └── __init__.py │ ├── requirements.txt │ ├── main.py │ └── Dockerfile ├── .devcontainer ├── requirements.txt ├── devcontainer.json └── Dockerfile ├── blog └── pics │ ├── chad.jpg │ ├── debug.png │ ├── fun.jpg │ ├── success.png │ ├── twitter.png │ ├── more_chad.png │ ├── nice_meme.jpeg │ ├── too_easy.jpg │ ├── file_browser.png │ ├── interactive.png │ ├── mythic_tasking.png │ ├── before_file_browser.png │ └── rick_and_morty_meme.jpg ├── .gitignore ├── config.json ├── .vscode └── launch.json └── LICENSE /C2_Profiles/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /agent_icons/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /documentation-c2/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /documentation-payload/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /documentation-wrapper/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/SliverRequests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/SliverRequests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.devcontainer/requirements.txt: -------------------------------------------------------------------------------- 1 | mythic-container==0.4.18 2 | tabulate 3 | sliver-py 4 | -------------------------------------------------------------------------------- /blog/pics/chad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/chad.jpg -------------------------------------------------------------------------------- /blog/pics/debug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/debug.png -------------------------------------------------------------------------------- /blog/pics/fun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/fun.jpg -------------------------------------------------------------------------------- /Payload_Type/sliverapi/requirements.txt: -------------------------------------------------------------------------------- 1 | mythic-container==0.4.18 2 | tabulate 3 | sliver-py 4 | -------------------------------------------------------------------------------- /blog/pics/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/success.png -------------------------------------------------------------------------------- /blog/pics/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/twitter.png -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/requirements.txt: -------------------------------------------------------------------------------- 1 | mythic-container==0.4.18 2 | tabulate 3 | sliver-py 4 | -------------------------------------------------------------------------------- /blog/pics/more_chad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/more_chad.png -------------------------------------------------------------------------------- /blog/pics/nice_meme.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/nice_meme.jpeg -------------------------------------------------------------------------------- /blog/pics/too_easy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/too_easy.jpg -------------------------------------------------------------------------------- /blog/pics/file_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/file_browser.png -------------------------------------------------------------------------------- /blog/pics/interactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/interactive.png -------------------------------------------------------------------------------- /blog/pics/mythic_tasking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/mythic_tasking.png -------------------------------------------------------------------------------- /blog/pics/before_file_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/before_file_browser.png -------------------------------------------------------------------------------- /blog/pics/rick_and_morty_meme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MythicAgents/sliver/HEAD/blog/pics/rick_and_morty_meme.jpg -------------------------------------------------------------------------------- /Payload_Type/sliverapi/main.py: -------------------------------------------------------------------------------- 1 | import mythic_container 2 | import asyncio 3 | import sliverapi 4 | 5 | mythic_container.mythic_service.start_and_run_forever() -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/main.py: -------------------------------------------------------------------------------- 1 | import mythic_container 2 | import asyncio 3 | import sliverimplant 4 | 5 | mythic_container.mythic_service.start_and_run_forever() -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # setup for local testing 2 | rabbitmq_config.json 3 | rabbitmq_config.json.kali 4 | rabbitmq_config.json.ubuntu 5 | 6 | __pycache__/ 7 | mythic_go_services* 8 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/rabbitmq_config.json.example: -------------------------------------------------------------------------------- 1 | { 2 | "rabbitmq_host": "127.0.0.1", 3 | "rabbitmq_password": "", 4 | "mythic_server_host": "127.0.0.1", 5 | "debug_level": "debug" 6 | } -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude_payload_type": false, 3 | "exclude_c2_profiles": true, 4 | "exclude_documentation_payload": true, 5 | "exclude_documentation_c2": true, 6 | "exclude_agent_icons": true, 7 | "remote_images": { 8 | "sliverapi": "ghcr.io/mythicagents/sliver:sliverapi.v0.0.0.16", 9 | "sliverimplant": "ghcr.io/mythicagents/sliver:sliverimplant.v0.0.0.16" 10 | } 11 | } -------------------------------------------------------------------------------- /agent_icons/sliver.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/sliver.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/sliver.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/__init__.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os.path 3 | from pathlib import Path 4 | from importlib import import_module, invalidate_caches 5 | import sys 6 | # Get file paths of all modules. 7 | 8 | currentPath = Path(__file__) 9 | searchPath = currentPath.parent / "agent_functions" / "*.py" 10 | modules = glob.glob(f"{searchPath}") 11 | invalidate_caches() 12 | for x in modules: 13 | if not x.endswith("__init__.py") and x[-3:] == ".py": 14 | module = import_module(f"{__name__}.agent_functions." + Path(x).stem) 15 | for el in dir(module): 16 | if "__" not in el: 17 | globals()[el] = getattr(module, el) 18 | 19 | 20 | sys.path.append(os.path.abspath(currentPath.name)) -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/__init__.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os.path 3 | from pathlib import Path 4 | from importlib import import_module, invalidate_caches 5 | import sys 6 | # Get file paths of all modules. 7 | 8 | currentPath = Path(__file__) 9 | searchPath = currentPath.parent / "agent_functions" / "*.py" 10 | modules = glob.glob(f"{searchPath}") 11 | invalidate_caches() 12 | for x in modules: 13 | if not x.endswith("__init__.py") and x[-3:] == ".py": 14 | module = import_module(f"{__name__}.agent_functions." + Path(x).stem) 15 | for el in dir(module): 16 | if "__" not in el: 17 | globals()[el] = getattr(module, el) 18 | 19 | 20 | sys.path.append(os.path.abspath(currentPath.name)) -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slithic_devcontainer", 3 | "build": { 4 | "dockerfile": "Dockerfile" 5 | }, 6 | "mounts": [ 7 | // useful for git 8 | "type=bind,source=/home/${localEnv:USER}/.ssh,target=/root/.ssh,readonly" 9 | ], 10 | "customizations": { 11 | "vscode": { 12 | "settings": { 13 | "python.defaultInterpreterPath": "/usr/local/bin/python", 14 | "pylint.args": [ 15 | "--disable=E1101", 16 | "--disable=W0212" 17 | ] 18 | }, 19 | "extensions": [ 20 | "ms-python.python", 21 | "ms-azuretools.vscode-docker", 22 | "ms-python.pylint", 23 | "golang.go", 24 | "ms-vscode.makefile-tools" 25 | ] 26 | } 27 | }, 28 | "postStartCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}" 29 | } -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM itsafeaturemythic/mythic_python_base:latest as builder 2 | 3 | RUN apt-get update 4 | RUN apt-get install -y git gnupg software-properties-common 5 | 6 | WORKDIR /Mythic/ 7 | 8 | RUN git clone --depth 1 https://github.com/grpc/grpc 9 | RUN cd grpc && git submodule update --init 10 | RUN cd grpc && pip install -r requirements.txt 11 | RUN cd grpc && pip uninstall -y protobuf 12 | RUN cd grpc && pip install protobuf==3.20.* 13 | RUN cd grpc && GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=True GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install . 14 | RUN cd grpc && python setup.py bdist_wheel --dist-dir=/grpc_wheel 15 | 16 | COPY ["requirements.txt", "requirements.txt"] 17 | RUN python3 -m pip wheel --wheel-dir /other_wheels -r requirements.txt 18 | 19 | ########################################################### 20 | ########################################################### 21 | 22 | FROM itsafeaturemythic/mythic_python_base:latest 23 | 24 | COPY --from=builder /other_wheels /other_wheels 25 | COPY --from=builder /grpc_wheel /grpc_wheel 26 | 27 | RUN pip install --no-cache /other_wheels/* 28 | RUN pip install --no-cache /grpc_wheel/* 29 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM itsafeaturemythic/mythic_python_base:latest as builder 2 | 3 | RUN apt-get update 4 | RUN apt-get install -y git gnupg software-properties-common 5 | 6 | WORKDIR /Mythic/ 7 | 8 | RUN git clone --depth 1 https://github.com/grpc/grpc 9 | RUN cd grpc && git submodule update --init 10 | RUN cd grpc && pip install -r requirements.txt 11 | RUN cd grpc && pip uninstall -y protobuf 12 | RUN cd grpc && pip install protobuf==3.20.* 13 | RUN cd grpc && GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=True GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install . 14 | RUN cd grpc && python setup.py bdist_wheel --dist-dir=/grpc_wheel 15 | 16 | COPY ["requirements.txt", "requirements.txt"] 17 | RUN python3 -m pip wheel --wheel-dir /other_wheels -r requirements.txt 18 | 19 | ########################################################### 20 | ########################################################### 21 | 22 | FROM itsafeaturemythic/mythic_python_base:latest 23 | 24 | COPY --from=builder /other_wheels /other_wheels 25 | COPY --from=builder /grpc_wheel /grpc_wheel 26 | 27 | RUN pip install --no-cache /other_wheels/* 28 | RUN pip install --no-cache /grpc_wheel/* 29 | 30 | WORKDIR /Mythic/ 31 | 32 | COPY [".", "."] 33 | 34 | CMD ["python3", "main.py"] -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM itsafeaturemythic/mythic_python_base:latest as builder 2 | 3 | RUN apt-get update 4 | RUN apt-get install -y git gnupg software-properties-common 5 | 6 | WORKDIR /Mythic/ 7 | 8 | RUN git clone --depth 1 https://github.com/grpc/grpc 9 | RUN cd grpc && git submodule update --init 10 | RUN cd grpc && pip install -r requirements.txt 11 | RUN cd grpc && pip uninstall -y protobuf 12 | RUN cd grpc && pip install protobuf==3.20.* 13 | RUN cd grpc && GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=True GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install . 14 | RUN cd grpc && python setup.py bdist_wheel --dist-dir=/grpc_wheel 15 | 16 | COPY ["requirements.txt", "requirements.txt"] 17 | RUN python3 -m pip wheel --wheel-dir /other_wheels -r requirements.txt 18 | 19 | ########################################################### 20 | ########################################################### 21 | 22 | FROM itsafeaturemythic/mythic_python_base:latest 23 | 24 | COPY --from=builder /other_wheels /other_wheels 25 | COPY --from=builder /grpc_wheel /grpc_wheel 26 | 27 | RUN pip install --no-cache /other_wheels/* 28 | RUN pip install --no-cache /grpc_wheel/* 29 | 30 | WORKDIR /Mythic/ 31 | 32 | COPY [".", "."] 33 | 34 | CMD ["python3", "main.py"] -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "SliverApi", 9 | "type": "debugpy", 10 | "python": "/usr/local/bin/python", 11 | "request": "launch", 12 | "program": "${workspaceFolder}/Payload_Type/sliverapi/main.py", 13 | "console": "integratedTerminal", 14 | "cwd": "${workspaceFolder}/Payload_Type/sliverapi", 15 | "consoleTitle": "SliverApi" 16 | }, 17 | { 18 | "name": "SliverImplant", 19 | "type": "debugpy", 20 | "python": "/usr/local/bin/python", 21 | "request": "launch", 22 | "program": "${workspaceFolder}/Payload_Type/sliverimplant/main.py", 23 | "console": "integratedTerminal", 24 | "cwd": "${workspaceFolder}/Payload_Type/sliverimplant", 25 | "consoleTitle": "SliverImplant", 26 | "justMyCode": false 27 | }, 28 | ], 29 | "compounds": [ 30 | { 31 | "name": "SliverApi && SliverImplant", 32 | "configurations": [ 33 | "SliverApi", 34 | "SliverImplant" 35 | ] 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2024, Spencer Adolph 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/licenses.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class LicensesArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Licenses(CommandBase): 17 | cmd = "licenses" 18 | needs_admin = False 19 | help_cmd = "licenses" 20 | description = "Open source licenses" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = LicensesArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Open source licenses 28 | 29 | response = await licenses(taskData) 30 | 31 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 32 | TaskID=taskData.Task.ID, 33 | Response=response.encode("UTF8"), 34 | )) 35 | 36 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 37 | TaskID=taskData.Task.ID, 38 | Success=True, 39 | Completed=True 40 | ) 41 | 42 | return taskResponse 43 | 44 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 45 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 46 | return resp 47 | 48 | 49 | async def licenses(taskData: PTTaskMessageAllData): 50 | # TODO: match sliver formatting 51 | 52 | # This is just hard-coded in the real client 53 | return "https://github.com/BishopFox/sliver/blob/master/client/licenses/licenses.go" 54 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/SliverRequests/SliverAPI.py: -------------------------------------------------------------------------------- 1 | from mythic_container.MythicCommandBase import PTTaskMessageAllData 2 | from mythic_container.MythicRPC import SendMythicRPCFileGetContent, MythicRPCFileGetContentMessage 3 | from sliver import SliverClientConfig, SliverClient, client_pb2, sliver_pb2 4 | from mythic_container.MythicCommandBase import * 5 | from mythic_container.MythicRPC import * 6 | from mythic_container.PayloadBuilder import * 7 | import json 8 | 9 | from mythic_container.LoggingBase import * 10 | from mythic_container.MythicGoRPC import * 11 | 12 | from sliver import InteractiveBeacon 13 | 14 | # TODO: make this better, if using identify all fields that will be used / handle emptying when exiting 15 | sliver_clients = {} 16 | 17 | async def create_sliver_interact(taskData: PTTaskMessageAllData): 18 | # check to see if its cached 19 | if (f"{taskData.Callback.ID}" in sliver_clients.keys()): 20 | return sliver_clients[f"{taskData.Callback.ID}"]['interact'], isinstance(sliver_clients[f"{taskData.Callback.ID}"]['interact'], InteractiveBeacon) 21 | 22 | extraInfoObj = json.loads(taskData.Callback.ExtraInfo) 23 | configfile = extraInfoObj['slivercfg_fileid'] 24 | 25 | # otherwise get it 26 | filecontent = await SendMythicRPCFileGetContent(MythicRPCFileGetContentMessage( 27 | AgentFileId=configfile 28 | )) 29 | 30 | config = SliverClientConfig.parse_config(filecontent.Content) 31 | client = SliverClient(config) 32 | await client.connect() 33 | 34 | callback_extra_info = json.loads(taskData.Callback.ExtraInfo) 35 | isBeacon = callback_extra_info['type'] == 'beacon' 36 | if (isBeacon): 37 | interact = await client.interact_beacon(taskData.Payload.UUID) 38 | else: 39 | interact = await client.interact_session(taskData.Payload.UUID) 40 | 41 | # cache it for later 42 | # TODO: memory leak if this never gets removed? (why useful to implement 'exit' command) 43 | sliver_clients[f"{taskData.Callback.ID}"] = { 44 | 'interact': interact, 45 | } 46 | 47 | return interact, isBeacon 48 | 49 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/getpid.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class GetpidArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Getpid(CommandBase): 17 | cmd = "getpid" 18 | needs_admin = False 19 | help_cmd = "getpid" 20 | description = "Get session pid" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = GetpidArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Get session pid 28 | 29 | # Usage: 30 | # ====== 31 | # getpid [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # -h, --help display help 36 | # -t, --timeout int command timeout in seconds (default: 60) 37 | 38 | pid_results = await getpid(taskData) 39 | 40 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 41 | TaskID=taskData.Task.ID, 42 | Response=pid_results.encode("UTF8"), 43 | )) 44 | 45 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 46 | TaskID=taskData.Task.ID, 47 | Success=True, 48 | Completed=True 49 | ) 50 | return taskResponse 51 | 52 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 53 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 54 | return resp 55 | 56 | async def getpid(taskData: PTTaskMessageAllData): 57 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 58 | return f"{interact.pid}" 59 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/getuid.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class GetuidArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Getuid(CommandBase): 17 | cmd = "getuid" 18 | needs_admin = False 19 | help_cmd = "getuid" 20 | description = "Get session process uid" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = GetuidArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Get session process uid 28 | 29 | # Usage: 30 | # ====== 31 | # getuid [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # -h, --help display help 36 | # -t, --timeout int command timeout in seconds (default: 60) 37 | 38 | uid_results = await getuid(taskData) 39 | 40 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 41 | TaskID=taskData.Task.ID, 42 | Response=uid_results.encode("UTF8"), 43 | )) 44 | 45 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 46 | TaskID=taskData.Task.ID, 47 | Success=True, 48 | Completed=True 49 | ) 50 | return taskResponse 51 | 52 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 53 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 54 | return resp 55 | 56 | async def getuid(taskData: PTTaskMessageAllData): 57 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 58 | return f"{interact.uid}" 59 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/getgid.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class GetgidArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Getgid(CommandBase): 17 | cmd = "getgid" 18 | needs_admin = False 19 | help_cmd = "getgid" 20 | description = "Get session process GID" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = GetgidArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Get session process GID 28 | 29 | # Usage: 30 | # ====== 31 | # getgid [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # -h, --help display help 36 | # -t, --timeout int command timeout in seconds (default: 60) 37 | 38 | gid_results = await getgid(taskData) 39 | 40 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 41 | TaskID=taskData.Task.ID, 42 | Response=gid_results.encode("UTF8"), 43 | )) 44 | 45 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 46 | TaskID=taskData.Task.ID, 47 | Success=True, 48 | Completed=True 49 | ) 50 | return taskResponse 51 | 52 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 53 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 54 | return resp 55 | 56 | async def getgid(taskData: PTTaskMessageAllData): 57 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 58 | return f"{interact.gid}" 59 | 60 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/whoami.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class WhoamiArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Whoami(CommandBase): 17 | cmd = "whoami" 18 | needs_admin = False 19 | help_cmd = "whoami" 20 | description = "Get session user execution context" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = WhoamiArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Get session user execution context 28 | 29 | # Usage: 30 | # ====== 31 | # whoami [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # -h, --help display help 36 | # -t, --timeout int command timeout in seconds (default: 60) 37 | 38 | whoami_results = await whoami(taskData) 39 | 40 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 41 | TaskID=taskData.Task.ID, 42 | Response=whoami_results.encode("UTF8"), 43 | )) 44 | 45 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 46 | TaskID=taskData.Task.ID, 47 | Success=True, 48 | Completed=True 49 | ) 50 | return taskResponse 51 | 52 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 53 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 54 | return resp 55 | 56 | async def whoami(taskData: PTTaskMessageAllData): 57 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 58 | 59 | # TODO: this is special for windows 60 | 61 | return f"Logon ID: {interact.username}" 62 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/operators.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | # from sliver import common_pb2 8 | 9 | class OperatorsArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Operators(CommandBase): 19 | cmd = "operators" 20 | needs_admin = False 21 | help_cmd = "operators" 22 | description = "Manage operators" 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = OperatorsArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Manage operators 30 | 31 | # Usage: 32 | # ====== 33 | # operators [flags] 34 | 35 | # Flags: 36 | # ====== 37 | # -h, --help display help 38 | # -t, --timeout int command timeout in seconds (default: 60) 39 | 40 | response = await operators(taskData) 41 | 42 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 43 | TaskID=taskData.Task.ID, 44 | Response=response.encode("UTF8"), 45 | )) 46 | 47 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 48 | TaskID=taskData.Task.ID, 49 | Success=True, 50 | Completed=True 51 | ) 52 | 53 | return taskResponse 54 | 55 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 56 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 57 | return resp 58 | 59 | 60 | async def operators(taskData: PTTaskMessageAllData): 61 | client = await SliverAPI.create_sliver_client(taskData) 62 | 63 | operators_results = await client.operators() 64 | 65 | # TODO: match sliver formatting 66 | 67 | return f"{operators_results}" 68 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/canaries.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | 8 | class CanariesArguments(TaskArguments): 9 | def __init__(self, command_line, **kwargs): 10 | super().__init__(command_line, **kwargs) 11 | self.args = [] 12 | 13 | async def parse_arguments(self): 14 | pass 15 | 16 | 17 | class Canaries(CommandBase): 18 | cmd = "canaries" 19 | needs_admin = False 20 | help_cmd = "canaries" 21 | description = "List previously generated canaries" 22 | version = 1 23 | author = "Spencer Adolph" 24 | argument_class = CanariesArguments 25 | attackmapping = [] 26 | 27 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 28 | # List previously generated canaries 29 | 30 | # Usage: 31 | # ====== 32 | # canaries [flags] 33 | 34 | # Flags: 35 | # ====== 36 | # TODO: -b, --burned show only triggered/burned canaries 37 | # -h, --help display help 38 | # -t, --timeout int command timeout in seconds (default: 60) 39 | 40 | response = await canaries(taskData) 41 | 42 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 43 | TaskID=taskData.Task.ID, 44 | Response=response.encode("UTF8"), 45 | )) 46 | 47 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 48 | TaskID=taskData.Task.ID, 49 | Success=True, 50 | Completed=True 51 | ) 52 | 53 | return taskResponse 54 | 55 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 56 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 57 | return resp 58 | 59 | 60 | async def canaries(taskData: PTTaskMessageAllData): 61 | client = await SliverAPI.create_sliver_client(taskData) 62 | 63 | canaries_list = await client.canaries() 64 | 65 | # TODO: match sliver formatting 66 | 67 | return f"{canaries_list}" 68 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/builders.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | 8 | class BuildersArguments(TaskArguments): 9 | def __init__(self, command_line, **kwargs): 10 | super().__init__(command_line, **kwargs) 11 | self.args = [] 12 | 13 | async def parse_arguments(self): 14 | pass 15 | 16 | 17 | class Builders(CommandBase): 18 | cmd = "builders" 19 | needs_admin = False 20 | help_cmd = "builders" 21 | description = "Lists external builders currently registered with the server." 22 | version = 1 23 | author = "Spencer Adolph" 24 | argument_class = BuildersArguments 25 | attackmapping = [] 26 | 27 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 28 | # Command: builders 29 | # About: Lists external builders currently registered with the server. 30 | 31 | # External builders allow the Sliver server offload implant builds onto external machines. 32 | # For more information: https://github.com/BishopFox/sliver/wiki/External-Builders 33 | 34 | # Usage: 35 | # ====== 36 | # builders [flags] 37 | 38 | response = await builders(taskData) 39 | 40 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 41 | TaskID=taskData.Task.ID, 42 | Response=response.encode("UTF8"), 43 | )) 44 | 45 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 46 | TaskID=taskData.Task.ID, 47 | Success=True, 48 | Completed=True 49 | ) 50 | 51 | return taskResponse 52 | 53 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 54 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 55 | return resp 56 | 57 | 58 | async def builders(taskData: PTTaskMessageAllData): 59 | # client = await SliverAPI.create_sliver_client(taskData) 60 | # client._stub.bu 61 | 62 | # TODO: match sliver formatting 63 | 64 | return "This command not yet implemented, requires re-build of gRPC (or sliver 1.6)" 65 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/ifconfig.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class IfconfigArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Ifconfig(CommandBase): 17 | cmd = "ifconfig" 18 | needs_admin = False 19 | help_cmd = "ifconfig" 20 | description = "View network interface configurations" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = IfconfigArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # View network interface configurations 28 | 29 | # Usage: 30 | # ====== 31 | # ifconfig [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # TODO: -A, --all show all network adapters (default only shows IPv4) 36 | # -h, --help display help 37 | # -t, --timeout int command timeout in seconds (default: 60) 38 | 39 | ifconfig_results = await ifconfig(taskData) 40 | 41 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 42 | TaskID=taskData.Task.ID, 43 | Response=f"{str(ifconfig_results)}".encode("UTF8"), 44 | )) 45 | 46 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 47 | TaskID=taskData.Task.ID, 48 | Success=True, 49 | Completed=True 50 | ) 51 | return taskResponse 52 | 53 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 54 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 55 | return resp 56 | 57 | async def ifconfig(taskData: PTTaskMessageAllData): 58 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 59 | 60 | ifconfig_results = await interact.ifconfig() 61 | 62 | if (isBeacon): 63 | ifconfig_results = await ifconfig_results 64 | 65 | return ifconfig_results 66 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/memfiles.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class MemfilesArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Memfiles(CommandBase): 17 | cmd = "memfiles" 18 | needs_admin = False 19 | help_cmd = "memfiles" 20 | description = "List current memfiles" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = MemfilesArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # List current memfiles 28 | 29 | # Usage: 30 | # ====== 31 | # memfiles [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # -h, --help display help 36 | # -t, --timeout int command timeout in seconds (default: 60) 37 | 38 | # Sub Commands: 39 | # ============= 40 | # TODO: add Add a memfile 41 | # TODO: rm Remove a memfile 42 | 43 | response = await memfiles(taskData) 44 | 45 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 46 | TaskID=taskData.Task.ID, 47 | Response=response.encode("UTF8"), 48 | )) 49 | 50 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 51 | TaskID=taskData.Task.ID, 52 | Success=True, 53 | Completed=True 54 | ) 55 | return taskResponse 56 | 57 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 58 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 59 | return resp 60 | 61 | async def memfiles(taskData: PTTaskMessageAllData): 62 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 63 | 64 | # ifconfig_results = await interact._stub() 65 | 66 | # if (isBeacon): 67 | # ifconfig_results = await ifconfig_results 68 | 69 | return "This command not yet implemented..." 70 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/pwd.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | from sliver import sliver_pb2 8 | 9 | class PwdArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Pwd(CommandBase): 19 | cmd = "pwd" 20 | needs_admin = False 21 | help_cmd = "pwd" 22 | description = "Print working directory of the active session." 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = PwdArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Command: pwd 30 | # About: Print working directory of the active session. 31 | 32 | # Usage: 33 | # ====== 34 | # pwd [flags] 35 | 36 | # Flags: 37 | # ====== 38 | # -h, --help display help 39 | # -t, --timeout int command timeout in seconds (default: 60) 40 | 41 | response = await pwd(taskData) 42 | 43 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 44 | TaskID=taskData.Task.ID, 45 | Response=response.encode("UTF8"), 46 | )) 47 | 48 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 49 | TaskID=taskData.Task.ID, 50 | Success=True, 51 | Completed=True 52 | ) 53 | return taskResponse 54 | 55 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 56 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 57 | return resp 58 | 59 | 60 | async def pwd(taskData: PTTaskMessageAllData): 61 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 62 | 63 | pwd_results = await interact.pwd() 64 | 65 | # pwd_results = await interact._stub.Pwd(interact._request(sliver_pb2.PwdReq())) 66 | 67 | if (isBeacon): 68 | pwd_results = await pwd_results 69 | 70 | return f"{pwd_results}" 71 | 72 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/socks5.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class Socks5Arguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Socks5(CommandBase): 17 | cmd = "socks5" 18 | needs_admin = False 19 | help_cmd = "socks5" 20 | description = "In-band SOCKS5 Proxy" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = Socks5Arguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # In-band SOCKS5 Proxy 28 | 29 | # Usage: 30 | # ====== 31 | # socks5 [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # -h, --help display help 36 | # -t, --timeout int router timeout in seconds (default: 60) 37 | 38 | # Sub Commands: 39 | # ============= 40 | # TODO: start Start an in-band SOCKS5 proxy 41 | # TODO: stop Stop a SOCKS5 proxy 42 | 43 | response = await socks5(taskData) 44 | 45 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 46 | TaskID=taskData.Task.ID, 47 | Response=response.encode("UTF8"), 48 | )) 49 | 50 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 51 | TaskID=taskData.Task.ID, 52 | Success=True, 53 | Completed=True 54 | ) 55 | return taskResponse 56 | 57 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 58 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 59 | return resp 60 | 61 | async def socks5(taskData: PTTaskMessageAllData): 62 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 63 | 64 | # ifconfig_results = await interact._stub() 65 | 66 | # if (isBeacon): 67 | # ifconfig_results = await ifconfig_results 68 | 69 | return "This command not yet implemented..." 70 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/hosts.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | from sliver import common_pb2 8 | 9 | class HostsArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Hosts(CommandBase): 19 | cmd = "hosts" 20 | needs_admin = False 21 | help_cmd = "hosts" 22 | description = "Manage the database of hosts" 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = HostsArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Manage the database of hosts 30 | 31 | # Usage: 32 | # ====== 33 | # hosts [flags] 34 | 35 | # Flags: 36 | # ====== 37 | # -h, --help display help 38 | # -t, --timeout int command timeout in seconds (default: 60) 39 | 40 | # Sub Commands: 41 | # ============= 42 | # TODO: ioc Manage tracked IOCs on a given host 43 | # TODO: rm Remove a host from the database 44 | 45 | response = await hosts(taskData) 46 | 47 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 48 | TaskID=taskData.Task.ID, 49 | Response=response.encode("UTF8"), 50 | )) 51 | 52 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 53 | TaskID=taskData.Task.ID, 54 | Success=True, 55 | Completed=True 56 | ) 57 | 58 | return taskResponse 59 | 60 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 61 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 62 | return resp 63 | 64 | 65 | async def hosts(taskData: PTTaskMessageAllData): 66 | client = await SliverAPI.create_sliver_client(taskData) 67 | 68 | hosts_list = await client._stub.Hosts(common_pb2.Empty()) 69 | 70 | # TODO: match sliver formatting 71 | 72 | return f"{hosts_list}" 73 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/ping.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class PingArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Ping(CommandBase): 17 | cmd = "ping" 18 | needs_admin = False 19 | help_cmd = "ping" 20 | description = "sends a small C2 message round trip" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = PingArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Command: ping 28 | # About: Ping session by name or the active session. This does NOT send an ICMP packet, it just sends a small 29 | # C2 message round trip to ensure the remote implant is still responding to commands. 30 | 31 | # Usage: 32 | # ====== 33 | # ping [flags] 34 | 35 | # Flags: 36 | # ====== 37 | # -h, --help display help 38 | # -t, --timeout int command timeout in seconds (default: 60) 39 | 40 | ping_results = await ping(taskData) 41 | 42 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 43 | TaskID=taskData.Task.ID, 44 | Response=ping_results.encode("UTF8"), 45 | )) 46 | 47 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 48 | TaskID=taskData.Task.ID, 49 | Success=True, 50 | Completed=True 51 | ) 52 | return taskResponse 53 | 54 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 55 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 56 | return resp 57 | 58 | async def ping(taskData: PTTaskMessageAllData): 59 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 60 | ping_result = await interact.ping() 61 | 62 | if (isBeacon): 63 | ping_result = await ping_result 64 | 65 | return f"{ping_result}" 66 | 67 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/portfwd.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class PortfwdArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Portfwd(CommandBase): 17 | cmd = "portfwd" 18 | needs_admin = False 19 | help_cmd = "portfwd" 20 | description = "In-band TCP port forwarding" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = PortfwdArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # In-band TCP port forwarding 28 | 29 | # Usage: 30 | # ====== 31 | # portfwd [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # -h, --help display help 36 | # -t, --timeout int command timeout in seconds (default: 60) 37 | 38 | # Sub Commands: 39 | # ============= 40 | # TODO: add Create a new port forwarding tunnel 41 | # TODO: rm Remove a port forwarding tunnel 42 | 43 | response = await portfwd(taskData) 44 | 45 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 46 | TaskID=taskData.Task.ID, 47 | Response=response.encode("UTF8"), 48 | )) 49 | 50 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 51 | TaskID=taskData.Task.ID, 52 | Success=True, 53 | Completed=True 54 | ) 55 | return taskResponse 56 | 57 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 58 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 59 | return resp 60 | 61 | async def portfwd(taskData: PTTaskMessageAllData): 62 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 63 | 64 | # ifconfig_results = await interact._stub() 65 | 66 | # if (isBeacon): 67 | # ifconfig_results = await ifconfig_results 68 | 69 | return "This command not yet implemented..." 70 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/rportfwd.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class RportfwdArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Rportfwd(CommandBase): 17 | cmd = "rportfwd" 18 | needs_admin = False 19 | help_cmd = "rportfwd" 20 | description = "reverse port forwardings" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = RportfwdArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # reverse port forwardings 28 | 29 | # Usage: 30 | # ====== 31 | # rportfwd [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # -h, --help display help 36 | # -t, --timeout int command timeout in seconds (default: 60) 37 | 38 | # Sub Commands: 39 | # ============= 40 | # TODO: add Add and start reverse port forwarding 41 | # TODO: rm Stop and remove reverse port forwarding 42 | 43 | response = await rportfwd(taskData) 44 | 45 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 46 | TaskID=taskData.Task.ID, 47 | Response=response.encode("UTF8"), 48 | )) 49 | 50 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 51 | TaskID=taskData.Task.ID, 52 | Success=True, 53 | Completed=True 54 | ) 55 | return taskResponse 56 | 57 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 58 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 59 | return resp 60 | 61 | async def rportfwd(taskData: PTTaskMessageAllData): 62 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 63 | 64 | # ifconfig_results = await interact._stub() 65 | 66 | # if (isBeacon): 67 | # ifconfig_results = await ifconfig_results 68 | 69 | return "This command not yet implemented..." 70 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/kill.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | from sliver import sliver_pb2, client_pb2 8 | 9 | 10 | class KillArguments(TaskArguments): 11 | def __init__(self, command_line, **kwargs): 12 | super().__init__(command_line, **kwargs) 13 | self.args = [] 14 | 15 | async def parse_arguments(self): 16 | pass 17 | 18 | 19 | class Kill(CommandBase): 20 | cmd = "kill" 21 | needs_admin = False 22 | help_cmd = "kill" 23 | description = "Kill a remote implant process (does not delete file)" 24 | version = 1 25 | author = "Spencer Adolph" 26 | argument_class = KillArguments 27 | attackmapping = [] 28 | 29 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 30 | # Command: kill 31 | # About: Kill a remote implant process (does not delete file). 32 | 33 | # Usage: 34 | # ====== 35 | # kill [flags] 36 | 37 | # Flags: 38 | # ====== 39 | # TODO: -F, --force Force kill, does not clean up 40 | # -h, --help display help 41 | # -t, --timeout int command timeout in seconds (default: 60) 42 | 43 | response = await kill(taskData) 44 | 45 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 46 | TaskID=taskData.Task.ID, 47 | Response=response.encode("UTF8"), 48 | )) 49 | 50 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 51 | TaskID=taskData.Task.ID, 52 | Success=True, 53 | Completed=True 54 | ) 55 | return taskResponse 56 | 57 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 58 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 59 | return resp 60 | 61 | async def kill(taskData: PTTaskMessageAllData): 62 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 63 | 64 | # TODO: not sure how to wait for this 65 | kill_results = await interact._stub.Kill(interact._request(sliver_pb2.KillReq())) 66 | 67 | # if (isBeacon): 68 | # kill_results = await kill_results 69 | 70 | return "Tasked Kill!" 71 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/version.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | 8 | class VersionArguments(TaskArguments): 9 | def __init__(self, command_line, **kwargs): 10 | super().__init__(command_line, **kwargs) 11 | self.args = [] 12 | 13 | async def parse_arguments(self): 14 | pass 15 | 16 | 17 | class Version(CommandBase): 18 | cmd = "version" 19 | needs_admin = False 20 | help_cmd = "version" 21 | description = "Display version information" 22 | version = 1 23 | author = "Spencer Adolph" 24 | argument_class = VersionArguments 25 | attackmapping = [] 26 | 27 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 28 | # Display version information 29 | 30 | # Usage: 31 | # ====== 32 | # version [flags] 33 | 34 | # Flags: 35 | # ====== 36 | # -h, --help display help 37 | # -t, --timeout int command timeout in seconds (default: 60) 38 | 39 | response = await version(taskData) 40 | 41 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 42 | TaskID=taskData.Task.ID, 43 | Response=response.encode("UTF8"), 44 | )) 45 | 46 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 47 | TaskID=taskData.Task.ID, 48 | Success=True, 49 | Completed=True, 50 | ) 51 | 52 | return taskResponse 53 | 54 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 55 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 56 | return resp 57 | 58 | 59 | async def version(taskData: PTTaskMessageAllData): 60 | client = await SliverAPI.create_sliver_client(taskData) 61 | version_results = await client.version() 62 | 63 | # TODO: match sliver formatting 64 | 65 | # [*] Client v1.5.42 - 85b0e870d05ec47184958dbcb871ddee2eb9e3df - linux/amd64 66 | # Compiled at 2024-02-28 13:46:53 -0600 CST 67 | # Compiled with go version go1.20.7 linux/amd64 68 | 69 | 70 | # [*] Server v1.5.42 - 85b0e870d05ec47184958dbcb871ddee2eb9e3df - linux/amd64 71 | # Compiled at 2024-02-28 13:46:53 -0600 CST 72 | 73 | return f"{version_results}" 74 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/chown.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class ChownArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Chown(CommandBase): 17 | cmd = "chown" 18 | needs_admin = False 19 | help_cmd = "chown" 20 | description = "Change owner on a file or directory" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = ChownArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Change owner on a file or directory 28 | 29 | # Usage: 30 | # ====== 31 | # chown [flags] path uid gid 32 | 33 | # Args: 34 | # ===== 35 | # path string path to the file to remove 36 | # uid string User, e.g. root 37 | # gid string Group, e.g. root 38 | 39 | # Flags: 40 | # ====== 41 | # -h, --help display help 42 | # TODO: -r, --recursive recursively change permissions on files 43 | # -t, --timeout int command timeout in seconds (default: 60) 44 | 45 | response = await chown(taskData) 46 | 47 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 48 | TaskID=taskData.Task.ID, 49 | Response=response.encode("UTF8"), 50 | )) 51 | 52 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 53 | TaskID=taskData.Task.ID, 54 | Success=True, 55 | Completed=True 56 | ) 57 | return taskResponse 58 | 59 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 60 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 61 | return resp 62 | 63 | async def chown(taskData: PTTaskMessageAllData): 64 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 65 | 66 | # ifconfig_results = await interact._stub() 67 | 68 | # if (isBeacon): 69 | # ifconfig_results = await ifconfig_results 70 | 71 | return "This command not yet implemented..." 72 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/chtimes.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class ChtimesArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Chtimes(CommandBase): 17 | cmd = "chtimes" 18 | needs_admin = False 19 | help_cmd = "chtimes" 20 | description = "Change access and modification times on a file (timestomp)" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = ChtimesArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Change access and modification times on a file (timestomp) 28 | 29 | # Usage: 30 | # ====== 31 | # chtimes [flags] path atime mtime 32 | 33 | # Args: 34 | # ===== 35 | # path string path to the file to remove 36 | # atime string Last accessed time in DateTime format, i.e. 2006-01-02 15:04:05 37 | # mtime string Last modified time in DateTime format, i.e. 2006-01-02 15:04:05 38 | 39 | # Flags: 40 | # ====== 41 | # -h, --help display help 42 | # -t, --timeout int command timeout in seconds (default: 60) 43 | 44 | response = await chtimes(taskData) 45 | 46 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 47 | TaskID=taskData.Task.ID, 48 | Response=response.encode("UTF8"), 49 | )) 50 | 51 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 52 | TaskID=taskData.Task.ID, 53 | Success=True, 54 | Completed=True 55 | ) 56 | return taskResponse 57 | 58 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 59 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 60 | return resp 61 | 62 | async def chtimes(taskData: PTTaskMessageAllData): 63 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 64 | 65 | # ifconfig_results = await interact._stub() 66 | 67 | # if (isBeacon): 68 | # ifconfig_results = await ifconfig_results 69 | 70 | return "This command not yet implemented..." 71 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/extensions.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class ExtensionsArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Extensions(CommandBase): 17 | cmd = "extensions" 18 | needs_admin = False 19 | help_cmd = "extensions" 20 | description = "Manage extensions" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = ExtensionsArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Manage extensions 28 | 29 | # Usage: 30 | # ====== 31 | # extensions [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # -h, --help display help 36 | # -t, --timeout int command timeout in seconds (default: 60) 37 | 38 | # Sub Commands: 39 | # ============= 40 | # TODO: install Install an extension from a local directory or .tar.gz file 41 | # TODO: list List extensions loaded in the current session or beacon 42 | # TODO: load Temporarily load an extension from a local directory 43 | # TODO: rm Remove an installed extension 44 | 45 | response = await extensions(taskData) 46 | 47 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 48 | TaskID=taskData.Task.ID, 49 | Response=response.encode("UTF8"), 50 | )) 51 | 52 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 53 | TaskID=taskData.Task.ID, 54 | Success=True, 55 | Completed=True 56 | ) 57 | return taskResponse 58 | 59 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 60 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 61 | return resp 62 | 63 | async def extensions(taskData: PTTaskMessageAllData): 64 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 65 | 66 | # ifconfig_results = await interact._stub() 67 | 68 | # if (isBeacon): 69 | # ifconfig_results = await ifconfig_results 70 | 71 | return "This command not yet implemented..." 72 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/cd.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | 4 | from mythic_container.MythicCommandBase import * 5 | from mythic_container.MythicRPC import * 6 | from mythic_container.PayloadBuilder import * 7 | 8 | class CdArguments(TaskArguments): 9 | def __init__(self, command_line, **kwargs): 10 | super().__init__(command_line, **kwargs) 11 | self.args = [ 12 | CommandParameter( 13 | name="path", 14 | description="path to cd to", 15 | type=ParameterType.String 16 | ), 17 | ] 18 | 19 | async def parse_arguments(self): 20 | self.load_args_from_json_string(self.command_line) 21 | 22 | 23 | class Cd(CommandBase): 24 | cmd = "cd" 25 | needs_admin = False 26 | help_cmd = "cd" 27 | description = "Change directories" 28 | version = 1 29 | author = "Spencer Adolph" 30 | argument_class = CdArguments 31 | attackmapping = [] 32 | 33 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 34 | # Command: cd [remote path] 35 | # About: Change working directory of the active session. 36 | 37 | # Usage: 38 | # ====== 39 | # cd [flags] [path] 40 | 41 | # Args: 42 | # ===== 43 | # path string path to the directory (default: .) 44 | 45 | # Flags: 46 | # ====== 47 | # -h, --help display help 48 | # -t, --timeout int command timeout in seconds (default: 60) 49 | 50 | response = await cd(taskData, taskData.args.get_arg('path')) 51 | 52 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 53 | TaskID=taskData.Task.ID, 54 | Response=response.encode("UTF8"), 55 | )) 56 | 57 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 58 | TaskID=taskData.Task.ID, 59 | Success=True, 60 | Completed=True 61 | ) 62 | return taskResponse 63 | 64 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 65 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 66 | return resp 67 | 68 | async def cd(taskData: PTTaskMessageAllData, remote_path: str): 69 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 70 | 71 | cd_results = await interact.cd(remote_path=remote_path) 72 | 73 | if (isBeacon): 74 | cd_results = await cd_results 75 | 76 | return f"{cd_results}" 77 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/dns.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | 8 | class DnsArguments(TaskArguments): 9 | def __init__(self, command_line, **kwargs): 10 | super().__init__(command_line, **kwargs) 11 | self.args = [] 12 | 13 | async def parse_arguments(self): 14 | pass 15 | 16 | 17 | class Dns(CommandBase): 18 | cmd = "dns" 19 | needs_admin = False 20 | help_cmd = "dns" 21 | description = "Start a DNS listener" 22 | version = 1 23 | author = "Spencer Adolph" 24 | argument_class = DnsArguments 25 | attackmapping = [] 26 | 27 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 28 | # Start a DNS listener 29 | 30 | # Usage: 31 | # ====== 32 | # dns [flags] 33 | 34 | # Flags: 35 | # ====== 36 | # TODO: -D, --disable-otp disable otp authentication 37 | # TODO: -d, --domains string parent domain(s) to use for DNS c2 38 | # -h, --help display help 39 | # TODO: -L, --lhost string interface to bind server to 40 | # TODO: -l, --lport int udp listen port (default: 53) 41 | # TODO: -c, --no-canaries disable dns canary detection 42 | # TODO: -p, --persistent make persistent across restarts 43 | # -t, --timeout int command timeout in seconds (default: 60) 44 | 45 | response = await dns(taskData) 46 | 47 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 48 | TaskID=taskData.Task.ID, 49 | Response=response.encode("UTF8"), 50 | )) 51 | 52 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 53 | TaskID=taskData.Task.ID, 54 | Success=True, 55 | Completed=True 56 | ) 57 | 58 | return taskResponse 59 | 60 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 61 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 62 | return resp 63 | 64 | 65 | async def dns(taskData: PTTaskMessageAllData): 66 | client = await SliverAPI.create_sliver_client(taskData) 67 | 68 | dns_results = await client.start_dns_listener(domains=['1.example.com.'], host='192.168.17.129') 69 | 70 | # TODO: match sliver formatting 71 | 72 | return f"{dns_results}" 73 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/armory.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | # from sliver import common_pb2 8 | 9 | class ArmoryArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Armory(CommandBase): 19 | cmd = "armory" 20 | needs_admin = False 21 | help_cmd = "armory" 22 | description = "Automatically download and install extensions/aliases" 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = ArmoryArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Automatically download and install extensions/aliases 30 | 31 | # Usage: 32 | # ====== 33 | # armory [flags] 34 | 35 | # Flags: 36 | # ====== 37 | # TODO: -c, --ignore-cache ignore metadata cache, force refresh 38 | # TODO: -I, --insecure skip tls certificate validation 39 | # TODO: -p, --proxy string specify a proxy url (e.g. http://localhost:8080) 40 | 41 | # Sub Commands: 42 | # ============= 43 | # TODO: install Install an alias or extension 44 | # TODO: search Search for aliases and extensions by name (regex) 45 | # TODO: update Update installed an aliases and extensions 46 | 47 | response = await armory(taskData) 48 | 49 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 50 | TaskID=taskData.Task.ID, 51 | Response=response.encode("UTF8"), 52 | )) 53 | 54 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 55 | TaskID=taskData.Task.ID, 56 | Success=True, 57 | Completed=True 58 | ) 59 | 60 | return taskResponse 61 | 62 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 63 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 64 | return resp 65 | 66 | 67 | async def armory(taskData: PTTaskMessageAllData): 68 | # client = await SliverAPI.create_sliver_client(taskData) 69 | 70 | # armory_results = await client.armory() 71 | 72 | # TODO: match sliver formatting 73 | 74 | return "This command not yet implemented..." 75 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/msf.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class MsfArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Msf(CommandBase): 17 | cmd = "msf" 18 | needs_admin = False 19 | help_cmd = "msf" 20 | description = "Execute a metasploit payload in the current process" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = MsfArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Command: msf [--lhost] 28 | # About: Execute a metasploit payload in the current process. 29 | 30 | # Usage: 31 | # ====== 32 | # msf [flags] 33 | 34 | # Flags: 35 | # ====== 36 | # TODO: -e, --encoder string msf encoder 37 | # -h, --help display help 38 | # TODO: -i, --iterations int iterations of the encoder (default: 1) 39 | # TODO: -L, --lhost string listen host 40 | # TODO: -l, --lport int listen port (default: 4444) 41 | # TODO: -m, --payload string msf payload (default: meterpreter_reverse_https) 42 | # -t, --timeout int command timeout in seconds (default: 60) 43 | 44 | response = await msf(taskData) 45 | 46 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 47 | TaskID=taskData.Task.ID, 48 | Response=response.encode("UTF8"), 49 | )) 50 | 51 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 52 | TaskID=taskData.Task.ID, 53 | Success=True, 54 | Completed=True 55 | ) 56 | return taskResponse 57 | 58 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 59 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 60 | return resp 61 | 62 | async def msf(taskData: PTTaskMessageAllData): 63 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 64 | 65 | # ifconfig_results = await interact._stub() 66 | 67 | # if (isBeacon): 68 | # ifconfig_results = await ifconfig_results 69 | 70 | return "This command not yet implemented..." 71 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/pivots.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class PivotsArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Pivots(CommandBase): 17 | cmd = "pivots" 18 | needs_admin = False 19 | help_cmd = "pivots" 20 | description = "List pivots for the current session" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = PivotsArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Command: pivots 28 | # About: List pivots for the current session. NOTE: pivots are only supported on sessions, not beacons. 29 | 30 | # Usage: 31 | # ====== 32 | # pivots [flags] 33 | 34 | # Flags: 35 | # ====== 36 | # -h, --help display help 37 | # -t, --timeout int command timeout in seconds (default: 60) 38 | 39 | # Sub Commands: 40 | # ============= 41 | # TODO: details Get details of a pivot listener 42 | # TODO: graph Get details of a pivot listener 43 | # TODO: named-pipe Start a named pipe pivot listener 44 | # TODO: stop Stop a pivot listener 45 | # TODO: tcp Start a TCP pivot listener 46 | 47 | response = await pivots(taskData) 48 | 49 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 50 | TaskID=taskData.Task.ID, 51 | Response=response.encode("UTF8"), 52 | )) 53 | 54 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 55 | TaskID=taskData.Task.ID, 56 | Success=True, 57 | Completed=True 58 | ) 59 | return taskResponse 60 | 61 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 62 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 63 | return resp 64 | 65 | async def pivots(taskData: PTTaskMessageAllData): 66 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 67 | 68 | # ifconfig_results = await interact._stub() 69 | 70 | # if (isBeacon): 71 | # ifconfig_results = await ifconfig_results 72 | 73 | return "This command not yet implemented..." 74 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/procdump.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class ProcdumpArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Procdump(CommandBase): 17 | cmd = "procdump" 18 | needs_admin = False 19 | help_cmd = "procdump" 20 | description = "Dumps the process memory given a process identifier" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = ProcdumpArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Command: procdump [pid] 28 | # About: Dumps the process memory given a process identifier (pid) 29 | 30 | # Usage: 31 | # ====== 32 | # procdump [flags] 33 | 34 | # Flags: 35 | # ====== 36 | # -h, --help display help 37 | # TODO: -X, --loot save output as loot 38 | # TODO: -N, --loot-name string name to assign when adding the memory dump to the loot store (optional) 39 | # TODO: -n, --name string target process name 40 | # TODO: -p, --pid int target pid (default: -1) 41 | # TODO: -s, --save string save to file (will overwrite if exists) 42 | # -t, --timeout int command timeout in seconds (default: 60) 43 | 44 | response = await procdump(taskData) 45 | 46 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 47 | TaskID=taskData.Task.ID, 48 | Response=response.encode("UTF8"), 49 | )) 50 | 51 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 52 | TaskID=taskData.Task.ID, 53 | Success=True, 54 | Completed=True 55 | ) 56 | return taskResponse 57 | 58 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 59 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 60 | return resp 61 | 62 | async def procdump(taskData: PTTaskMessageAllData): 63 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 64 | 65 | # ifconfig_results = await interact._stub() 66 | 67 | # if (isBeacon): 68 | # ifconfig_results = await ifconfig_results 69 | 70 | return "This command not yet implemented..." 71 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/chmod.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class ChmodArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Chmod(CommandBase): 17 | cmd = "chmod" 18 | needs_admin = False 19 | help_cmd = "chmod" 20 | description = "Change permissions on a file or directory" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = ChmodArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Change permissions on a file or directory 28 | 29 | # Usage: 30 | # ====== 31 | # chmod [flags] path mode 32 | 33 | # Args: 34 | # ===== 35 | # path string path to the file to remove 36 | # mode string file permissions in octal, e.g. 0644 37 | 38 | # Flags: 39 | # ====== 40 | # -h, --help display help 41 | # TODO: -r, --recursive recursively change permissions on files 42 | # -t, --timeout int command timeout in seconds (default: 60) 43 | 44 | response = await chmod(taskData) 45 | 46 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 47 | TaskID=taskData.Task.ID, 48 | Response=response.encode("UTF8"), 49 | )) 50 | 51 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 52 | TaskID=taskData.Task.ID, 53 | Success=True, 54 | Completed=True 55 | ) 56 | return taskResponse 57 | 58 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 59 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 60 | return resp 61 | 62 | async def chmod(taskData: PTTaskMessageAllData): 63 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 64 | 65 | # RPC not on the current stub, would need to upgrade or regen from protobufs? 66 | # https://github.com/BishopFox/sliver/blob/5e992e073e98015a37a503fa7d85aebe8a874860/client/command/filesystem/chmod.go#L53 67 | 68 | # chmod_results = await interact.tas 69 | 70 | # if (isBeacon): 71 | # chmod_results = await chmod_results 72 | 73 | # return f"{chmod_results}" 74 | 75 | return "This command not yet implemented..." 76 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/builder.py: -------------------------------------------------------------------------------- 1 | import pathlib 2 | from mythic_container.PayloadBuilder import * 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from sliver import SliverClientConfig, SliverClient, client_pb2 6 | 7 | 8 | class SliverImplant(PayloadType): 9 | name = "sliverimplant" 10 | author = "Spencer Adolph" 11 | note = """This payload connects to sliver to interact with a specific implant.""" 12 | supported_os = [SupportedOS.Windows, SupportedOS.Linux, SupportedOS.MacOS] 13 | file_extension = "" 14 | wrapper = False 15 | wrapped_payloads = [] 16 | supports_dynamic_loading = False 17 | c2_profiles = [] 18 | mythic_encrypts = False 19 | translation_container = None # "myPythonTranslation" 20 | # agent_type = "" 21 | agent_path = pathlib.Path(".") / "sliverimplant" 22 | agent_icon_path = agent_path / "agent_functions" / "sliver.svg" 23 | agent_code_path = agent_path / "agent_code" 24 | build_steps = [] 25 | build_parameters = [ 26 | BuildParameter( 27 | name="sliverconfig_file_uuid", 28 | description="sliverconfig_file_uuid", 29 | parameter_type=BuildParameterType.String, 30 | ), 31 | BuildParameter( 32 | name="os", 33 | description="os", 34 | parameter_type=BuildParameterType.String, 35 | ), 36 | BuildParameter( 37 | name="mtls", 38 | description="mtls", 39 | parameter_type=BuildParameterType.String, 40 | ), 41 | ] 42 | 43 | async def build(self) -> BuildResponse: 44 | os = self.get_parameter('os') 45 | mtls = self.get_parameter('mtls') 46 | sliverconfig_file_uuid = self.get_parameter('sliverconfig_file_uuid') 47 | 48 | if (os == ''): 49 | return BuildResponse(status=BuildStatus.Success) 50 | 51 | filecontent = await SendMythicRPCFileGetContent(MythicRPCFileGetContentMessage( 52 | AgentFileId=sliverconfig_file_uuid 53 | )) 54 | config = SliverClientConfig.parse_config(filecontent.Content) 55 | client = SliverClient(config) 56 | await client.connect() 57 | 58 | implant_config = client_pb2.ImplantConfig( 59 | IsBeacon=False, 60 | Name=f"{self.uuid}", 61 | GOARCH="amd64", 62 | GOOS=os, 63 | Format=client_pb2.OutputFormat.EXECUTABLE, 64 | ObfuscateSymbols=False, 65 | C2=[client_pb2.ImplantC2(Priority=0, URL=f"{mtls}")], 66 | ) 67 | 68 | implant = await client.generate_implant(implant_config) 69 | implant_bytes = implant.File.Data 70 | 71 | resp = BuildResponse(status=BuildStatus.Success, payload=implant_bytes) 72 | return resp 73 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/mkdir.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | 4 | from mythic_container.MythicCommandBase import * 5 | from mythic_container.MythicRPC import * 6 | from mythic_container.PayloadBuilder import * 7 | 8 | class MkdirArguments(TaskArguments): 9 | def __init__(self, command_line, **kwargs): 10 | super().__init__(command_line, **kwargs) 11 | self.args = [ 12 | CommandParameter( 13 | name="path", 14 | description="path to create dir", 15 | type=ParameterType.String 16 | ), 17 | ] 18 | 19 | async def parse_arguments(self): 20 | self.load_args_from_json_string(self.command_line) 21 | 22 | 23 | class Mkdir(CommandBase): 24 | cmd = "mkdir" 25 | needs_admin = False 26 | help_cmd = "mkdir" 27 | description = "make directory" 28 | version = 1 29 | author = "Spencer Adolph" 30 | argument_class = MkdirArguments 31 | attackmapping = [] 32 | 33 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 34 | # Command: mkdir [remote path] 35 | # About: Create a remote directory. 36 | 37 | # Usage: 38 | # ====== 39 | # mkdir [flags] path 40 | 41 | # Args: 42 | # ===== 43 | # path string path to the directory to create 44 | 45 | # Flags: 46 | # ====== 47 | # -h, --help display help 48 | # -t, --timeout int command timeout in seconds (default: 60) 49 | 50 | mkdir_results = await mkdir(taskData) 51 | 52 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 53 | TaskID=taskData.Task.ID, 54 | Response=f"{str(mkdir_results)}".encode("UTF8"), 55 | )) 56 | 57 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 58 | TaskID=taskData.Task.ID, 59 | Success=True, 60 | Completed=True 61 | ) 62 | return taskResponse 63 | 64 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 65 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 66 | return resp 67 | 68 | 69 | async def mkdir(taskData: PTTaskMessageAllData): 70 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 71 | 72 | # TODO: get these from function parameters and extract in the parent function instead 73 | remote_path = taskData.args.get_arg('path') 74 | 75 | mkdir_results = await interact.mkdir(remote_path=remote_path) 76 | 77 | if (isBeacon): 78 | mkdir_results = await mkdir_results 79 | 80 | return mkdir_results 81 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/netstat.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class NetstatArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Netstat(CommandBase): 17 | cmd = "netstat" 18 | needs_admin = False 19 | help_cmd = "netstat" 20 | description = "Print network connection information" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = NetstatArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Print network connection information 28 | 29 | # Usage: 30 | # ====== 31 | # netstat [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # -h, --help display help 36 | # TODO: -4, --ip4 display information about IPv4 sockets 37 | # TODO: -6, --ip6 display information about IPv6 sockets 38 | # TODO: -l, --listen display information about listening sockets 39 | # TODO: -n, --numeric display numeric addresses (disable hostname resolution) 40 | # TODO: -T, --tcp display information about TCP sockets 41 | # -t, --timeout int command timeout in seconds (default: 60) 42 | # TODO: -u, --udp display information about UDP sockets 43 | 44 | netstat_results = await netstat(taskData) 45 | 46 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 47 | TaskID=taskData.Task.ID, 48 | Response=f"{str(netstat_results)}".encode("UTF8"), 49 | )) 50 | 51 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 52 | TaskID=taskData.Task.ID, 53 | Success=True, 54 | Completed=True 55 | ) 56 | return taskResponse 57 | 58 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 59 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 60 | return resp 61 | 62 | async def netstat(taskData: PTTaskMessageAllData): 63 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 64 | 65 | netstat_results = await interact.netstat(tcp=True, udp=True, ipv4=True, ipv6=True, listening=True) 66 | 67 | if (isBeacon): 68 | netstat_results = await netstat_results 69 | 70 | return netstat_results 71 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/msf_inject.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class MsfInjectArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class MsfInject(CommandBase): 17 | cmd = "msf_inject" 18 | needs_admin = False 19 | help_cmd = "msf_inject" 20 | description = "Execute a metasploit payload in a remote process" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = MsfInjectArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Command: inject [--pid] [--lhost] 28 | # About: Execute a metasploit payload in a remote process. 29 | 30 | # Usage: 31 | # ====== 32 | # msf-inject [flags] 33 | 34 | # Flags: 35 | # ====== 36 | # TODO: -e, --encoder string msf encoder 37 | # -h, --help display help 38 | # TODO: -i, --iterations int iterations of the encoder (default: 1) 39 | # TODO: -L, --lhost string listen host 40 | # TODO: -l, --lport int listen port (default: 4444) 41 | # TODO: -m, --payload string msf payload (default: meterpreter_reverse_https) 42 | # TODO: -p, --pid int pid to inject into (default: -1) 43 | # -t, --timeout int command timeout in seconds (default: 60) 44 | 45 | response = await msf_inject(taskData) 46 | 47 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 48 | TaskID=taskData.Task.ID, 49 | Response=response.encode("UTF8"), 50 | )) 51 | 52 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 53 | TaskID=taskData.Task.ID, 54 | Success=True, 55 | Completed=True 56 | ) 57 | return taskResponse 58 | 59 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 60 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 61 | return resp 62 | 63 | async def msf_inject(taskData: PTTaskMessageAllData): 64 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 65 | 66 | # ifconfig_results = await interact._stub() 67 | 68 | # if (isBeacon): 69 | # ifconfig_results = await ifconfig_results 70 | 71 | return "This command not yet implemented..." 72 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/cursed.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | 8 | class CursedArguments(TaskArguments): 9 | def __init__(self, command_line, **kwargs): 10 | super().__init__(command_line, **kwargs) 11 | self.args = [] 12 | 13 | async def parse_arguments(self): 14 | pass 15 | 16 | 17 | class Cursed(CommandBase): 18 | cmd = "cursed" 19 | needs_admin = False 20 | help_cmd = "cursed" 21 | description = "Chrome/electron post-exploitation tool kit" 22 | version = 1 23 | author = "Spencer Adolph" 24 | argument_class = CursedArguments 25 | attackmapping = [] 26 | 27 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 28 | # Chrome/electron post-exploitation tool kit (∩`-´)⊃━☆゚.*・。゚ 29 | 30 | # Usage: 31 | # ====== 32 | # cursed [flags] 33 | 34 | # Flags: 35 | # ====== 36 | # -h, --help display help 37 | # -t, --timeout int command timeout in seconds (default: 60) 38 | 39 | # Sub Commands: 40 | # ============= 41 | # TODO: chrome Automatically inject a Cursed Chrome payload into a remote Chrome extension 42 | # TODO: console Start a JavaScript console connected to a debug target 43 | # TODO: cookies Dump all cookies from cursed process 44 | # TODO: edge Automatically inject a Cursed Chrome payload into a remote Edge extension 45 | # TODO: electron Curse a remote Electron application 46 | # TODO: rm Remove a Curse from a process 47 | # TODO: screenshot Take a screenshot of a cursed process debug target 48 | 49 | response = await cursed(taskData) 50 | 51 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 52 | TaskID=taskData.Task.ID, 53 | Response=response.encode("UTF8"), 54 | )) 55 | 56 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 57 | TaskID=taskData.Task.ID, 58 | Success=True, 59 | Completed=True 60 | ) 61 | 62 | return taskResponse 63 | 64 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 65 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 66 | return resp 67 | 68 | 69 | async def cursed(taskData: PTTaskMessageAllData): 70 | # client = await SliverAPI.create_sliver_client(taskData) 71 | # client._stub.cu 72 | 73 | # TODO: match sliver formatting 74 | 75 | return "This command not yet implemented..." 76 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/tasks.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | from sliver import sliver_pb2, client_pb2 8 | 9 | class TasksArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Tasks(CommandBase): 19 | cmd = "tasks" 20 | needs_admin = False 21 | help_cmd = "tasks" 22 | description = "Beacon task management" 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = TasksArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Beacon task management 30 | 31 | # Usage: 32 | # ====== 33 | # tasks [flags] 34 | 35 | # Flags: 36 | # ====== 37 | # TODO: -f, --filter string filter based on task type (case-insensitive prefix matching) 38 | # -h, --help display help 39 | # TODO: -O, --overflow overflow terminal width (display truncated rows) 40 | # TODO: -S, --skip-pages int skip the first n page(s) (default: 0) 41 | # -t, --timeout int command timeout in seconds (default: 60) 42 | 43 | # Sub Commands: 44 | # ============= 45 | # TODO: cancel Cancel a pending beacon task 46 | # TODO: fetch Fetch the details of a beacon task 47 | 48 | response = await tasks(taskData) 49 | 50 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 51 | TaskID=taskData.Task.ID, 52 | Response=response.encode("UTF8"), 53 | )) 54 | 55 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 56 | TaskID=taskData.Task.ID, 57 | Success=True, 58 | Completed=True 59 | ) 60 | return taskResponse 61 | 62 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 63 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 64 | return resp 65 | 66 | async def tasks(taskData: PTTaskMessageAllData): 67 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 68 | 69 | if (not isBeacon): 70 | return "Beacon only command!" 71 | 72 | task_results = await interact._stub.GetBeaconTasks(client_pb2.Beacon(ID=interact.beacon_id)) 73 | 74 | # if (isBeacon): 75 | # ifconfig_results = await ifconfig_results 76 | 77 | return f"{task_results}" 78 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/terminate.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class TerminateArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [ 11 | CommandParameter( 12 | name="process_id", 13 | description="pid to kill", 14 | type=ParameterType.Number 15 | ), 16 | ] 17 | 18 | async def parse_arguments(self): 19 | self.load_args_from_json_string(self.command_line) 20 | 21 | 22 | class Terminate(CommandBase): 23 | cmd = "terminate" 24 | needs_admin = False 25 | help_cmd = "terminate" 26 | description = "Kills a remote process designated by PID" 27 | version = 1 28 | author = "Spencer Adolph" 29 | argument_class = TerminateArguments 30 | attackmapping = [] 31 | supported_ui_features = ['process_browser:kill'] 32 | 33 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 34 | # Command: terminate PID 35 | # About: Kills a remote process designated by PID 36 | 37 | # Usage: 38 | # ====== 39 | # terminate [flags] pid 40 | 41 | # Args: 42 | # ===== 43 | # pid uint pid 44 | 45 | # Flags: 46 | # ====== 47 | # TODO: -F, --force disregard safety and kill the PID 48 | # -h, --help display help 49 | # -t, --timeout int command timeout in seconds (default: 60) 50 | 51 | pid_to_kill = taskData.args.get_arg('process_id') 52 | response = await terminate(taskData, pid_to_kill) 53 | 54 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 55 | TaskID=taskData.Task.ID, 56 | Response=response.encode("UTF8"), 57 | )) 58 | 59 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 60 | TaskID=taskData.Task.ID, 61 | Success=True, 62 | Completed=True 63 | ) 64 | return taskResponse 65 | 66 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 67 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 68 | return resp 69 | 70 | 71 | async def terminate(taskData: PTTaskMessageAllData, pid: int): 72 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 73 | 74 | terminate_results = await interact.terminate(pid=pid) 75 | 76 | if (isBeacon): 77 | terminate_results = await terminate_results 78 | 79 | return f"{terminate_results}" 80 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/http.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | # from sliver import common_pb2 8 | 9 | class HttpArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Http(CommandBase): 19 | cmd = "http" 20 | needs_admin = False 21 | help_cmd = "http" 22 | description = "Start an HTTP listener" 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = HttpArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Start an HTTP listener 30 | 31 | # Usage: 32 | # ====== 33 | # http [flags] 34 | 35 | # Flags: 36 | # ====== 37 | # TODO: -D, --disable-otp disable otp authentication 38 | # TODO: -d, --domain string limit responses to specific domain 39 | # -h, --help display help 40 | # TODO: -L, --lhost string interface to bind server to 41 | # TODO: -J, --long-poll-jitter string server-side long poll jitter (default: 2s) 42 | # TODO: -T, --long-poll-timeout string server-side long poll timeout (default: 1s) 43 | # TODO: -l, --lport int tcp listen port (default: 80) 44 | # TODO: -p, --persistent make persistent across restarts 45 | # -t, --timeout int command timeout in seconds (default: 60) 46 | # TODO: -w, --website string website name (see websites cmd) 47 | 48 | response = await http(taskData) 49 | 50 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 51 | TaskID=taskData.Task.ID, 52 | Response=response.encode("UTF8"), 53 | )) 54 | 55 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 56 | TaskID=taskData.Task.ID, 57 | Success=True, 58 | Completed=True 59 | ) 60 | 61 | return taskResponse 62 | 63 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 64 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 65 | return resp 66 | 67 | 68 | async def http(taskData: PTTaskMessageAllData): 69 | client = await SliverAPI.create_sliver_client(taskData) 70 | 71 | http_result = await client.start_http_listener() 72 | 73 | # TODO: match sliver formatting 74 | 75 | return f"{http_result}" 76 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/screenshot.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class ScreenshotArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Screenshot(CommandBase): 17 | cmd = "screenshot" 18 | needs_admin = False 19 | help_cmd = "screenshot" 20 | description = "Take a screenshot from the remote implant" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = ScreenshotArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Command: screenshot 28 | # About: Take a screenshot from the remote implant. 29 | 30 | # Usage: 31 | # ====== 32 | # screenshot [flags] 33 | 34 | # Flags: 35 | # ====== 36 | # TODO: -h, --help display help 37 | # TODO: -X, --loot save output as loot 38 | # TODO: -n, --name string name to assign loot (optional) 39 | # TODO: -s, --save string save to file (will overwrite if exists) 40 | # TODO: -t, --timeout int command timeout in seconds (default: 60) 41 | 42 | screenshot_results = await screenshot(taskData) 43 | 44 | results = await SendMythicRPCFileCreate(MythicRPCFileCreateMessage( 45 | TaskID=taskData.Task.ID, 46 | RemotePathOnTarget="/tmp/this_is_weird", 47 | FileContents=screenshot_results, 48 | IsScreenshot=True, 49 | IsDownloadFromAgent=False, 50 | Filename="this_is_weird", 51 | )) 52 | 53 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 54 | TaskID=taskData.Task.ID, 55 | Response=f"agent file id == {results.AgentFileId}".encode("UTF8"), 56 | )) 57 | 58 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 59 | TaskID=taskData.Task.ID, 60 | Success=True, 61 | Completed=True 62 | ) 63 | return taskResponse 64 | 65 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 66 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 67 | return resp 68 | 69 | async def screenshot(taskData: PTTaskMessageAllData): 70 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 71 | screenshot_result = await interact.screenshot() 72 | 73 | if (isBeacon): 74 | screenshot_result = await screenshot_result 75 | 76 | return screenshot_result.Data 77 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/beacons.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class BeaconsArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Beacons(CommandBase): 17 | cmd = "beacons" 18 | needs_admin = False 19 | help_cmd = "beacons" 20 | description = "Get the list of beacons that Sliver is aware of." 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = BeaconsArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Manage beacons 28 | 29 | # Usage: 30 | # ====== 31 | # beacons [flags] 32 | 33 | # Flags: 34 | # ====== 35 | # TODO: -f, --filter string filter beacons by substring 36 | # TODO: -e, --filter-re string filter beacons by regular expression 37 | # TODO: -F, --force force killing of the beacon 38 | # TODO: -k, --kill string kill a beacon 39 | # TODO: -K, --kill-all kill all beacons 40 | 41 | # Sub Commands: 42 | # ============= 43 | # TODO: prune Prune stale beacons automatically 44 | # TODO: rm Remove a beacon 45 | # TODO: watch Watch your beacons 46 | 47 | 48 | # 'beacons' with no options 49 | response = await beacons_list(taskData) 50 | 51 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 52 | TaskID=taskData.Task.ID, 53 | Response=response.encode("UTF8"), 54 | )) 55 | 56 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 57 | TaskID=taskData.Task.ID, 58 | Success=True, 59 | Completed=True 60 | ) 61 | 62 | return taskResponse 63 | 64 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 65 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 66 | return resp 67 | 68 | async def beacons_list(taskData: PTTaskMessageAllData): 69 | client = await SliverAPI.create_sliver_client(taskData) 70 | beacons = await client.beacons() 71 | 72 | # TODO: match sliver formatting 73 | 74 | # ID Name Transport Hostname Username Operating System Last Check-In Next Check-In 75 | # ========== ============= =========== ========== ========== ================== =============== =============== 76 | # d90a2ec6 DARK_MITTEN mtls ubuntu ubuntu linux/amd64 2s 1m4s 77 | 78 | # What to show if no beacons? 79 | 80 | return f"{beacons}" 81 | 82 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/wg.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | # from sliver import common_pb2 8 | 9 | class WgArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [ 13 | # CommandParameter( 14 | # name="n_port", 15 | # cli_name="n_port", 16 | # display_name="n_port", 17 | # description="virtual tun interface listen port", 18 | # type=ParameterType.Number 19 | # ), 20 | ] 21 | 22 | async def parse_arguments(self): 23 | self.load_args_from_json_string(self.command_line) 24 | 25 | 26 | class Wg(CommandBase): 27 | cmd = "wg" 28 | needs_admin = False 29 | help_cmd = "wg" 30 | description = "Start a WireGuard listener" 31 | version = 1 32 | author = "Spencer Adolph" 33 | argument_class = WgArguments 34 | attackmapping = [] 35 | 36 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 37 | # Start a WireGuard listener 38 | 39 | # Usage: 40 | # ====== 41 | # wg [flags] 42 | 43 | # Flags: 44 | # ====== 45 | # -h, --help display help 46 | # TODO: -x, --key-port int virtual tun interface key exchange port (default: 1337) 47 | # TODO: -L, --lhost string interface to bind server to 48 | # TODO: -l, --lport int udp listen port (default: 53) 49 | # TODO: -n, --nport int virtual tun interface listen port (default: 8888) 50 | # TODO: -p, --persistent make persistent across restarts 51 | # -t, --timeout int command timeout in seconds (default: 60) 52 | 53 | # n_port = taskData.args.get_arg('n_port') 54 | response = await wireguard(taskData) 55 | 56 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 57 | TaskID=taskData.Task.ID, 58 | Response=response.encode("UTF8"), 59 | )) 60 | 61 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 62 | TaskID=taskData.Task.ID, 63 | Success=True, 64 | Completed=True 65 | ) 66 | 67 | return taskResponse 68 | 69 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 70 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 71 | return resp 72 | 73 | 74 | async def wireguard(taskData: PTTaskMessageAllData): 75 | client = await SliverAPI.create_sliver_client(taskData) 76 | 77 | start_wg_listener_results = await client.start_wg_listener(tun_ip='0.0.0.0') 78 | 79 | # TODO: match sliver formatting 80 | 81 | return f"{start_wg_listener_results}" 82 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/mtls.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class MtlsArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [ 11 | CommandParameter( 12 | name="lport", 13 | cli_name="l", 14 | display_name="lport", 15 | description="tcp listen port (default: 8888)", 16 | default_value=8888, 17 | type=ParameterType.Number 18 | ), 19 | ] 20 | 21 | async def parse_arguments(self): 22 | self.load_args_from_json_string(self.command_line) 23 | 24 | 25 | class Mtls(CommandBase): 26 | cmd = "mtls" 27 | needs_admin = False 28 | help_cmd = "mtls" 29 | description = "Start an mTLS listener" 30 | version = 1 31 | author = "Spencer Adolph" 32 | argument_class = MtlsArguments 33 | attackmapping = [] 34 | 35 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 36 | # Start an mTLS listener 37 | 38 | # Usage: 39 | # ====== 40 | # mtls [flags] 41 | 42 | # Flags: 43 | # ====== 44 | # -h, --help display help 45 | # TODO: -L, --lhost string interface to bind server to 46 | # -l, --lport int tcp listen port (default: 8888) 47 | # TODO: -p, --persistent make persistent across restarts 48 | # -t, --timeout int command timeout in seconds (default: 60) 49 | 50 | # 'mtls -l ' 51 | port = taskData.args.get_arg('lport') 52 | response = await mtls_start(taskData, port) 53 | 54 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 55 | TaskID=taskData.Task.ID, 56 | Response=response.encode("UTF8"), 57 | )) 58 | 59 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 60 | TaskID=taskData.Task.ID, 61 | Success=True, 62 | Completed=True 63 | ) 64 | 65 | return taskResponse 66 | 67 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 68 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 69 | return resp 70 | 71 | 72 | async def mtls_start(taskData: PTTaskMessageAllData, port: int): 73 | client = await SliverAPI.create_sliver_client(taskData) 74 | 75 | mtls_start_result = await client.start_mtls_listener( 76 | host = "0.0.0.0", 77 | port = port, 78 | persistent = False, 79 | ) 80 | 81 | # TODO: match sliver formatting 82 | 83 | # [*] Starting mTLS listener ... 84 | # [*] Successfully started job #1 85 | 86 | return f"{mtls_start_result}" 87 | 88 | 89 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/interactive.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | from sliver import sliver_pb2, client_pb2 8 | 9 | class InteractiveArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Interactive(CommandBase): 19 | cmd = "interactive" 20 | needs_admin = False 21 | help_cmd = "interactive" 22 | description = "Task a beacon to open an interactive session (Beacon only)" 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = InteractiveArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Task a beacon to open an interactive session (Beacon only) 30 | 31 | # Usage: 32 | # ====== 33 | # interactive [flags] 34 | 35 | # Flags: 36 | # ====== 37 | # TODO: -d, --delay string delay opening the session (after checkin) for a given period of time (default: 0s) 38 | # TODO: -n, --dns string dns connection strings 39 | # -h, --help display help 40 | # TODO: -b, --http string http(s) connection strings 41 | # TODO: -m, --mtls string mtls connection strings 42 | # TODO: -p, --named-pipe string namedpipe connection strings 43 | # TODO: -i, --tcp-pivot string tcppivot connection strings 44 | # -t, --timeout int command timeout in seconds (default: 60) 45 | # TODO: -g, --wg string wg connection strings 46 | 47 | response = await interactive(taskData) 48 | 49 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 50 | TaskID=taskData.Task.ID, 51 | Response=response.encode("UTF8"), 52 | )) 53 | 54 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 55 | TaskID=taskData.Task.ID, 56 | Success=True, 57 | Completed=True 58 | ) 59 | return taskResponse 60 | 61 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 62 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 63 | return resp 64 | 65 | async def interactive(taskData: PTTaskMessageAllData): 66 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 67 | 68 | if (not isBeacon): 69 | return "Beacon Only..." 70 | 71 | # TODO: figure out how to wait for task to complete, or decide if don't worry about it 72 | interactive_results = await interact._stub.OpenSession(interact._request(sliver_pb2.OpenSession())) 73 | 74 | return "Tasked to create an interactive session!" 75 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/mv.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | from sliver import sliver_pb2, client_pb2 8 | 9 | class MvArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [ 13 | CommandParameter( 14 | name="src", 15 | cli_name="src", 16 | display_name="src", 17 | description="source file", 18 | type=ParameterType.String, 19 | ), 20 | CommandParameter( 21 | name="dst", 22 | cli_name="dst", 23 | display_name="dst", 24 | description="destination file", 25 | type=ParameterType.String, 26 | ), 27 | ] 28 | 29 | async def parse_arguments(self): 30 | self.load_args_from_json_string(self.command_line) 31 | 32 | 33 | class Mv(CommandBase): 34 | cmd = "mv" 35 | needs_admin = False 36 | help_cmd = "mv" 37 | description = "Move or rename a file" 38 | version = 1 39 | author = "Spencer Adolph" 40 | argument_class = MvArguments 41 | attackmapping = [] 42 | 43 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 44 | # Move or rename a file 45 | 46 | # Usage: 47 | # ====== 48 | # mv [flags] src dst 49 | 50 | # Args: 51 | # ===== 52 | # src string path to source file 53 | # dst string path to dest file 54 | 55 | # Flags: 56 | # ====== 57 | # -h, --help display help 58 | # -t, --timeout int command timeout in seconds (default: 60) 59 | 60 | src = taskData.args.get_arg('src') 61 | dst = taskData.args.get_arg('dst') 62 | response = await mv(taskData, src, dst) 63 | 64 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 65 | TaskID=taskData.Task.ID, 66 | Response=response.encode("UTF8"), 67 | )) 68 | 69 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 70 | TaskID=taskData.Task.ID, 71 | Success=True, 72 | Completed=True 73 | ) 74 | return taskResponse 75 | 76 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 77 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 78 | return resp 79 | 80 | async def mv(taskData: PTTaskMessageAllData, src: str, dst: str): 81 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 82 | 83 | # TODO: figure out how to await the task completing 84 | mv_results = await interact._stub.Mv(interact._request(sliver_pb2.MvReq(Src=src, Dst=dst))) 85 | 86 | # if (isBeacon): 87 | # mv_results = await mv_results 88 | 89 | return f"Tasked [*] {src} > {dst}" 90 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/reconfig.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | from sliver import sliver_pb2 8 | 9 | class ReconfigArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [ 13 | CommandParameter( 14 | name="beacon_interval", 15 | description="beacon_interval in seconds", 16 | type=ParameterType.Number, 17 | ), 18 | ] 19 | 20 | async def parse_arguments(self): 21 | self.load_args_from_json_string(self.command_line) 22 | 23 | 24 | class Reconfig(CommandBase): 25 | cmd = "reconfig" 26 | needs_admin = False 27 | help_cmd = "reconfig" 28 | description = "Reconfigure the active beacon/session" 29 | version = 1 30 | author = "Spencer Adolph" 31 | argument_class = ReconfigArguments 32 | attackmapping = [] 33 | 34 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 35 | # Reconfigure the active beacon/session 36 | 37 | # Usage: 38 | # ====== 39 | # reconfig [flags] 40 | 41 | # Flags: 42 | # ====== 43 | # -i, --beacon-interval string beacon callback interval 44 | # TODO: -j, --beacon-jitter string beacon callback jitter (random up to) 45 | # -h, --help display help 46 | # TODO: -r, --reconnect-interval string reconnect interval for implant 47 | # -t, --timeout int command timeout in seconds (default: 60) 48 | 49 | beacon_interval = taskData.args.get_arg('beacon_interval') 50 | response = await reconfig(taskData, beacon_interval) 51 | 52 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 53 | TaskID=taskData.Task.ID, 54 | Response=response.encode("UTF8"), 55 | )) 56 | 57 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 58 | TaskID=taskData.Task.ID, 59 | Success=True, 60 | Completed=True 61 | ) 62 | return taskResponse 63 | 64 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 65 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 66 | return resp 67 | 68 | async def reconfig(taskData: PTTaskMessageAllData, beacon_interval_seconds: int): 69 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 70 | 71 | if (not isBeacon): 72 | return "Beacon only command!" 73 | 74 | beacon_interval = beacon_interval_seconds * 1000000000 75 | 76 | reconfig_results = await interact._stub.Reconfigure(interact._request(sliver_pb2.ReconfigureReq(BeaconInterval=beacon_interval))) 77 | 78 | # if (isBeacon): 79 | # ifconfig_results = await ifconfig_results 80 | 81 | return "Tasked Reconfig!" 82 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/websites.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | # from sliver import common_pb2 8 | 9 | class WebsitesArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Websites(CommandBase): 19 | cmd = "websites" 20 | needs_admin = False 21 | help_cmd = "websites" 22 | description = "Add content to HTTP(S) C2 websites to make them look more legit" 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = WebsitesArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Command: websites 30 | # About: Add content to HTTP(S) C2 websites to make them look more legit. 31 | 32 | # Usage: 33 | # ====== 34 | # websites [flags] [name] 35 | 36 | # Args: 37 | # ===== 38 | # name string website name 39 | 40 | # Flags: 41 | # ====== 42 | # -h, --help display help 43 | # -t, --timeout int command timeout in seconds (default: 60) 44 | 45 | # Sub Commands: 46 | # ============= 47 | # TODO: add-content Add content to a website 48 | # TODO: content-type Update a path's content-type 49 | # TODO: rm Remove an entire website and all of its contents 50 | # TODO: rm-content Remove specific content from a website 51 | 52 | response = await websites(taskData) 53 | 54 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 55 | TaskID=taskData.Task.ID, 56 | Response=response.encode("UTF8"), 57 | )) 58 | 59 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 60 | TaskID=taskData.Task.ID, 61 | Success=True, 62 | Completed=True 63 | ) 64 | 65 | return taskResponse 66 | 67 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 68 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 69 | return resp 70 | 71 | 72 | async def websites(taskData: PTTaskMessageAllData): 73 | client = await SliverAPI.create_sliver_client(taskData) 74 | 75 | websites_results = await client.websites() 76 | 77 | # here generate the html 78 | # html = gen() 79 | 80 | # websites_results = await client.add_website_content(content=html) 81 | # websites_results = await client.remove_website() 82 | # websites_results = await client.remove_website_content() 83 | # websites_results = await client.update_website() 84 | # websites_results = await client.update_website_content() 85 | 86 | # TODO: match sliver formatting 87 | 88 | return f"{websites_results}" 89 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/ssh.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class SshArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Ssh(CommandBase): 17 | cmd = "ssh" 18 | needs_admin = False 19 | help_cmd = "ssh" 20 | description = "Run an one-off SSH command via the implant" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = SshArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Command: ssh 28 | # About: Run an one-off SSH command via the implant. 29 | 30 | # Usage: 31 | # ====== 32 | # ssh [flags] hostname [command...] 33 | 34 | # Args: 35 | # ===== 36 | # hostname string remote host to SSH to 37 | # command string list command line with arguments 38 | 39 | # Flags: 40 | # ====== 41 | # -h, --help display help 42 | # TODO: -c, --kerberos-config string path to remote Kerberos config file (default: /etc/krb5.conf) 43 | # TODO: -k, --kerberos-keytab string path to Kerberos keytab file 44 | # TODO: -r, --kerberos-realm string Kerberos realm 45 | # TODO: -l, --login string username to use to connect 46 | # TODO: -P, --password string SSH user password 47 | # TODO: -p, --port uint SSH port (default: 22) 48 | # TODO: -i, --private-key string path to private key file 49 | # TODO: -u, --signed-user-cert string path to user signed certificate (certificate based auth) 50 | # TODO: -s, --skip-loot skip the prompt to use loot credentials 51 | # -t, --timeout int command timeout in seconds (default: 60) 52 | 53 | response = await ssh(taskData) 54 | 55 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 56 | TaskID=taskData.Task.ID, 57 | Response=response.encode("UTF8"), 58 | )) 59 | 60 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 61 | TaskID=taskData.Task.ID, 62 | Success=True, 63 | Completed=True 64 | ) 65 | return taskResponse 66 | 67 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 68 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 69 | return resp 70 | 71 | async def ssh(taskData: PTTaskMessageAllData): 72 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 73 | 74 | # ifconfig_results = await interact._stub() 75 | 76 | # if (isBeacon): 77 | # ifconfig_results = await ifconfig_results 78 | 79 | return "This command not yet implemented..." 80 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/sessions.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | from tabulate import tabulate 7 | 8 | 9 | class SessionsArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Sessions(CommandBase): 19 | cmd = "sessions" 20 | needs_admin = False 21 | help_cmd = "sessions" 22 | description = "Get the list of sessions that Sliver is aware of." 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = SessionsArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Command: sessions 30 | # About: List Sliver sessions, and optionally interact or kill a session. 31 | 32 | # Usage: 33 | # ====== 34 | # sessions [flags] 35 | 36 | # Flags: 37 | # ====== 38 | # TODO: -C, --clean clean out any sessions marked as [DEAD] 39 | # TODO: -f, --filter string filter sessions by substring 40 | # TODO: -e, --filter-re string filter sessions by regular expression 41 | # TODO: -F, --force force session action without waiting for results 42 | # -h, --help display help 43 | # TODO: -i, --interact string interact with a session 44 | # TODO: -k, --kill string kill the designated session 45 | # TODO: -K, --kill-all kill all the sessions 46 | # -t, --timeout int command timeout in seconds (default: 60) 47 | 48 | # Sub Commands: 49 | # ============= 50 | # TODO: prune Kill all stale/dead sessions 51 | 52 | # 'sessions' with no options 53 | response = await sessions_list(taskData) 54 | 55 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 56 | TaskID=taskData.Task.ID, 57 | Response=response.encode("UTF8"), 58 | )) 59 | 60 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 61 | TaskID=taskData.Task.ID, 62 | Success=True, 63 | Completed=True, 64 | ) 65 | 66 | return taskResponse 67 | 68 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 69 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 70 | return resp 71 | 72 | 73 | async def sessions_list(taskData: PTTaskMessageAllData): 74 | client = await SliverAPI.create_sliver_client(taskData) 75 | sessions = await client.sessions() 76 | 77 | headers = ["ID", "Transport", "Remote Address", "Hostname", "Username", "Operating System", "Health"] 78 | data = [(session.ID, session.Transport, session.RemoteAddress, session.Hostname, session.Username, session.OS, "[DEAD]" if session.IsDead else "[ALIVE]") for session in sessions] 79 | table = tabulate(data, headers=headers) 80 | 81 | return table 82 | 83 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/https.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | # from sliver import common_pb2 8 | 9 | class HttpsArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Https(CommandBase): 19 | cmd = "https" 20 | needs_admin = False 21 | help_cmd = "https" 22 | description = "Start an HTTPS listener" 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = HttpsArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Start an HTTPS listener 30 | 31 | # Usage: 32 | # ====== 33 | # https [flags] 34 | 35 | # Flags: 36 | # ====== 37 | # TODO: -c, --cert string PEM encoded certificate file 38 | # TODO: -D, --disable-otp disable otp authentication 39 | # TODO: -E, --disable-randomized-jarm disable randomized jarm fingerprints 40 | # TODO: -d, --domain string limit responses to specific domain 41 | # -h, --help display help 42 | # TODO: -k, --key string PEM encoded private key file 43 | # TODO: -e, --lets-encrypt attempt to provision a let's encrypt certificate 44 | # TODO: -L, --lhost string interface to bind server to 45 | # TODO: -J, --long-poll-jitter string server-side long poll jitter (default: 2s) 46 | # TODO: -T, --long-poll-timeout string server-side long poll timeout (default: 1s) 47 | # TODO: -l, --lport int tcp listen port (default: 443) 48 | # TODO: -p, --persistent make persistent across restarts 49 | # -t, --timeout int command timeout in seconds (default: 60) 50 | # TODO: -w, --website string website name (see websites cmd) 51 | 52 | response = await https(taskData) 53 | 54 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 55 | TaskID=taskData.Task.ID, 56 | Response=response.encode("UTF8"), 57 | )) 58 | 59 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 60 | TaskID=taskData.Task.ID, 61 | Success=True, 62 | Completed=True 63 | ) 64 | 65 | return taskResponse 66 | 67 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 68 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 69 | return resp 70 | 71 | 72 | async def https(taskData: PTTaskMessageAllData): 73 | client = await SliverAPI.create_sliver_client(taskData) 74 | 75 | https_result = await client.start_https_listener() 76 | 77 | # TODO: match sliver formatting 78 | 79 | return f"{https_result}" 80 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/upload.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class UploadArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [ 11 | CommandParameter( 12 | name="path", 13 | description="full path to create file", 14 | type=ParameterType.String 15 | ), 16 | CommandParameter( 17 | name="uuid", 18 | description="uuid of existing file to upload", 19 | type=ParameterType.String 20 | ), 21 | ] 22 | 23 | async def parse_arguments(self): 24 | self.load_args_from_json_string(self.command_line) 25 | 26 | 27 | class Upload(CommandBase): 28 | cmd = "upload" 29 | needs_admin = False 30 | help_cmd = "upload" 31 | description = "Upload a file" 32 | version = 1 33 | author = "Spencer Adolph" 34 | argument_class = UploadArguments 35 | attackmapping = [] 36 | supported_ui_features = ["file_browser:upload"] 37 | 38 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 39 | # Command: upload [local src] 40 | # About: Upload a file to the remote system. 41 | 42 | # Usage: 43 | # ====== 44 | # upload [flags] local-path [remote-path] 45 | 46 | # Args: 47 | # ===== 48 | # local-path string local path to the file to upload 49 | # remote-path string path to the file or directory to upload to 50 | 51 | # Flags: 52 | # ====== 53 | # -h, --help display help 54 | # TODO: -i, --ioc track uploaded file as an ioc 55 | # -t, --timeout int command timeout in seconds (default: 60) 56 | 57 | response = await upload(taskData, taskData.args.get_arg('uuid'), taskData.args.get_arg('path')) 58 | 59 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 60 | TaskID=taskData.Task.ID, 61 | Response="upload success!".encode("UTF8"), 62 | )) 63 | 64 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 65 | TaskID=taskData.Task.ID, 66 | Success=True, 67 | Completed=True 68 | ) 69 | return taskResponse 70 | 71 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 72 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 73 | return resp 74 | 75 | async def upload(taskData: PTTaskMessageAllData, agent_file_uuid: str, path: str): 76 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 77 | 78 | filestuff = await SendMythicRPCFileGetContent(MythicRPCFileGetContentMessage( 79 | AgentFileId=agent_file_uuid 80 | )) 81 | 82 | upload_results = await interact.upload( 83 | remote_path=path, 84 | data=filestuff.Content 85 | ) 86 | 87 | if (isBeacon): 88 | upload_results = await upload_results 89 | 90 | return upload_results 91 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/ps.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class PsArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Ps(CommandBase): 17 | cmd = "ps" 18 | needs_admin = False 19 | help_cmd = "ps" 20 | description = "List processes on remote system." 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = PsArguments 24 | attackmapping = [] 25 | supported_ui_features = ["process_browser:list"] 26 | 27 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 28 | # Command: ps 29 | # About: List processes on remote system. 30 | 31 | # Usage: 32 | # ====== 33 | # ps [flags] 34 | 35 | # Flags: 36 | # ====== 37 | # TODO: -e, --exe string filter based on executable name 38 | # -h, --help display help 39 | # TODO: -O, --overflow overflow terminal width (display truncated rows) 40 | # TODO: -o, --owner string filter based on owner 41 | # TODO: -p, --pid int filter based on pid (default: -1) 42 | # TODO: -c, --print-cmdline print command line arguments 43 | # TODO: -S, --skip-pages int skip the first n page(s) (default: 0) 44 | # -t, --timeout int command timeout in seconds (default: 60) 45 | # TODO: -T, --tree print process tree 46 | 47 | ps_results = await ps(taskData) 48 | 49 | processes = [] 50 | for individual_ps in ps_results: 51 | processes.append( 52 | MythicRPCProcessCreateData( 53 | Host=taskData.Callback.Host, 54 | ProcessID=individual_ps.Pid, 55 | ParentProcessID=individual_ps.Ppid, 56 | Name=individual_ps.Executable, 57 | User=individual_ps.Owner, 58 | Architecture=individual_ps.Architecture, 59 | CommandLine=" ".join(individual_ps.CmdLine), 60 | ) 61 | ) 62 | 63 | await SendMythicRPCProcessCreate(MythicRPCProcessesCreateMessage( 64 | TaskID=taskData.Task.ID, 65 | Processes=processes, 66 | )) 67 | 68 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 69 | TaskID=taskData.Task.ID, 70 | Success=True, 71 | Completed=True, 72 | ) 73 | return taskResponse 74 | 75 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 76 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 77 | return resp 78 | 79 | async def ps(taskData: PTTaskMessageAllData): 80 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 81 | 82 | ps_results = await interact.ps() 83 | 84 | if (isBeacon): 85 | ps_results = await ps_results 86 | 87 | return ps_results 88 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/reaction.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | # from sliver import common_pb2 8 | 9 | class ReactionArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Reaction(CommandBase): 19 | cmd = "reaction" 20 | needs_admin = False 21 | help_cmd = "reaction" 22 | description = "Automate commands in reaction to event(s)" 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = ReactionArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Command: reaction 30 | # About: Automate commands in reaction to event(s). The built-in 31 | # reactions do not support variables or logic, they simply allow you to run verbatim 32 | # commands when an event occurs. To implement complex event-based logic we recommend 33 | # using SliverPy (Python) or sliver-script (TypeScript/JavaScript). 34 | 35 | # Reactable Events: 36 | # session-connected Triggered when a new session is opened to a target 37 | # session-updated Triggered on changes to session metadata 38 | # session-disconnected Triggered when a session is closed (for any reason) 39 | # canary Triggered when a canary is burned or created 40 | # watchtower Triggered when implants are discovered on threat intel platforms 41 | # loot-added Triggered when a new piece of loot is added to the server 42 | # loot-removed Triggered when a piece of loot is removed from the server 43 | 44 | 45 | # Usage: 46 | # ====== 47 | # reaction [flags] 48 | 49 | # Flags: 50 | # ====== 51 | # -h, --help display help 52 | 53 | # Sub Commands: 54 | # ============= 55 | # TODO: reload Reload reactions from disk, replaces the running configuration 56 | # TODO: save Save current reactions to disk 57 | # TODO: set Set a reaction to an event 58 | # TODO: unset Unset an existing reaction 59 | 60 | response = await reaction(taskData) 61 | 62 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 63 | TaskID=taskData.Task.ID, 64 | Response=response.encode("UTF8"), 65 | )) 66 | 67 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 68 | TaskID=taskData.Task.ID, 69 | Success=True, 70 | Completed=True 71 | ) 72 | 73 | return taskResponse 74 | 75 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 76 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 77 | return resp 78 | 79 | 80 | async def reaction(taskData: PTTaskMessageAllData): 81 | # client = await SliverAPI.create_sliver_client(taskData) 82 | 83 | # reaction_result = await client._stub.rea 84 | 85 | # TODO: match sliver formatting 86 | 87 | return "This command not yet implemented..." 88 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/stage_listener.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | # from sliver import common_pb2 8 | 9 | class StageListenerArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class StageListener(CommandBase): 19 | cmd = "stage_listener" 20 | needs_admin = False 21 | help_cmd = "stage_listener" 22 | description = "Starts a stager listener bound to a Sliver profile" 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = StageListenerArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # Command: stage-listener 30 | # About: Starts a stager listener bound to a Sliver profile. 31 | 32 | # Usage: 33 | # ====== 34 | # stage-listener [flags] 35 | 36 | # Flags: 37 | # ====== 38 | # TODO: --aes-encrypt-iv string encrypt stage with AES encryption iv 39 | # TODO: --aes-encrypt-key string encrypt stage with AES encryption key 40 | # TODO: -c, --cert string path to PEM encoded certificate file (HTTPS only) 41 | # TODO: -C, --compress string compress the stage before encrypting (zlib, gzip, deflate9, none) (default: none) 42 | # TODO: -k, --key string path to PEM encoded private key file (HTTPS only) 43 | # TODO: -e, --lets-encrypt attempt to provision a let's encrypt certificate (HTTPS only) 44 | # TODO: -P, --prepend-size prepend the size of the stage to the payload (to use with MSF stagers) 45 | # TODO: -p, --profile string implant profile name to link with the listener 46 | # TODO: -u, --url string URL to which the stager will call back to 47 | 48 | response = await stage_listener(taskData) 49 | 50 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 51 | TaskID=taskData.Task.ID, 52 | Response=response.encode("UTF8"), 53 | )) 54 | 55 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 56 | TaskID=taskData.Task.ID, 57 | Success=True, 58 | Completed=True 59 | ) 60 | 61 | return taskResponse 62 | 63 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 64 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 65 | return resp 66 | 67 | 68 | async def stage_listener(taskData: PTTaskMessageAllData): 69 | # client = await SliverAPI.create_sliver_client(taskData) 70 | 71 | 72 | # should have the profile and listen url by now 73 | # get the binary (either already built or build one) 74 | # use implant_builds and filter on the name in the profile 75 | # if not found, task to build one (sub-task?) 76 | # if found, use Regenerate using the same implant name 77 | 78 | 79 | # start_tcp_stager_listener_result = await client.stager 80 | 81 | # TODO: match sliver formatting 82 | 83 | return "This command not yet implemented..." 84 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/sideload.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class SideloadArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Sideload(CommandBase): 17 | cmd = "sideload" 18 | needs_admin = False 19 | help_cmd = "sideload" 20 | description = "Load and execute a shared library in memory in a remote process" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = SideloadArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Command: sideload 28 | # About: Load and execute a shared library in memory in a remote process. 29 | 30 | # Usage: 31 | # ====== 32 | # sideload [flags] filepath [args...] 33 | 34 | # Args: 35 | # ===== 36 | # filepath string path the shared library file 37 | # args string list arguments for the binary (default: []) 38 | 39 | # Flags: 40 | # ====== 41 | # TODO: -e, --entry-point string Entrypoint for the DLL (Windows only) 42 | # -h, --help display help 43 | # TODO: -k, --keep-alive don't terminate host process once the execution completes 44 | # TODO: -X, --loot save output as loot 45 | # TODO: -n, --name string name to assign loot (optional) 46 | # TODO: -P, --ppid uint parent process id (optional) (default: 0) 47 | # TODO: -p, --process string Path to process to host the shellcode (default: c:\windows\system32\notepad.exe) 48 | # TODO: -A, --process-arguments string arguments to pass to the hosting process 49 | # TODO: -s, --save save output to file 50 | # -t, --timeout int command timeout in seconds (default: 60) 51 | # TODO: -w, --unicode Command line is passed to unmanaged DLL function in UNICODE format. (default is ANSI) 52 | 53 | response = await sideload(taskData) 54 | 55 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 56 | TaskID=taskData.Task.ID, 57 | Response=response.encode("UTF8"), 58 | )) 59 | 60 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 61 | TaskID=taskData.Task.ID, 62 | Success=True, 63 | Completed=True 64 | ) 65 | return taskResponse 66 | 67 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 68 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 69 | return resp 70 | 71 | async def sideload(taskData: PTTaskMessageAllData): 72 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 73 | 74 | # ifconfig_results = await interact._stub() 75 | 76 | # if (isBeacon): 77 | # ifconfig_results = await ifconfig_results 78 | 79 | return "This command not yet implemented..." 80 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/cat.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | 4 | from mythic_container.MythicCommandBase import * 5 | from mythic_container.MythicRPC import * 6 | from mythic_container.PayloadBuilder import * 7 | import gzip 8 | 9 | class CatArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [ 13 | CommandParameter( 14 | name="full_path", 15 | description="path to file", 16 | type=ParameterType.String 17 | ), 18 | ] 19 | 20 | async def parse_arguments(self): 21 | self.load_args_from_json_string(self.command_line) 22 | 23 | 24 | class Cat(CommandBase): 25 | cmd = "cat" 26 | needs_admin = False 27 | help_cmd = "cat" 28 | description = "cat a file" 29 | version = 1 30 | author = "Spencer Adolph" 31 | argument_class = CatArguments 32 | attackmapping = [] 33 | 34 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 35 | # Command: cat 36 | # About: Cat a remote file to stdout. 37 | 38 | # Usage: 39 | # ====== 40 | # cat [flags] path 41 | 42 | # Args: 43 | # ===== 44 | # path string path to the file to print 45 | 46 | # Flags: 47 | # ====== 48 | # TODO: -c, --colorize-output colorize output 49 | # TODO: -F, --file-type string force a specific file type (binary/text) if looting (optional) 50 | # -h, --help display help 51 | # TODO: -x, --hex display as a hex dump 52 | # TODO: -X, --loot save output as loot 53 | # TODO: -n, --name string name to assign loot (optional) 54 | # -t, --timeout int command timeout in seconds (default: 60) 55 | # TODO: -T, --type string force a specific loot type (file/cred) if looting (optional) 56 | 57 | # just download and don't create a file, show the output to user 58 | # sliver py doesn't have a direct 'cat' method to use 59 | plaintext = await download(taskData, taskData.args.get_arg('full_path')) 60 | 61 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 62 | TaskID=taskData.Task.ID, 63 | Response=f"{plaintext.decode('utf-8')}".encode("UTF8"), 64 | )) 65 | 66 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 67 | TaskID=taskData.Task.ID, 68 | Success=True, 69 | Completed=True 70 | ) 71 | return taskResponse 72 | 73 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 74 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 75 | return resp 76 | 77 | async def download(taskData: PTTaskMessageAllData, full_path: str): 78 | # TODO: this is duplicated in the download.py command, consider refactoring 79 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 80 | 81 | download_results = await interact.download(remote_path=full_path) 82 | 83 | if (isBeacon): 84 | download_results = await download_results 85 | 86 | plaintext = gzip.decompress(download_results.Data) 87 | 88 | return plaintext 89 | 90 | 91 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/execute_shellcode.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class ExecuteShellcodeArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class ExecuteShellcode(CommandBase): 17 | cmd = "execute_shellcode" 18 | needs_admin = False 19 | help_cmd = "execute_shellcode" 20 | description = "Executes the given shellcode in the implant's process" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = ExecuteShellcodeArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Command: execute-shellcode [local path to raw shellcode] 28 | # About: Executes the given shellcode in the implant's process. 29 | 30 | # ++ Shellcode ++ 31 | # Shellcode files should be binary encoded, you can generate Sliver shellcode files with the generate command: 32 | # generate --format shellcode 33 | 34 | # Usage: 35 | # ====== 36 | # execute-shellcode [flags] filepath 37 | 38 | # Args: 39 | # ===== 40 | # filepath string path the shellcode file 41 | 42 | # Flags: 43 | # ====== 44 | # TODO: -A, --architecture string architecture of the shellcode: 386, amd64 (used with --shikata-ga-nai flag) (default: amd64) 45 | # -h, --help display help 46 | # TODO: -i, --interactive Inject into a new process and interact with it 47 | # TODO: -I, --iterations int number of encoding iterations (used with --shikata-ga-nai flag) (default: 1) 48 | # TODO: -p, --pid uint Pid of process to inject into (0 means injection into ourselves) (default: 0) 49 | # TODO: -n, --process string Process to inject into when running in interactive mode (default: c:\windows\system32\notepad.exe) 50 | # TODO: -r, --rwx-pages Use RWX permissions for memory pages 51 | # TODO: -S, --shikata-ga-nai encode shellcode using shikata ga nai prior to execution 52 | # -t, --timeout int command timeout in seconds (default: 60) 53 | 54 | response = await execute_shellcode(taskData) 55 | 56 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 57 | TaskID=taskData.Task.ID, 58 | Response=response.encode("UTF8"), 59 | )) 60 | 61 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 62 | TaskID=taskData.Task.ID, 63 | Success=True, 64 | Completed=True 65 | ) 66 | return taskResponse 67 | 68 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 69 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 70 | return resp 71 | 72 | async def execute_shellcode(taskData: PTTaskMessageAllData): 73 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 74 | 75 | # ifconfig_results = await interact._stub() 76 | 77 | # if (isBeacon): 78 | # ifconfig_results = await ifconfig_results 79 | 80 | return "This command not yet implemented..." 81 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/implants.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | from tabulate import tabulate 7 | 8 | 9 | class ImplantsArguments(TaskArguments): 10 | def __init__(self, command_line, **kwargs): 11 | super().__init__(command_line, **kwargs) 12 | self.args = [] 13 | 14 | async def parse_arguments(self): 15 | pass 16 | 17 | 18 | class Implants(CommandBase): 19 | cmd = "implants" 20 | needs_admin = False 21 | help_cmd = "implants" 22 | description = "Get the list of implants that Sliver is aware of." 23 | version = 1 24 | author = "Spencer Adolph" 25 | argument_class = ImplantsArguments 26 | attackmapping = [] 27 | 28 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 29 | # List implant builds 30 | 31 | # Usage: 32 | # ====== 33 | # implants [flags] 34 | 35 | # Flags: 36 | # ====== 37 | # TODO: -a, --arch string filter builds by cpu architecture 38 | # TODO: -f, --format string filter builds by artifact format 39 | # -h, --help display help 40 | # TODO: -d, --no-debug filter builds by debug flag 41 | # TODO: -b, --only-beacons filter beacons 42 | # TODO: -s, --only-sessions filter interactive sessions 43 | # TODO: -o, --os string filter builds by operating system 44 | # -t, --timeout int command timeout in seconds (default: 60) 45 | 46 | # Sub Commands: 47 | # ============= 48 | # TODO: rm Remove implant build 49 | 50 | # 'implants' with no options 51 | response = await implants_list(taskData) 52 | 53 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 54 | TaskID=taskData.Task.ID, 55 | Response=response.encode("UTF8"), 56 | )) 57 | 58 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 59 | TaskID=taskData.Task.ID, 60 | Success=True, 61 | Completed=True 62 | ) 63 | 64 | return taskResponse 65 | 66 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 67 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 68 | return resp 69 | 70 | 71 | async def implants_list(taskData: PTTaskMessageAllData): 72 | client = await SliverAPI.create_sliver_client(taskData) 73 | implants = await client.implant_builds() 74 | 75 | # This is the sliver formatting 76 | 77 | # Name Implant Type Template OS/Arch Format Command & Control Debug 78 | # ================ ============== ========== ============= ============ =============================== ======= 79 | # DARK_MITTEN beacon sliver linux/amd64 EXECUTABLE [1] mtls://192.168.17.129:443 false 80 | 81 | # TODO: match sliver formatting 82 | # how to show Template? 83 | # implant.Format is ValueType? 84 | # C2 only shows first URL 85 | # What to show if no implants? 86 | 87 | headers = ["Name", "Implant Type", "OS/Arch", "Command & Control", "Debug"] 88 | data = [(implant.FileName, "beacon" if implant.IsBeacon else "session", f"{implant.GOOS}/{implant.GOARCH}", implant.C2[0].URL, implant.Debug) for implant in implants.values()] 89 | table = tabulate(data, headers=headers) 90 | 91 | return table 92 | 93 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/rm.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class RmArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [ 11 | CommandParameter( 12 | name="full_path", 13 | description="absolute path to the file/folder", 14 | default_value='.', 15 | type=ParameterType.String, 16 | parameter_group_info=[ParameterGroupInfo( 17 | required=False 18 | )] 19 | ), 20 | ] 21 | 22 | async def parse_arguments(self): 23 | self.load_args_from_json_string(self.command_line) 24 | 25 | 26 | class Rm(CommandBase): 27 | cmd = "rm" 28 | needs_admin = False 29 | help_cmd = "rm" 30 | description = "List current directory" 31 | version = 1 32 | author = "Spencer Adolph" 33 | argument_class = RmArguments 34 | attackmapping = [] 35 | supported_ui_features = ["file_browser:remove"] 36 | 37 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 38 | # Command: rm [remote path] 39 | # About: Delete a remote file or directory. 40 | 41 | # Usage: 42 | # ====== 43 | # rm [flags] path 44 | 45 | # Args: 46 | # ===== 47 | # path string path to the file to remove 48 | 49 | # Flags: 50 | # ====== 51 | # TODO: -F, --force ignore safety and forcefully remove files 52 | # -h, --help display help 53 | # TODO: -r, --recursive recursively remove files 54 | # -t, --timeout int command timeout in seconds (default: 60) 55 | 56 | path_to_rm = taskData.args.get_arg('full_path') 57 | rm_results = await rm(taskData, path_to_rm) 58 | 59 | # TODO: this should be refactored 60 | Name = path_to_rm.split('/')[-1] 61 | Parent = "/".join(path_to_rm.split('/')[:-1]) 62 | 63 | await SendMythicRPCFileBrowserCreate(MythicRPCFileBrowserCreateMessage( 64 | TaskID=taskData.Task.ID, 65 | FileBrowser=MythicRPCFileBrowserData( 66 | Name=Name, 67 | ParentPath=Parent, 68 | IsFile=True, 69 | Files=[], 70 | Success=True, 71 | UpdateDeleted=True, 72 | ), 73 | )) 74 | 75 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 76 | TaskID=taskData.Task.ID, 77 | Response=f"{str(rm_results)}".encode("UTF8"), 78 | )) 79 | 80 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 81 | TaskID=taskData.Task.ID, 82 | Success=True, 83 | Completed=True 84 | ) 85 | return taskResponse 86 | 87 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 88 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 89 | return resp 90 | 91 | 92 | async def rm(taskData: PTTaskMessageAllData, path_to_rm: str): 93 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 94 | 95 | rm_results = await interact.rm(remote_path=path_to_rm) 96 | 97 | if (isBeacon): 98 | rm_results = await rm_results 99 | 100 | return rm_results 101 | 102 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/download.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | import gzip 3 | 4 | from mythic_container.MythicCommandBase import * 5 | from mythic_container.MythicRPC import * 6 | from mythic_container.PayloadBuilder import * 7 | 8 | class DownloadArguments(TaskArguments): 9 | def __init__(self, command_line, **kwargs): 10 | super().__init__(command_line, **kwargs) 11 | self.args = [ 12 | CommandParameter( 13 | name="full_path", 14 | description="path to file", 15 | type=ParameterType.String 16 | ), 17 | ] 18 | 19 | async def parse_arguments(self): 20 | self.load_args_from_json_string(self.command_line) 21 | 22 | 23 | class Download(CommandBase): 24 | cmd = "download" 25 | needs_admin = False 26 | help_cmd = "download" 27 | description = "Download a file" 28 | version = 1 29 | author = "Spencer Adolph" 30 | argument_class = DownloadArguments 31 | attackmapping = [] 32 | supported_ui_features = ["file_browser:download"] 33 | 34 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 35 | # Command: download [remote src] 36 | # About: Download a file or directory from the remote system. Directories will be downloaded as a gzipped TAR file. 37 | 38 | # Usage: 39 | # ====== 40 | # download [flags] remote-path [local-path] 41 | 42 | # Args: 43 | # ===== 44 | # remote-path string path to the file or directory to download 45 | # local-path string local path where the downloaded file will be saved (default: .) 46 | 47 | # Flags: 48 | # ====== 49 | # TODO: -F, --file-type string force a specific file type (binary/text) if looting 50 | # -h, --help display help 51 | # TODO: -X, --loot save output as loot 52 | # TODO: -n, --name string name to assign the download if looting 53 | # TODO: -r, --recurse recursively download all files in a directory 54 | # -t, --timeout int command timeout in seconds (default: 60) 55 | # TODO: -T, --type string force a specific loot type (file/cred) if looting 56 | 57 | plaintext = await download(taskData, taskData.args.get_arg('full_path')) 58 | 59 | # TODO: update the file browser and indicate it was downloaded? 60 | results = await SendMythicRPCFileCreate(MythicRPCFileCreateMessage( 61 | TaskID=taskData.Task.ID, 62 | RemotePathOnTarget=taskData.args.get_arg('full_path'), 63 | FileContents=plaintext, 64 | IsScreenshot=False, 65 | IsDownloadFromAgent=True, 66 | # Filename=taskData.args.get_arg('full_path').split('/')[-1], 67 | )) 68 | 69 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 70 | TaskID=taskData.Task.ID, 71 | Response=f"agent file id == {results.AgentFileId}".encode("UTF8"), 72 | )) 73 | 74 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 75 | TaskID=taskData.Task.ID, 76 | Success=True, 77 | Completed=True 78 | ) 79 | return taskResponse 80 | 81 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 82 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 83 | return resp 84 | 85 | async def download(taskData: PTTaskMessageAllData, full_path: str): 86 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 87 | 88 | download_results = await interact.download(remote_path=full_path) 89 | 90 | if (isBeacon): 91 | download_results = await download_results 92 | 93 | plaintext = gzip.decompress(download_results.Data) 94 | 95 | return plaintext 96 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/execute.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | 4 | from mythic_container.MythicCommandBase import * 5 | from mythic_container.MythicRPC import * 6 | from mythic_container.PayloadBuilder import * 7 | 8 | class ExecuteArguments(TaskArguments): 9 | def __init__(self, command_line, **kwargs): 10 | super().__init__(command_line, **kwargs) 11 | self.args = [ 12 | CommandParameter( 13 | name="exe", 14 | description="exe to execute", 15 | type=ParameterType.String 16 | ), 17 | CommandParameter( 18 | name="args", 19 | description="args to pass to executable", 20 | type=ParameterType.Array 21 | ), 22 | CommandParameter( 23 | name="output", 24 | description="capture output or not", 25 | type=ParameterType.Boolean 26 | ), 27 | ] 28 | 29 | async def parse_arguments(self): 30 | self.load_args_from_json_string(self.command_line) 31 | 32 | 33 | class Execute(CommandBase): 34 | cmd = "execute" 35 | needs_admin = False 36 | help_cmd = "execute" 37 | description = "Execute a program on the remote system" 38 | version = 1 39 | author = "Spencer Adolph" 40 | argument_class = ExecuteArguments 41 | attackmapping = [] 42 | 43 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 44 | # Execute a program on the remote system 45 | 46 | # Usage: 47 | # ====== 48 | # execute [flags] command [arguments...] 49 | 50 | # Args: 51 | # ===== 52 | # command string command to execute 53 | # arguments string list arguments to the command 54 | 55 | # Flags: 56 | # ====== 57 | # -h, --help display help 58 | # TODO: -S, --ignore-stderr don't print STDERR output 59 | # TODO: -X, --loot save output as loot 60 | # TODO: -n, --name string name to assign loot (optional) 61 | # TODO: -o, --output capture command output 62 | # TODO: -P, --ppid uint parent process id (optional, Windows only) (default: 0) 63 | # TODO: -s, --save save output to a file 64 | # TODO: -E, --stderr string remote path to redirect STDERR to 65 | # TODO: -O, --stdout string remote path to redirect STDOUT to 66 | # -t, --timeout int command timeout in seconds (default: 60) 67 | # TODO: -T, --token execute command with current token (windows only) 68 | 69 | execute_results = await execute(taskData) 70 | 71 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 72 | TaskID=taskData.Task.ID, 73 | Response=f"{str(execute_results)}".encode("UTF8"), 74 | )) 75 | 76 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 77 | TaskID=taskData.Task.ID, 78 | Success=True, 79 | Completed=True 80 | ) 81 | return taskResponse 82 | 83 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 84 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 85 | return resp 86 | 87 | async def execute(taskData: PTTaskMessageAllData): 88 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 89 | 90 | # TODO: get these from function parameters and extract in the parent function instead 91 | exe = taskData.args.get_arg('exe') 92 | args = taskData.args.get_arg('args') 93 | output = taskData.args.get_arg('output') 94 | 95 | execute_results = await interact.execute(exe=exe, args=args, output=output) 96 | 97 | if (isBeacon): 98 | execute_results = await execute_results 99 | 100 | return execute_results 101 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/execute_assembly.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class ExecuteAssemblyArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class ExecuteAssembly(CommandBase): 17 | cmd = "execute_assembly" 18 | needs_admin = False 19 | help_cmd = "execute_assembly" 20 | description = "(Windows Only) Executes the .NET assembly in a child process" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = ExecuteAssemblyArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # TODO: ensure this command is only loaded into windows implants... 28 | 29 | # Command: execute-assembly [local path to assembly] [arguments] 30 | # About: (Windows Only) Executes the .NET assembly in a child process. 31 | 32 | # Usage: 33 | # ====== 34 | # execute-assembly [flags] filepath [arguments...] 35 | 36 | # Args: 37 | # ===== 38 | # filepath string path the assembly file 39 | # arguments string list arguments to pass to the assembly entrypoint (default: []) 40 | 41 | # Flags: 42 | # ====== 43 | # TODO: -M, --amsi-bypass Bypass AMSI on Windows (only supported when used with --in-process) 44 | # TODO: -d, --app-domain string AppDomain name to create for .NET assembly. Generated randomly if not set. 45 | # TODO: -a, --arch string Assembly target architecture: x86, x64, x84 (x86+x64) (default: x84) 46 | # TODO: -c, --class string Optional class name (required for .NET DLL) 47 | # TODO: -E, --etw-bypass Bypass ETW on Windows (only supported when used with --in-process) 48 | # -h, --help display help 49 | # TODO: -i, --in-process Run in the current sliver process 50 | # TODO: -X, --loot save output as loot 51 | # TODO: -m, --method string Optional method (a method is required for a .NET DLL) 52 | # TODO: -n, --name string name to assign loot (optional) 53 | # TODO: -P, --ppid uint parent process id (optional) (default: 0) 54 | # TODO: -p, --process string hosting process to inject into (default: notepad.exe) 55 | # TODO: -A, --process-arguments string arguments to pass to the hosting process 56 | # TODO: -r, --runtime string Runtime to use for running the assembly (only supported when used with --in-process) 57 | # TODO: -s, --save save output to file 58 | # -t, --timeout int command timeout in seconds (default: 60) 59 | 60 | response = await execute_assembly(taskData) 61 | 62 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 63 | TaskID=taskData.Task.ID, 64 | Response=response.encode("UTF8"), 65 | )) 66 | 67 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 68 | TaskID=taskData.Task.ID, 69 | Success=True, 70 | Completed=True 71 | ) 72 | return taskResponse 73 | 74 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 75 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 76 | return resp 77 | 78 | async def execute_assembly(taskData: PTTaskMessageAllData): 79 | # interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 80 | 81 | # ifconfig_results = await interact._stub() 82 | 83 | # if (isBeacon): 84 | # ifconfig_results = await ifconfig_results 85 | 86 | return "This command not yet implemented..." 87 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/builder.py: -------------------------------------------------------------------------------- 1 | import pathlib 2 | from mythic_container.PayloadBuilder import * 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from ..SliverRequests import SliverAPI 6 | 7 | from sliver import SliverClientConfig, SliverClient 8 | 9 | import asyncio 10 | 11 | 12 | async def setupApiThreads(): 13 | # print('setup api threads') 14 | 15 | sliverapi_payloads = await SendMythicRPCPayloadSearch(MythicRPCPayloadSearchMessage( 16 | CallbackID=1, 17 | PayloadTypes=['sliverapi'] 18 | )) 19 | 20 | for sliverapi_payload in sliverapi_payloads.Payloads: 21 | # print('got payload to setup') 22 | client = await SliverAPI.create_sliver_client_with_config(sliverapi_payload.UUID, sliverapi_payload.BuildParameters[0].Value) 23 | 24 | # TODO: could further improve here by looking for sessions that now exist (that were created while the Mythic service was offline) 25 | # Create those payloads and callbacks 26 | # Would fit the usecase of connecting mythic to an already existing sliver operation with lots of callbacks 27 | 28 | # sessions = await client.sessions() 29 | # for session in sessions: 30 | # # if payload uuid doesn't exist, create it and then create the callback? 31 | # sliverimplant_payloads = await SendMythicRPCPayloadSearch(MythicRPCPayloadSearchMessage( 32 | # CallbackID=1, 33 | # PayloadUUID=session.ID 34 | # )) 35 | # if (len(sliverimplant_payloads.Payloads) == 0): 36 | # create the payload and callback associated and thread? 37 | 38 | # TODO: better name for this 39 | initial_thread_to_handle_api_events = None 40 | 41 | class SliverApi(PayloadType): 42 | # TODO: understand why this fires off twice 43 | def __init__(self, **kwargs): 44 | super().__init__(**kwargs) 45 | 46 | # This class is instantiated during start_and_run_forever, as well as when payloads are generated 47 | # In this case, I only want this to run setupApiThreads when the service first starts up 48 | global initial_thread_to_handle_api_events 49 | if (initial_thread_to_handle_api_events == None): 50 | initial_thread_to_handle_api_events = asyncio.create_task(setupApiThreads()) 51 | 52 | name = "sliverapi" 53 | author = "Spencer Adolph" 54 | note = """This payload connects to sliver to run meta commands.""" 55 | supported_os = [SupportedOS("sliver")] 56 | file_extension = "" 57 | wrapper = False 58 | wrapped_payloads = [] 59 | supports_dynamic_loading = False 60 | c2_profiles = [] 61 | mythic_encrypts = False 62 | translation_container = None 63 | agent_type = "service" 64 | agent_path = pathlib.Path(".") / "sliverapi" 65 | agent_icon_path = agent_path / "agent_functions" / "sliver.svg" 66 | agent_code_path = agent_path / "agent_code" 67 | build_steps = [] 68 | build_parameters = [ 69 | BuildParameter( 70 | name="CONFIGFILE", 71 | description="Sliver Operator Config (select file)", 72 | parameter_type=BuildParameterType.File, 73 | ) 74 | ] 75 | 76 | async def build(self) -> BuildResponse: 77 | # this function gets called to create an instance of your payload 78 | resp = BuildResponse(status=BuildStatus.Success) 79 | ip = "127.0.0.1" 80 | create_callback = await SendMythicRPCCallbackCreate(MythicRPCCallbackCreateMessage( 81 | PayloadUUID=self.uuid, 82 | C2ProfileName="", 83 | User="SliverAPI", 84 | Host="SliverAPI", 85 | Ip=ip, 86 | IntegrityLevel=3, 87 | ExtraInfo=self.uuid, 88 | )) 89 | 90 | # TODO: fail building if callback already exists for this sliver config? 91 | 92 | # doing this will cache the connection and start to read events 93 | await SliverAPI.create_sliver_client_with_config(self.uuid, self.build_parameters[0].value) 94 | 95 | if not create_callback.Success: 96 | logger.info(create_callback.Error) 97 | else: 98 | logger.info(create_callback.CallbackUUID) 99 | return resp 100 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/info.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class InfoArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [] 11 | 12 | async def parse_arguments(self): 13 | pass 14 | 15 | 16 | class Info(CommandBase): 17 | cmd = "info" 18 | needs_admin = False 19 | help_cmd = "info" 20 | description = "Get information about a Sliver by name, or for the active Sliver" 21 | version = 1 22 | author = "Spencer Adolph" 23 | argument_class = InfoArguments 24 | attackmapping = [] 25 | 26 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 27 | # Command: info 28 | # About: Get information about a Sliver by name, or for the active Sliver. 29 | 30 | # Usage: 31 | # ====== 32 | # info [flags] [session] 33 | 34 | # Args: 35 | # ===== 36 | # session string session ID 37 | 38 | # Flags: 39 | # ====== 40 | # -h, --help display help 41 | # -t, --timeout int command timeout in seconds (default: 60) 42 | 43 | info_results = await info(taskData) 44 | 45 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 46 | TaskID=taskData.Task.ID, 47 | Response=info_results.encode("UTF8"), 48 | )) 49 | 50 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 51 | TaskID=taskData.Task.ID, 52 | Success=True, 53 | Completed=True 54 | ) 55 | return taskResponse 56 | 57 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 58 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 59 | return resp 60 | 61 | async def info(taskData: PTTaskMessageAllData): 62 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 63 | 64 | # Session ID: d7e28b37-88be-44f9-ba31-8913bf535d1a 65 | # Name: FUNNY_DRIVEWAY 66 | # Hostname: ubuntu 67 | # UUID: c744e366-d14c-4bf3-94c3-558012eda8a1 68 | # Username: root 69 | # UID: 0 70 | # GID: 0 71 | # PID: 120952 72 | # OS: linux 73 | # Version: Linux ubuntu 6.5.0-27-generic 74 | # Locale: en-US 75 | # Arch: amd64 76 | # Active C2: mtls://192.168.17.129:443 77 | # Remote Address: 192.168.17.129:50072 78 | # Proxy URL: 79 | # Reconnect Interval: 1m0s 80 | # First Contact: Fri Apr 12 21:11:25 CDT 2024 (28m16s ago) 81 | # Last Checkin: Fri Apr 12 21:39:39 CDT 2024 (2s ago) 82 | 83 | responseString = [] 84 | responseString.append(f"Session Id: {interact.session_id}") 85 | responseString.append(f"Name: {interact.name}") 86 | responseString.append(f"Hostname: {interact.hostname}") 87 | responseString.append(f"UUID: {interact.uuid}") 88 | responseString.append(f"Username: {interact.username}") 89 | responseString.append(f"UID: {interact.uid}") 90 | responseString.append(f"GID: {interact.gid}") 91 | responseString.append(f"PID: {interact.pid}") 92 | responseString.append(f"OS: {interact.os}") 93 | responseString.append(f"Version: {interact.version}") 94 | # responseString.append(f"Locale: {interact.L}") 95 | responseString.append(f"Arch: {interact.arch}") 96 | responseString.append(f"Active C2: {interact.active_c2}") 97 | responseString.append(f"Remote Address: {interact.remote_address}") 98 | responseString.append(f"Proxy URL: {interact.proxy_url}") 99 | responseString.append(f"Reconnect Interval: {interact.reconnect_interval}") 100 | # responseString.append(f"First Contact: {interact.last_checkin}") 101 | responseString.append(f"Last Checkin: {interact.last_checkin}") 102 | 103 | finalResponse = "\n".join(responseString) 104 | 105 | return finalResponse 106 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/regenerate.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | from sliver import SliverClientConfig, SliverClient, client_pb2 8 | from tabulate import tabulate 9 | 10 | class RegenerateArguments(TaskArguments): 11 | def __init__(self, command_line, **kwargs): 12 | super().__init__(command_line, **kwargs) 13 | self.args = [ 14 | CommandParameter( 15 | name="implant-name", 16 | cli_name="implant-name", 17 | display_name="implant-name", 18 | description="implant-name", 19 | # type=ParameterType.Number, 20 | type=ParameterType.ChooseOne, 21 | dynamic_query_function=self.get_implants, 22 | # default_value=-1, 23 | parameter_group_info=[ 24 | ParameterGroupInfo( 25 | required=True, 26 | group_name="Default", 27 | ui_position=1 28 | ), 29 | ] 30 | ), 31 | ] 32 | 33 | async def get_implants(self, inputMsg: PTRPCDynamicQueryFunctionMessage) -> PTRPCDynamicQueryFunctionMessageResponse: 34 | implant_names = [] 35 | 36 | # TODO: this is quick and dirty, could refactor this (and put into SliverAPI file) 37 | this_payload = await SendMythicRPCPayloadSearch(MythicRPCPayloadSearchMessage( 38 | CallbackID=inputMsg.Callback, 39 | PayloadUUID=inputMsg.PayloadUUID 40 | )) 41 | 42 | filecontent = await SendMythicRPCFileGetContent(MythicRPCFileGetContentMessage( 43 | AgentFileId=this_payload.Payloads[0].BuildParameters[0].Value 44 | )) 45 | 46 | config = SliverClientConfig.parse_config(filecontent.Content) 47 | client = SliverClient(config) 48 | await client.connect() 49 | list_of_implants = await client.implant_builds() 50 | for key, value in list_of_implants.items(): 51 | implant_names.append(key) 52 | 53 | return PTRPCDynamicQueryFunctionMessageResponse(Success=True, Choices=implant_names) 54 | 55 | 56 | 57 | async def parse_arguments(self): 58 | self.load_args_from_json_string(self.command_line) 59 | 60 | 61 | class Regenerate(CommandBase): 62 | cmd = "regenerate" 63 | needs_admin = False 64 | help_cmd = "regenerate" 65 | description = "Regenerate an implant" 66 | version = 1 67 | author = "Spencer Adolph" 68 | argument_class = RegenerateArguments 69 | attackmapping = [] 70 | 71 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 72 | # Regenerate an implant 73 | 74 | # Usage: 75 | # ====== 76 | # regenerate [flags] implant-name 77 | 78 | # Args: 79 | # ===== 80 | # implant-name string name of the implant 81 | 82 | # Flags: 83 | # ====== 84 | # -h, --help display help 85 | # -s, --save string directory/file to the binary to 86 | # -t, --timeout int command timeout in seconds (default: 60) 87 | 88 | response = await regenerate(taskData) 89 | 90 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 91 | TaskID=taskData.Task.ID, 92 | Response=response.encode("UTF8"), 93 | )) 94 | 95 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 96 | TaskID=taskData.Task.ID, 97 | Success=True, 98 | Completed=True 99 | ) 100 | 101 | return taskResponse 102 | 103 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 104 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 105 | return resp 106 | 107 | 108 | async def regenerate(taskData: PTTaskMessageAllData): 109 | client = await SliverAPI.create_sliver_client(taskData) 110 | implant_name = taskData.args.get_arg('implant-name') 111 | regenerate_result = await client.regenerate_implant(implant_name=implant_name) 112 | implant_bytes = regenerate_result.File.Data 113 | 114 | # TODO: match sliver formatting 115 | 116 | return f"generated {regenerate_result.File.Name}" 117 | -------------------------------------------------------------------------------- /Payload_Type/sliverimplant/sliverimplant/agent_functions/ls.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | class LsArguments(TaskArguments): 8 | def __init__(self, command_line, **kwargs): 9 | super().__init__(command_line, **kwargs) 10 | self.args = [ 11 | CommandParameter( 12 | name="full_path", 13 | description="absolute path to the file/folder", 14 | default_value='.', 15 | type=ParameterType.String, 16 | parameter_group_info=[ParameterGroupInfo( 17 | required=False 18 | )] 19 | ), 20 | ] 21 | 22 | async def parse_arguments(self): 23 | self.load_args_from_json_string(self.command_line) 24 | 25 | 26 | class Ls(CommandBase): 27 | cmd = "ls" 28 | needs_admin = False 29 | help_cmd = "ls" 30 | description = "List current directory" 31 | version = 1 32 | author = "Spencer Adolph" 33 | argument_class = LsArguments 34 | attackmapping = [] 35 | supported_ui_features = ["file_browser:list"] 36 | 37 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 38 | # Command: ls 39 | # About: List remote files in current directory, or path if provided. 40 | 41 | # Usage: 42 | # ====== 43 | # ls [flags] [path] 44 | 45 | # Args: 46 | # ===== 47 | # path string path to enumerate (default: .) 48 | 49 | # Flags: 50 | # ====== 51 | # -h, --help display help 52 | # TODO: -m, --modified sort by modified time 53 | # TODO: -r, --reverse reverse sort order 54 | # TODO: -s, --size sort by size 55 | # -t, --timeout int command timeout in seconds (default: 60) 56 | 57 | path_to_ls = taskData.args.get_arg('full_path') 58 | ls_results = await ls(taskData, path_to_ls) 59 | 60 | # PATH will always be the 'directory' that is queried 61 | # Files will always be files/directories inside the path 62 | 63 | # This is the shape of data that sliver offers 64 | 65 | # Path: "/home" 66 | # Exists: true 67 | # Files { 68 | # Name: "ubuntu" 69 | # IsDir: true 70 | # Size: 4096 71 | # ModTime: 1712706688 72 | # Mode: "drwxr-x---" 73 | # } 74 | # timezone: "CDT" 75 | # timezoneOffset: -18000 76 | 77 | files = [] 78 | if ls_results.Files != []: 79 | for file in ls_results.Files: 80 | files.append(MythicRPCFileBrowserDataChildren( 81 | Name=file.Name, 82 | IsFile=not file.IsDir, 83 | Permissions={"perms": file.Mode}, 84 | ModifyTime=file.ModTime, 85 | Size=file.Size 86 | ) 87 | ) 88 | 89 | Name = ls_results.Path.split('/')[-1] 90 | Parent = "/".join(ls_results.Path.split('/')[:-1]) 91 | 92 | # # edge case (probably check length of parent path list instead) 93 | if Parent == '': 94 | Parent = '/' 95 | 96 | # # TODO: refactor all of this for edge cases 97 | if path_to_ls == '/': 98 | Name = '/' 99 | Parent = '' 100 | 101 | # TODO: currently unable to directly list a file, only directories 102 | 103 | await SendMythicRPCFileBrowserCreate(MythicRPCFileBrowserCreateMessage( 104 | TaskID=taskData.Task.ID, 105 | FileBrowser=MythicRPCFileBrowserData( 106 | Name=Name, 107 | ParentPath=Parent, 108 | IsFile=False, 109 | Files=files, 110 | # Success=True 111 | ), 112 | )) 113 | 114 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 115 | TaskID=taskData.Task.ID, 116 | Response=f"{str(ls_results)}".encode("UTF8"), 117 | )) 118 | 119 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 120 | TaskID=taskData.Task.ID, 121 | Success=True, 122 | Completed=True 123 | ) 124 | return taskResponse 125 | 126 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 127 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 128 | return resp 129 | 130 | 131 | async def ls(taskData: PTTaskMessageAllData, path_to_ls: str): 132 | interact, isBeacon = await SliverAPI.create_sliver_interact(taskData) 133 | 134 | ls_results = await interact.ls(remote_path=path_to_ls) 135 | 136 | if (isBeacon): 137 | ls_results = await ls_results 138 | 139 | return ls_results 140 | 141 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/agent_functions/jobs.py: -------------------------------------------------------------------------------- 1 | from ..SliverRequests import SliverAPI 2 | 3 | from mythic_container.MythicCommandBase import * 4 | from mythic_container.MythicRPC import * 5 | from mythic_container.PayloadBuilder import * 6 | 7 | from sliver import SliverClientConfig, SliverClient, client_pb2 8 | from tabulate import tabulate 9 | 10 | class JobsArguments(TaskArguments): 11 | def __init__(self, command_line, **kwargs): 12 | super().__init__(command_line, **kwargs) 13 | self.args = [ 14 | CommandParameter( 15 | name="list", 16 | cli_name="list", 17 | display_name="jobs", 18 | type=ParameterType.Boolean, 19 | default_value=True, 20 | description="jobs", 21 | parameter_group_info=[ 22 | ParameterGroupInfo( 23 | required=False, 24 | group_name="Default", 25 | ui_position=1 26 | ), 27 | ]), 28 | CommandParameter( 29 | name="kill", 30 | cli_name="kill", 31 | display_name="job id to kill", 32 | description="job id to kill", 33 | # type=ParameterType.Number, 34 | type=ParameterType.ChooseOne, 35 | dynamic_query_function=self.get_jobs, 36 | # default_value=-1, 37 | parameter_group_info=[ 38 | ParameterGroupInfo( 39 | required=True, 40 | group_name="kill", 41 | ui_position=1 42 | ), 43 | ] 44 | ), 45 | ] 46 | 47 | async def get_jobs(self, inputMsg: PTRPCDynamicQueryFunctionMessage) -> PTRPCDynamicQueryFunctionMessageResponse: 48 | job_ids = [] 49 | 50 | # TODO: this is quick and dirty, could refactor this (and put into SliverAPI file) 51 | this_payload = await SendMythicRPCPayloadSearch(MythicRPCPayloadSearchMessage( 52 | CallbackID=inputMsg.Callback, 53 | PayloadUUID=inputMsg.PayloadUUID 54 | )) 55 | 56 | filecontent = await SendMythicRPCFileGetContent(MythicRPCFileGetContentMessage( 57 | AgentFileId=this_payload.Payloads[0].BuildParameters[0].Value 58 | )) 59 | 60 | config = SliverClientConfig.parse_config(filecontent.Content) 61 | client = SliverClient(config) 62 | await client.connect() 63 | list_of_jobs = await client.jobs() 64 | for job_item in list_of_jobs: 65 | job_ids.append(f"{job_item.ID}") 66 | 67 | return PTRPCDynamicQueryFunctionMessageResponse(Success=True, Choices=job_ids) 68 | 69 | async def parse_arguments(self): 70 | self.load_args_from_json_string(self.command_line) 71 | 72 | 73 | class Jobs(CommandBase): 74 | cmd = "jobs" 75 | needs_admin = False 76 | help_cmd = "jobs" 77 | description = "Get the list of jobs that Sliver is aware of." 78 | version = 1 79 | author = "Spencer Adolph" 80 | argument_class = JobsArguments 81 | attackmapping = [] 82 | 83 | async def create_go_tasking(self, taskData: MythicCommandBase.PTTaskMessageAllData) -> MythicCommandBase.PTTaskCreateTaskingMessageResponse: 84 | # Command: jobs 85 | # About: Manage jobs/listeners. 86 | 87 | # Usage: 88 | # ====== 89 | # jobs [flags] 90 | 91 | # Flags: 92 | # ====== 93 | # -h, --help display help 94 | # -k, --kill int kill a background job (default: -1) 95 | # TODO: -K, --kill-all kill all jobs 96 | # -t, --timeout int command timeout in seconds (default: 60) 97 | 98 | if (taskData.parameter_group_name == 'Default'): 99 | response = await jobs_list(taskData) 100 | 101 | if (taskData.parameter_group_name == 'kill'): 102 | job_id = int(taskData.args.get_arg('kill')) 103 | response = await jobs_kill(taskData, job_id) 104 | 105 | await SendMythicRPCResponseCreate(MythicRPCResponseCreateMessage( 106 | TaskID=taskData.Task.ID, 107 | Response=response.encode("UTF8"), 108 | )) 109 | 110 | taskResponse = MythicCommandBase.PTTaskCreateTaskingMessageResponse( 111 | TaskID=taskData.Task.ID, 112 | Success=True, 113 | Completed=True 114 | ) 115 | 116 | return taskResponse 117 | 118 | async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse: 119 | resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True) 120 | return resp 121 | 122 | 123 | async def jobs_list(taskData: PTTaskMessageAllData): 124 | client = await SliverAPI.create_sliver_client(taskData) 125 | jobs = await client.jobs() 126 | 127 | if (len(jobs) == 0): 128 | return "[*] No active jobs" 129 | 130 | # TODO: match sliver formatting 131 | 132 | headers = ["ID", "Name", "Protocol", "Port"] 133 | data = [(job.ID, job.Name, job.Protocol, job.Port) for job in jobs] 134 | table = tabulate(data, headers=headers) 135 | 136 | return table 137 | 138 | 139 | async def jobs_kill(taskData: PTTaskMessageAllData, job_id: int): 140 | client = await SliverAPI.create_sliver_client(taskData) 141 | kill_response = await client.kill_job(job_id=job_id) 142 | return f"[*] Successfully killed job #{kill_response.ID}" 143 | -------------------------------------------------------------------------------- /Payload_Type/sliverapi/sliverapi/SliverRequests/SliverAPI.py: -------------------------------------------------------------------------------- 1 | from mythic_container.MythicCommandBase import * 2 | from mythic_container.MythicRPC import SendMythicRPCFileGetContent, MythicRPCFileGetContentMessage 3 | from sliver import SliverClientConfig, SliverClient, client_pb2 4 | from mythic_container.MythicCommandBase import * 5 | from mythic_container.MythicRPC import * 6 | from mythic_container.PayloadBuilder import * 7 | import asyncio 8 | 9 | sliver_clients = {} 10 | 11 | async def create_sliver_client(taskData: PTTaskMessageAllData): 12 | # builder.py should have cached it by calling create_sliver_client_with_config 13 | if (f"{taskData.Payload.UUID}" in sliver_clients.keys()): 14 | return sliver_clients[f"{taskData.Payload.UUID}"] 15 | 16 | filecontent = await SendMythicRPCFileGetContent(MythicRPCFileGetContentMessage( 17 | # TODO: could possibly mirror this in the implant create_client, and get rid of extraInfo? (payload vs callback....) 18 | AgentFileId=taskData.BuildParameters[0].Value 19 | )) 20 | 21 | config = SliverClientConfig.parse_config(filecontent.Content) 22 | client = SliverClient(config) 23 | 24 | await client.connect() 25 | 26 | sliver_clients[f"{taskData.Payload.UUID}"] = client 27 | 28 | # 'Sync' Events from the Server 29 | # TODO: refactor this into the builder.py 30 | # TODO: is this a weird python closure? (and does that matter?) 31 | async def read_server_events(): 32 | async for data in client.events(): 33 | await handleSliverEvent(data, taskData.BuildParameters[0].Value) 34 | asyncio.create_task(read_server_events()) 35 | 36 | # TODO: sync callbacks and payloads here 37 | 38 | return client 39 | 40 | 41 | # TODO: could refactor this more 42 | async def create_sliver_client_with_config(payload_uuid, configFileId): 43 | filecontent = await SendMythicRPCFileGetContent(MythicRPCFileGetContentMessage( 44 | # TODO: could possibly mirror this in the implant create_client, and get rid of extraInfo? (payload vs callback....) 45 | AgentFileId=configFileId 46 | )) 47 | 48 | config = SliverClientConfig.parse_config(filecontent.Content) 49 | client = SliverClient(config) 50 | await client.connect() 51 | 52 | sliver_clients[f"{payload_uuid}"] = client 53 | 54 | # # TODO: refactor this into the builder.py 55 | async def read_server_events(): 56 | async for data in client.events(): 57 | await handleSliverEvent(data, configFileId) 58 | asyncio.create_task(read_server_events()) 59 | 60 | # TODO: sync callbacks and payloads here 61 | 62 | return client 63 | 64 | async def handleSliverEvent(event: client_pb2.Event, configFileId): 65 | print(event.EventType) 66 | 67 | if (event.EventType == 'session-connected'): 68 | # print(event.Session) 69 | 70 | # create payload 71 | sliver_os_table = { 72 | 'linux': 'Linux', 73 | 'windows': 'Windows' 74 | } 75 | 76 | # TODO: only include 'shell' for interactive sessions, not beacons 77 | 78 | new_payload = MythicRPCPayloadCreateFromScratchMessage( 79 | # TODO: this may need some mythic improvements 80 | TaskID=1, 81 | 82 | PayloadConfiguration=MythicRPCPayloadConfiguration( 83 | payload_type="sliverimplant", 84 | uuid=event.Session.ID, 85 | selected_os=sliver_os_table[event.Session.OS], 86 | description=f"(no download) using sliver interactive implant for {event.Session.ID}", 87 | build_parameters=[], 88 | c2_profiles=[], 89 | # TODO: figure out if possible to not specify these manually 90 | commands=['ifconfig', 'download', 'upload', 'ls', 'ps', 'ping', 'whoami', 'screenshot', 'netstat', 'getgid', 'getuid', 'getpid', 'cat', 'cd', 'pwd', 'info', 'execute', 'mkdir', 'shell', 'terminate', 'rm'] 91 | ), 92 | ) 93 | scratchBuild = await SendMythicRPCPayloadCreateFromScratch(new_payload) 94 | 95 | # create callback 96 | extra_info = json.dumps({ 97 | # TODO: if buildparams changes, then this won't work anymore (could make it more resilient) 98 | "slivercfg_fileid": configFileId, 99 | "type": 'session' 100 | }) 101 | response = await SendMythicRPCCallbackCreate(MythicRPCCallbackCreateMessage( 102 | PayloadUUID=event.Session.ID, 103 | 104 | C2ProfileName="", 105 | IntegrityLevel=3, 106 | Host=event.Session.Hostname, 107 | User=event.Session.Username, 108 | Ip=event.Session.RemoteAddress.split(':')[0], 109 | ExtraInfo=extra_info, 110 | PID=event.Session.PID 111 | )) 112 | 113 | if (event.EventType == 'session-disconnected'): 114 | # TODO: often hard-coding ID=1 cause not sure how else to get results back... 115 | # This thread isn't running on behalf of a specific callback 116 | # Could potentially pass down the CallbackID of the instantiated sliverapi callback 117 | # All the way from the parent function that called this? 118 | # it works for now tho........ 119 | callbacks = await SendMythicRPCCallbackSearch(MythicRPCCallbackSearchMessage( 120 | AgentCallbackID=1, 121 | SearchCallbackPID=event.Session.PID 122 | )) 123 | 124 | await SendMythicRPCCallbackUpdate(MythicRPCCallbackUpdateMessage( 125 | CallbackID=callbacks.Results[0].ID, 126 | TaskID=1, 127 | PID=event.Session.PID, 128 | 129 | Description='disconnected!' 130 | )) 131 | --------------------------------------------------------------------------------