Skip to content

Commit

Permalink
updated parsing for rm to match download
Browse files Browse the repository at this point in the history
  • Loading branch information
checkymander committed Feb 6, 2024
1 parent 9a89ae7 commit e876deb
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class DownloadArgs

public bool Validate(out string message)
{
message = String.Empty;
message = string.Empty;

//If we didn't get a path, then return an error
if (string.IsNullOrEmpty(path))
Expand Down
53 changes: 53 additions & 0 deletions Payload_Type/athena/athena/agent_code/rm/RmArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace rm
{
public class RmArgs
{
public string path { get; set; }
public string file { get; set; }
public string host { get; set; }

public bool Validate(out string message)
{
message = string.Empty;

//If we didn't get a path, then return an error
if (string.IsNullOrEmpty(path))
{
message = "Missing path parameter";
return false;
}

//If we get to this point we either have a full path, or we're using the file browser and have all three
//If we have a file combine it with the existing path
if (!string.IsNullOrEmpty(file))
{
this.path = Path.Combine(this.path, this.file);
}

//If we have a host, append it to the beginning of the path
if (!string.IsNullOrEmpty(host))
{
if (!host.Equals(Dns.GetHostName(), StringComparison.OrdinalIgnoreCase))
{
host = "\\\\" + host;
this.path = Path.Combine(this.host, this.path);
}
}

if (!File.Exists(this.path))
{
message = "File doesn't exist.";
return false;
}

return true;
}
}
}
21 changes: 7 additions & 14 deletions Payload_Type/athena/athena/agent_code/rm/rm.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Agent.Interfaces;
using Agent.Models;
using Agent.Utilities;
using rm;
using System.Text.Json;

namespace Agent
{
Expand All @@ -17,29 +19,20 @@ public Plugin(IMessageManager messageManager, IAgentConfig config, ILogger logge
}
public async Task Execute(ServerJob job)
{
Dictionary<string, string> args = Misc.ConvertJsonStringToDict(job.task.parameters);
string file = args.ContainsKey("file") ? args["file"] : string.Empty;
string path = args.ContainsKey("path") ? args["path"] : string.Empty;
string host = args.ContainsKey("host") ? args["host"] : string.Empty;
RmArgs args = JsonSerializer.Deserialize<RmArgs>(job.task.parameters);

if (!String.IsNullOrEmpty(host) & !host.StartsWith("\\\\"))
{
host = "\\\\" + host;
}

string fullPath = Path.Combine(host, path, file);
try
{
FileAttributes attr = File.GetAttributes(fullPath);
FileAttributes attr = File.GetAttributes(args.path);
if (attr.HasFlag(FileAttributes.Directory))
{
Directory.Delete(fullPath.Replace("\"", ""), true);
Directory.Delete(args.path.Replace("\"", ""), true);
}
else
{
File.Delete(fullPath.Replace("\"", ""));
File.Delete(args.path.Replace("\"", ""));
}
messageManager.Write($"{fullPath} removed.", job.task.id, true);
messageManager.Write($"{args.path} removed.", job.task.id, true);

}
catch (Exception e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ async def parse_arguments(self):
combined_path = self.build_file_path({"host":"","folder_path":path_parts["folder_path"],"file_name":path_parts["file_name"]})
self.add_arg("path", combined_path)
self.add_arg("host", path_parts["host"])

class DownloadCommand(CommandBase):
cmd = "download"
needs_admin = False
Expand Down
83 changes: 58 additions & 25 deletions Payload_Type/athena/athena/mythic/agent_functions/rm.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

from mythic_container.MythicCommandBase import *
import json
import json, re, os
from mythic_container.MythicRPC import *

from .athena_utils import message_converter
Expand All @@ -21,16 +21,6 @@ def __init__(self, command_line, **kwargs):
required=False,
),
]),
# CommandParameter(
# name="file",
# cli_name="File",
# display_name="File",
# type=ParameterType.String, description="The file to remove on the specified host (used by file browser)",
# parameter_group_info=[
# ParameterGroupInfo(
# required=False,
# ),
# ]),
CommandParameter(
name="host",
cli_name="Host",
Expand All @@ -44,22 +34,65 @@ def __init__(self, command_line, **kwargs):
]),
]

def build_file_path(self, parsed_info):
if parsed_info['host']:
# If it's a UNC path
file_path = f"\\\\{parsed_info['host']}\\{parsed_info['folder_path']}\\{parsed_info['file_name']}"
else:
# If it's a Windows or Linux path
file_path = os.path.join(parsed_info['folder_path'], parsed_info['file_name'])

return file_path

def parse_file_path(self, file_path):
# Check if the path is a UNC path
unc_match = re.match(r'^\\\\([^\\]+)\\(.+)$', file_path)

if unc_match:
host = unc_match.group(1)
folder_path = unc_match.group(2)
file_name = None # Set file_name to None if the path ends in a folder
if folder_path:
file_name = os.path.basename(folder_path)
folder_path = os.path.dirname(folder_path)
else:
# Use os.path.normpath to handle both Windows and Linux paths
normalized_path = os.path.normpath(file_path)
# Split the path into folder path and file name
folder_path, file_name = os.path.split(normalized_path)
host = None

# Check if the path ends in a folder
if not file_name:
file_name = None

# Check if the original path used Unix-style separators
if '/' in file_path:
folder_path = folder_path.replace('\\', '/')

return {
'host': host,
'folder_path': folder_path,
'file_name': file_name
}

async def parse_arguments(self):
if len(self.command_line) > 0:
if self.command_line[0] == '{':
self.load_args_from_json_string(self.command_line)
if (len(self.raw_command_line) > 0):
if(self.raw_command_line[0] == "{"):
temp_json = json.loads(self.raw_command_line)
if "file" in temp_json: # This means it likely came from the file
self.add_arg("path", temp_json["path"])
self.add_arg("host", temp_json["host"])
self.add_arg("file", temp_json["file"])
else:
self.add_arg("path", temp_json["path"])
self.add_arg("host", temp_json["host"])
else:
host = ""
if self.command_line[0] == "\\" and self.command_line[1] == "\\":
final = self.command_line.find("\\", 2)
if final != -1:
host = self.command_line[2:final]
else:
raise Exception("Invalid UNC path: {}".format(self.command_line))
self.add_arg("host", host)
self.add_arg("path", self.command_line)
else:
raise Exception("rm requires a path to remove.\n\tUsage: {}".format(RmCommand.help_cmd))
print("parsing from raw command line")
path_parts = self.parse_file_path(self.raw_command_line)
combined_path = self.build_file_path({"host":"","folder_path":path_parts["folder_path"],"file_name":path_parts["file_name"]})
self.add_arg("path", combined_path)
self.add_arg("host", path_parts["host"])

class RmCommand(CommandBase):
cmd = "rm"
Expand Down

0 comments on commit e876deb

Please sign in to comment.