file upload completed
This commit is contained in:
@@ -1,104 +0,0 @@
|
||||
from mythic_container.MythicCommandBase import *
|
||||
from mythic_container.MythicRPC import *
|
||||
import os
|
||||
|
||||
|
||||
class UploadArguments(TaskArguments):
|
||||
def __init__(self, command_line, **kwargs):
|
||||
super().__init__(command_line, **kwargs)
|
||||
self.args = [
|
||||
CommandParameter(
|
||||
name="file",
|
||||
type=ParameterType.File,
|
||||
description="File to upload to the target",
|
||||
),
|
||||
CommandParameter(
|
||||
name="path",
|
||||
type=ParameterType.String,
|
||||
description="Path where the file should be saved on the target",
|
||||
),
|
||||
]
|
||||
|
||||
async def parse_arguments(self):
|
||||
if len(self.command_line) == 0:
|
||||
raise ValueError("Must supply a file and path")
|
||||
|
||||
parts = self.command_line.split(" ", 1)
|
||||
if len(parts) != 2:
|
||||
raise ValueError("Must supply both file and path: upload <file_id> <path>")
|
||||
|
||||
self.add_arg("file", parts[0])
|
||||
self.add_arg("path", parts[1])
|
||||
|
||||
async def parse_dictionary(self, dictionary_arguments):
|
||||
if "file" in dictionary_arguments:
|
||||
self.add_arg("file", dictionary_arguments["file"])
|
||||
if "path" in dictionary_arguments:
|
||||
# Normalize path: replace double backslashes with single backslash
|
||||
path = dictionary_arguments["path"]
|
||||
if path:
|
||||
path = path.replace("\\\\", "\\")
|
||||
self.add_arg("path", path)
|
||||
|
||||
|
||||
class UploadCommand(CommandBase):
|
||||
cmd = "upload"
|
||||
needs_admin = False
|
||||
help_cmd = "upload <file> <path>"
|
||||
description = "Upload a file from the Mythic server to the target"
|
||||
version = 1
|
||||
author = "@KaseyaOFSTeam"
|
||||
argument_class = UploadArguments
|
||||
|
||||
async def create_go_tasking(self, taskData: PTTaskMessageAllData) -> PTTaskCreateTaskingMessageResponse:
|
||||
response = PTTaskCreateTaskingMessageResponse(
|
||||
TaskID=taskData.Task.ID,
|
||||
Success=True,
|
||||
)
|
||||
|
||||
file_id = taskData.args.get_arg("file")
|
||||
path = taskData.args.get_arg("path")
|
||||
|
||||
# Get file information to extract filename
|
||||
try:
|
||||
file_search = await SendMythicRPCFileSearch(MythicRPCFileSearchMessage(
|
||||
AgentFileId=file_id,
|
||||
LimitByCallback=False,
|
||||
TaskID=taskData.Task.ID
|
||||
))
|
||||
|
||||
if file_search.Success and len(file_search.Files) > 0:
|
||||
file_info = file_search.Files[0]
|
||||
filename = file_info.Filename
|
||||
|
||||
# If path is empty, use current directory
|
||||
if not path or path.strip() == "":
|
||||
path = ".\\" + filename
|
||||
# If path ends with backslash or is a directory, append filename
|
||||
elif path.endswith("\\") or path.endswith("/"):
|
||||
# Path is a directory, append filename
|
||||
path = path.rstrip("\\/") + "\\" + filename
|
||||
# Check if path is just a directory (no filename extension and ends with no backslash)
|
||||
elif not os.path.basename(path) or (not path.endswith("\\") and os.path.isabs(path) and not os.path.splitext(os.path.basename(path))[1]):
|
||||
# Try to check if it's a directory by seeing if basename has no extension
|
||||
# This is a heuristic - if path has no extension and looks like a directory, append filename
|
||||
if not os.path.splitext(os.path.basename(path))[1]:
|
||||
# No extension, might be a directory
|
||||
path = path.rstrip("\\/") + "\\" + filename
|
||||
|
||||
response.DisplayParams = f"file_id: {file_id}, path: {path}, filename: {filename}"
|
||||
# Update the path argument with the final path (including filename if needed)
|
||||
taskData.args.add_arg("path", path)
|
||||
else:
|
||||
# If we can't get file info, just use the path as-is
|
||||
response.DisplayParams = f"file_id: {file_id}, path: {path}"
|
||||
except Exception as e:
|
||||
# If we can't get file info, just use the path as-is
|
||||
response.DisplayParams = f"file_id: {file_id}, path: {path} (warning: could not get filename: {str(e)})"
|
||||
|
||||
return response
|
||||
|
||||
async def process_response(self, task: PTTaskMessageAllData, response: any) -> PTTaskProcessResponseMessageResponse:
|
||||
resp = PTTaskProcessResponseMessageResponse(TaskID=task.Task.ID, Success=True)
|
||||
return resp
|
||||
|
||||
Reference in New Issue
Block a user