Integrated sleep obfuscation settings into agent generation.
This commit is contained in:
@@ -7,17 +7,27 @@ import ../../common/[types, utils, profile, serialize, crypto]
|
||||
|
||||
const PLACEHOLDER = "PLACEHOLDER"
|
||||
|
||||
proc serializeConfiguration(cq: Conquest, listener: Listener, sleep: int): seq[byte] =
|
||||
proc serializeConfiguration(cq: Conquest, listener: Listener, sleep: int, sleepTechnique: string, spoofStack: bool): seq[byte] =
|
||||
|
||||
var packer = Packer.init()
|
||||
|
||||
# Add listener configuration
|
||||
# Variable length data is prefixed with a 4-byte length indicator
|
||||
|
||||
# Listener configuration
|
||||
packer.add(string.toUuid(listener.listenerId))
|
||||
packer.addDataWithLengthPrefix(string.toBytes(listener.address))
|
||||
packer.add(uint32(listener.port))
|
||||
|
||||
# Sleep settings
|
||||
packer.add(uint32(sleep))
|
||||
packer.add(uint8(parseEnum[SleepObfuscationTechnique](sleepTechnique.toUpperAscii())))
|
||||
packer.add(uint8(spoofStack))
|
||||
|
||||
# Public key for key exchange
|
||||
packer.addData(cq.keyPair.publicKey)
|
||||
|
||||
# C2 profile
|
||||
packer.addDataWithLengthPrefix(string.toBytes(cq.profile.toTomlString()))
|
||||
|
||||
let data = packer.pack()
|
||||
@@ -123,7 +133,7 @@ proc patch(cq: Conquest, unpatchedExePath: string, configuration: seq[byte]): bo
|
||||
return true
|
||||
|
||||
# Agent generation
|
||||
proc agentBuild*(cq: Conquest, listener, sleep: string): bool {.discardable.} =
|
||||
proc agentBuild*(cq: Conquest, listener, sleepDelay: string, sleepTechnique: string, spoofStack: bool): bool {.discardable.} =
|
||||
|
||||
# Verify that listener exists
|
||||
if not cq.dbListenerExists(listener.toUpperAscii):
|
||||
@@ -133,11 +143,11 @@ proc agentBuild*(cq: Conquest, listener, sleep: string): bool {.discardable.} =
|
||||
let listener = cq.listeners[listener.toUpperAscii]
|
||||
|
||||
var config: seq[byte]
|
||||
if sleep.isEmptyOrWhitespace():
|
||||
if sleepDelay.isEmptyOrWhitespace():
|
||||
# If no sleep value has been defined, take the default from the profile
|
||||
config = cq.serializeConfiguration(listener, cq.profile.getInt("agent.sleep"))
|
||||
config = cq.serializeConfiguration(listener, cq.profile.getInt("agent.sleep"), sleepTechnique, spoofStack)
|
||||
else:
|
||||
config = cq.serializeConfiguration(listener, parseInt(sleep))
|
||||
config = cq.serializeConfiguration(listener, parseInt(sleepDelay), sleepTechnique, spoofStack)
|
||||
|
||||
let unpatchedExePath = cq.compile(config.len)
|
||||
if unpatchedExePath.isEmptyOrWhitespace():
|
||||
|
||||
@@ -13,6 +13,8 @@ proc makeAgentLogDirectory*(cq: Conquest, agentId: string): bool =
|
||||
|
||||
proc log*(cq: Conquest, logEntry: string) =
|
||||
let
|
||||
# TODO: Fix issue where log files are written to the wrong agent when the interact agent is changed in the middle of command execution
|
||||
# Though that problem would not occur when a proper GUI is used in the future
|
||||
date = now().format("dd-MM-yyyy")
|
||||
agentLogPath = fmt"{CONQUEST_ROOT}/data/logs/{cq.interactAgent.agentId}/{date}.session.log"
|
||||
|
||||
|
||||
@@ -54,9 +54,10 @@ var parser = newParser:
|
||||
command("build"):
|
||||
help("Generate a new agent to connect to an active listener.")
|
||||
option("-l", "--listener", help="Name of the listener.", required=true)
|
||||
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"])
|
||||
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"):
|
||||
nohelpflag()
|
||||
|
||||
@@ -104,7 +105,7 @@ proc handleConsoleCommand(cq: Conquest, args: string) =
|
||||
of "interact":
|
||||
cq.agentInteract(opts.agent.get.interact.get.name)
|
||||
of "build":
|
||||
cq.agentBuild(opts.agent.get.build.get.listener, opts.agent.get.build.get.sleep)
|
||||
cq.agentBuild(opts.agent.get.build.get.listener, opts.agent.get.build.get.sleep, opts.agent.get.build.get.sleepmask, opts.agent.get.build.get.spoof_stack)
|
||||
else:
|
||||
cq.agentUsage()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user